Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support a file name field in license headers #1605

Merged
merged 10 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))
### Changes
* We are now opting in to Gradle's new stable configuration cache. ([#1591](https://github.com/diffplug/spotless/pull/1591))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public FormatterStep build() {
throw new IllegalStateException(yearMode.toString());
}
return new Runtime(headerLazy.get(), delimiter, yearSeparator, updateYear, skipLinesMatching);
}, step -> step::format);
}, step -> FormatterFunc.needsFile(step::format));
}

if (contentPattern == null) {
Expand Down Expand Up @@ -214,6 +214,8 @@ private static class Runtime implements Serializable {
private final boolean updateYearWithLatest;
private final boolean licenseHeaderWithRange;

private static final Pattern FILENAME_PATTERN = Pattern.compile("\\$FILE");

/** The license that we'd like enforced. */
private Runtime(String licenseHeader, String delimiter, String yearSeparator, boolean updateYearWithLatest, @Nullable String skipLinesMatching) {
if (delimiter.contains("\n")) {
Expand Down Expand Up @@ -266,9 +268,9 @@ private static Optional<String> getYearToken(String licenseHeader) {
}

/** Formats the given string. */
private String format(String raw) {
private String format(String raw, File file) {
if (skipLinesMatching == null) {
return addOrUpdateLicenseHeader(raw);
return addOrUpdateLicenseHeader(raw, file);
} else {
String[] lines = raw.split("\n");
StringBuilder skippedLinesBuilder = new StringBuilder();
Expand All @@ -287,11 +289,11 @@ private String format(String raw) {
remainingLinesBuilder.append(line).append('\n');
}
}
return skippedLinesBuilder + addOrUpdateLicenseHeader(remainingLinesBuilder.toString());
return skippedLinesBuilder + addOrUpdateLicenseHeader(remainingLinesBuilder.toString(), file);
}
}

private String addOrUpdateLicenseHeader(String raw) {
private String addOrUpdateLicenseHeader(String raw, File file) {
Matcher contentMatcher = delimiterPattern.matcher(raw);
if (!contentMatcher.find()) {
throw new IllegalArgumentException("Unable to find delimiter regex " + delimiterPattern);
Expand All @@ -305,13 +307,14 @@ private String addOrUpdateLicenseHeader(String raw) {
return raw;
} else {
// otherwise we'll have to add the header
return yearSepOrFull + content;
return replaceFileName(yearSepOrFull, file) + content;
}
} else {
// the yes year case is a bit harder
int beforeYearIdx = raw.indexOf(beforeYear);
int afterYearIdx = raw.indexOf(afterYear, beforeYearIdx + beforeYear.length() + 1);

String header;
if (beforeYearIdx >= 0 && afterYearIdx >= 0 && afterYearIdx + afterYear.length() <= contentMatcher.start()) {
// and also ends with exactly the right header, so it's easy to parse the existing year
String existingYear = raw.substring(beforeYearIdx + beforeYear.length(), afterYearIdx);
Expand All @@ -323,12 +326,13 @@ private String addOrUpdateLicenseHeader(String raw) {
return raw;
nedtwigg marked this conversation as resolved.
Show resolved Hide resolved
}
}
return beforeYear + newYear + afterYear + content;
header = beforeYear + newYear + afterYear;
} else {
String newYear = calculateYearBySearching(raw.substring(0, contentMatcher.start()));
// at worst, we just say that it was made today
return beforeYear + newYear + afterYear + content;
header = beforeYear + newYear + afterYear;
}
return replaceFileName(header, file) + content;
}
}
}
Expand Down Expand Up @@ -421,6 +425,10 @@ private String setLicenseHeaderYearsFromGitHistory(String raw, File file) throws
return beforeYear + yearRange + afterYear + raw.substring(contentMatcher.start());
}

private String replaceFileName(String header, File file) {
return FILENAME_PATTERN.matcher(header).replaceAll(file.getName());
}

private static String parseYear(String cmd, File file) throws IOException {
String fullCmd = cmd + " -- " + file.getAbsolutePath();
ProcessBuilder builder = new ProcessBuilder().directory(file.getParentFile());
Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Added
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))

## [6.16.0] - 2023-02-27
### Added
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))

## [2.34.0] - 2023-02-27
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
import com.diffplug.spotless.ResourceHarness;
import com.diffplug.spotless.SerializableEqualityTester;
import com.diffplug.spotless.StepHarness;
import com.diffplug.spotless.StepHarnessWithFile;
import com.diffplug.spotless.generic.LicenseHeaderStep.YearMode;

class LicenseHeaderStepTest extends ResourceHarness {
private static final String FILE_NO_LICENSE = "license/FileWithoutLicenseHeader.test";
private static final String package_ = "package ";
private static final String HEADER_WITH_$YEAR = "This is a fake license, $YEAR. ACME corp.";
private static final String HEADER_WITH_RANGE_TO_$YEAR = "This is a fake license with range, 2009-$YEAR. ACME corp.";
private static final String HEADER_WITH_$FILE = "This is a fake license, $FILE. ACME corp.";
private static final String HEADER_WITH_$YEAR_$FILE = "This is a fake license, $FILE, $YEAR. ACME corp.";

@Test
void parseExistingYear() throws Exception {
Expand Down Expand Up @@ -163,6 +166,16 @@ private String hasHeaderWithRangeAndWithYearTo(String toYear) throws IOException
return hasHeaderYear(HEADER_WITH_RANGE_TO_$YEAR, toYear);
}

private String hasHeaderFileName(String license, String fileName) throws IOException {
return header(license).replace("$FILE", fileName) + getTestResource(FILE_NO_LICENSE);
}

private String hasHeaderYearFileName(String license, String year, String fileName) throws IOException {
return header(license)
.replace("$YEAR", year)
.replace("$FILE", fileName) + getTestResource(FILE_NO_LICENSE);
}

private static String currentYear() {
return String.valueOf(YearMonth.now().getYear());
}
Expand Down Expand Up @@ -250,4 +263,21 @@ void should_preserve_year_for_license_with_address() throws Throwable {
hasHeader(licenceWithAddress().replace("$YEAR", "2015").replace("FooBar Inc. All", "FooBar Inc. All")),
hasHeader(licenceWithAddress().replace("$YEAR", "2015")));
}

@Test
void should_apply_license_containing_filename_token() throws Exception {
FormatterStep step = LicenseHeaderStep.headerDelimiter(header(HEADER_WITH_$FILE), package_).build();
StepHarnessWithFile.forStep(this, step)
.test(new File("Test.java"), getTestResource(FILE_NO_LICENSE), hasHeaderFileName(HEADER_WITH_$FILE, "Test.java"));
}

@Test
void should_apply_license_containing_YEAR_filename_token() throws Exception {
FormatterStep step = LicenseHeaderStep.headerDelimiter(header(HEADER_WITH_$YEAR_$FILE), package_).build();
StepHarnessWithFile.forStep(this, step)
.test(
new File("Test.java"),
getTestResource(FILE_NO_LICENSE),
hasHeaderYearFileName(HEADER_WITH_$YEAR_$FILE, currentYear(), "Test.java"));
}
}