Skip to content

Commit

Permalink
Merge pull request #542 from sameer-b/supportIntelliJTokens
Browse files Browse the repository at this point in the history
Enable support for intelliJ placeholder for year in license header
  • Loading branch information
nedtwigg authored Mar 20, 2020
2 parents 2204946 + 6ccc16d commit 07d58e5
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
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
* Enable IntelliJ-compatible token `$today.year` for specifying the year in license header files. ([#542](https://github.com/diffplug/spotless/pull/542))
### Build
* All `CHANGES.md` are now in keepachangelog format. ([#507](https://github.com/diffplug/spotless/pull/507))
* We now use [javadoc.io](https://javadoc.io/) instead of github pages. ([#508](https://github.com/diffplug/spotless/pull/508))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.time.YearMonth;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -35,17 +38,18 @@ public final class LicenseHeaderStep implements Serializable {

private static final String NAME = "licenseHeader";
private static final String DEFAULT_YEAR_DELIMITER = "-";
private static final List<String> YEAR_TOKENS = Arrays.asList("$YEAR", "$today.year");

private static final SerializableFileFilter UNSUPPORTED_JVM_FILES_FILTER = SerializableFileFilter.skipFilesNamed(
"package-info.java", "package-info.groovy", "module-info.java");

private final String licenseHeader;
private final boolean hasYearToken;
private final Pattern delimiterPattern;
private Pattern yearMatcherPattern;
private boolean hasYearToken;
private String licenseHeaderBeforeYearToken;
private String licenseHeaderAfterYearToken;
private String licenseHeaderWithYearTokenReplaced;
private final Pattern yearMatcherPattern;
private final String licenseHeaderBeforeYearToken;
private final String licenseHeaderAfterYearToken;
private final String licenseHeaderWithYearTokenReplaced;

/** Creates a FormatterStep which forces the start of each file to match a license header. */
public static FormatterStep createFromHeader(String licenseHeader, String delimiter) {
Expand Down Expand Up @@ -107,16 +111,34 @@ private LicenseHeaderStep(String licenseHeader, String delimiter, String yearSep
}
this.licenseHeader = licenseHeader;
this.delimiterPattern = Pattern.compile('^' + delimiter, Pattern.UNIX_LINES | Pattern.MULTILINE);
this.hasYearToken = licenseHeader.contains("$YEAR");
if (this.hasYearToken) {
int yearTokenIndex = licenseHeader.indexOf("$YEAR");
this.licenseHeaderBeforeYearToken = licenseHeader.substring(0, yearTokenIndex);
this.licenseHeaderAfterYearToken = licenseHeader.substring(yearTokenIndex + 5, licenseHeader.length());
this.licenseHeaderWithYearTokenReplaced = licenseHeader.replace("$YEAR", String.valueOf(YearMonth.now().getYear()));
this.yearMatcherPattern = Pattern.compile("[0-9]{4}(" + Pattern.quote(yearSeparator) + "[0-9]{4})?");

Optional<String> yearToken = getYearToken(licenseHeader);
this.hasYearToken = yearToken.isPresent();
if (hasYearToken) {
int yearTokenIndex = licenseHeader.indexOf(yearToken.get());
licenseHeaderBeforeYearToken = licenseHeader.substring(0, yearTokenIndex);
licenseHeaderAfterYearToken = licenseHeader.substring(yearTokenIndex + 5);
licenseHeaderWithYearTokenReplaced = licenseHeader.replace(yearToken.get(), String.valueOf(YearMonth.now().getYear()));
yearMatcherPattern = Pattern.compile("[0-9]{4}(" + Pattern.quote(yearSeparator) + "[0-9]{4})?");
} else {
licenseHeaderBeforeYearToken = null;
licenseHeaderAfterYearToken = null;
licenseHeaderWithYearTokenReplaced = null;
yearMatcherPattern = null;
}
}

/**
* Get the first place holder token being used in the
* license header for specifying the year
*
* @param licenseHeader String representation of the license header
* @return Matching value from YEAR_TOKENS or null if none exist
*/
private static Optional<String> getYearToken(String licenseHeader) {
return YEAR_TOKENS.stream().filter(licenseHeader::contains).findFirst();
}

/** Reads the license file from the given file. */
private LicenseHeaderStep(File licenseFile, Charset encoding, String delimiter, String yearSeparator) throws IOException {
this(new String(Files.readAllBytes(licenseFile.toPath()), encoding), delimiter, yearSeparator);
Expand Down
3 changes: 3 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Added
* Enable IntelliJ-compatible token `$today.year` for specifying the year in license header files. ([#542](https://github.com/diffplug/spotless/pull/542))
### Fixed
* Eclipse-WTP formatter (web tools platform, not java) could encounter errors in parallel multiproject builds [#492](https://github.com/diffplug/spotless/issues/492). Fixed for Eclipse-WTP formatter Eclipse version 4.13.0 (default version).

## [3.27.2] - 2020-03-05
### Fixed
* Add tests to `SpecificFilesTest` to fix [#529](https://github.com/diffplug/spotless/issues/529)
* If you applied spotless to a subproject, but not to the root project, then on Gradle 6+ you would get the deprecation warning `Using method Project#afterEvaluate(Action) when the project is already evaluated has been deprecated.` This has now been fixed. ([#506](https://github.com/diffplug/spotless/issues/506))

Expand Down
4 changes: 1 addition & 3 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -523,9 +523,7 @@ to true.

## License header options

If the string contents of a licenseHeader step or the file contents of a licenseHeaderFile step contains a $YEAR token,
then in the end-result generated license headers which use this license header as a template, $YEAR will be replaced with the current year.

If the license header (specified with `licenseHeader` or `licenseHeaderFile`) contains `$YEAR` or `$today.year`, then that token will be replaced with the current 4-digit year.

For example:
```
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
* Enable IntelliJ-compatible token `$today.year` for specifying the year in license header files. ([#542](https://github.com/diffplug/spotless/pull/542))
### Fixed
* Fix scala and kotlin maven config documentation.
* Eclipse-WTP formatter (web tools platform, not java) could encounter errors in parallel multiproject builds [#492](https://github.com/diffplug/spotless/issues/492). Fixed for Eclipse-WTP formatter Eclipse version 4.13.0 (default version).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class LicenseHeaderStepTest extends ResourceHarness {
private static final String KEY_FILE_WITH_LICENSE_AND_PLACEHOLDER = "license/FileWithLicenseHeaderAndPlaceholder.test";
// Licenses to test $YEAR token replacement
private static final String LICENSE_HEADER_YEAR = "This is a fake license, $YEAR. ACME corp.";
// License to test $today.year token replacement
private static final String LICENSE_HEADER_YEAR_INTELLIJ_TOKEN = "This is a fake license, $today.year. ACME corp.";
// Special case where the characters immediately before and after the year token are the same,
// start position of the second part might overlap the end position of the first part.
private static final String LICENSE_HEADER_YEAR_VARIANT = "This is a fake license. Copyright $YEAR ACME corp.";
Expand Down Expand Up @@ -82,6 +84,12 @@ public void should_apply_license_containing_YEAR_token() throws Throwable {
.test(fileWithLicenseContaining(" ACME corp."), fileWithLicenseContaining(LICENSE_HEADER_YEAR_VARIANT, currentYear()))
.test(fileWithLicenseContaining("This is a fake license. Copyright ACME corp."), fileWithLicenseContaining(LICENSE_HEADER_YEAR_VARIANT, currentYear()))
.test(fileWithLicenseContaining("This is a fake license. CopyrightACME corp."), fileWithLicenseContaining(LICENSE_HEADER_YEAR_VARIANT, currentYear()));

//Check when token is of the format $today.year
step = LicenseHeaderStep.createFromFile(createLicenseWith(LICENSE_HEADER_YEAR_INTELLIJ_TOKEN), StandardCharsets.UTF_8, LICENSE_HEADER_DELIMITER);

StepHarness.forStep(step)
.test(fileWithLicenseContaining(LICENSE_HEADER_YEAR_INTELLIJ_TOKEN), fileWithLicenseContaining(LICENSE_HEADER_YEAR_INTELLIJ_TOKEN, currentYear(), "$today.year"));
}

@Test
Expand Down Expand Up @@ -126,6 +134,10 @@ private String fileWithLicenseContaining(String license, String yearContent) thr
return getTestResource(KEY_FILE_WITH_LICENSE_AND_PLACEHOLDER).replace("__LICENSE_PLACEHOLDER__", license).replace("$YEAR", yearContent);
}

private String fileWithLicenseContaining(String license, String yearContent, String token) throws IOException {
return getTestResource(KEY_FILE_WITH_LICENSE_AND_PLACEHOLDER).replace("__LICENSE_PLACEHOLDER__", license).replace(token, yearContent);
}

private String currentYear() {
return String.valueOf(YearMonth.now().getYear());
}
Expand Down

0 comments on commit 07d58e5

Please sign in to comment.