diff --git a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java index 58473903c0..480c290cb2 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java @@ -151,6 +151,7 @@ private static class Runtime implements Serializable { private final @Nullable String beforeYear; private final @Nullable String afterYear; private final boolean updateYearWithLatest; + private final boolean licenseHeaderWithRange; /** The license that we'd like enforced. */ private Runtime(String licenseHeader, String delimiter, String yearSeparator, boolean updateYearWithLatest) { @@ -166,18 +167,31 @@ private Runtime(String licenseHeader, String delimiter, String yearSeparator, bo Optional yearToken = getYearToken(licenseHeader); if (yearToken.isPresent()) { - yearToday = String.valueOf(YearMonth.now().getYear()); + this.yearToday = String.valueOf(YearMonth.now().getYear()); int yearTokenIndex = licenseHeader.indexOf(yearToken.get()); - beforeYear = licenseHeader.substring(0, yearTokenIndex); - afterYear = licenseHeader.substring(yearTokenIndex + yearToken.get().length()); - yearSepOrFull = yearSeparator; + this.beforeYear = licenseHeader.substring(0, yearTokenIndex); + this.afterYear = licenseHeader.substring(yearTokenIndex + yearToken.get().length()); + this.yearSepOrFull = yearSeparator; this.updateYearWithLatest = updateYearWithLatest; + + boolean hasHeaderWithRange = false; + // year plus separator + int lastChars = 4 + yearSeparator.length(); + if (beforeYear.endsWith(yearSeparator) && yearTokenIndex > lastChars) { + // year from in range + String yearFrom = licenseHeader.substring(yearTokenIndex-lastChars, yearTokenIndex).substring(0, 4); + if (YYYY.matcher(yearFrom).matches()) { + hasHeaderWithRange = true; + } + } + this.licenseHeaderWithRange = hasHeaderWithRange; } else { - yearToday = null; - beforeYear = null; - afterYear = null; + this.yearToday = null; + this.beforeYear = null; + this.afterYear = null; this.yearSepOrFull = licenseHeader; this.updateYearWithLatest = false; + this.licenseHeaderWithRange = false; } } @@ -243,7 +257,11 @@ private String calculateYearExact(String parsedYear) { return parsedYear; } else if (YYYY.matcher(parsedYear).matches()) { if (updateYearWithLatest) { - return parsedYear + yearSepOrFull + yearToday; + if (licenseHeaderWithRange) { + return yearToday; + } else { + return parsedYear + yearSepOrFull + yearToday; + } } else { // it's already good as a single year return parsedYear; @@ -266,7 +284,15 @@ private String calculateYearBySearching(String content) { } else { secondYear = null; } - return secondYear == null ? firstYear : firstYear + yearSepOrFull + secondYear; + if (secondYear == null) { + return firstYear; + } else { + if (licenseHeaderWithRange) { + return secondYear; + } else { + return firstYear + yearSepOrFull + secondYear; + } + } } else { System.err.println("Can't parse copyright year '" + content + "', defaulting to " + yearToday); // couldn't recognize the year format diff --git a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java index f5a1b5d67d..e9be58119f 100644 --- a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java @@ -32,6 +32,7 @@ public 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."; @Test public void parseExistingYear() throws Exception { @@ -137,6 +138,10 @@ private String hasHeaderYear(String years) throws IOException { return hasHeaderYear(HEADER_WITH_$YEAR, years); } + private String hasHeaderWithRangeAndWithYearTo(String toYear) throws IOException { + return hasHeaderYear(HEADER_WITH_RANGE_TO_$YEAR, toYear); + } + private static String currentYear() { return String.valueOf(YearMonth.now().getYear()); } @@ -201,4 +206,10 @@ protected FormatterStep create() { } }.testEquals(); } + + @Test + public void should_apply_license_containing_YEAR_token_in_range() throws Throwable { + FormatterStep step = LicenseHeaderStep.headerDelimiter(header(HEADER_WITH_RANGE_TO_$YEAR), package_).withYearMode(YearMode.UPDATE_TO_TODAY).build(); + StepHarness.forStep(step).test(hasHeaderWithRangeAndWithYearTo("2015"), hasHeaderWithRangeAndWithYearTo(currentYear())); + } }