From 6a419301dfe14771c350d93ae1af6e4d301661c8 Mon Sep 17 00:00:00 2001 From: Baptiste Mesta Date: Tue, 19 Dec 2017 11:43:26 +0100 Subject: [PATCH 1/4] add a $YEAR as a supported variable in license This token is replaced by the current year in the following cases: * the license is missing * the license in not formatted * the $YEAR is not like 1990 or 1990-2005 --- .../spotless/generic/LicenseHeaderStep.java | 29 +++++++++++++- plugin-gradle/README.md | 26 ++++++++++++ .../generic/LicenseHeaderStepTest.java | 28 +++++++++++++ .../resources/license/LicenseWithYear.test | 40 +++++++++++++++++++ .../license/MissLicenseWithYear.test | 28 +++++++++++++ .../resources/license/TestLicencseWithYear | 12 ++++++ 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 testlib/src/test/resources/license/LicenseWithYear.test create mode 100644 testlib/src/test/resources/license/MissLicenseWithYear.test create mode 100644 testlib/src/test/resources/license/TestLicencseWithYear 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 eec6274c8d..e78e9dec6f 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java @@ -20,6 +20,7 @@ import java.io.Serializable; import java.nio.charset.Charset; import java.nio.file.Files; +import java.time.YearMonth; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -35,6 +36,11 @@ public final class LicenseHeaderStep implements Serializable { private final String licenseHeader; private final Pattern delimiterPattern; + private Pattern yearMatcherPattern; + private boolean hasYearToken; + private String licenseHeaderBeforeYEARToken; + private String licenseHeaderAfterYEARToken; + private 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) { @@ -74,6 +80,14 @@ private LicenseHeaderStep(String licenseHeader, String delimiter) { } this.licenseHeader = licenseHeader; this.delimiterPattern = Pattern.compile('^' + delimiter, Pattern.UNIX_LINES | Pattern.MULTILINE); + hasYearToken = licenseHeader.contains("$YEAR"); + if (hasYearToken) { + int yearTokenIndex = licenseHeader.indexOf("$YEAR"); + licenseHeaderBeforeYEARToken = licenseHeader.substring(0, yearTokenIndex); + licenseHeaderAfterYEARToken = licenseHeader.substring(yearTokenIndex + 5, licenseHeader.length()); + licenseHeaderWithYEARTokenReplaced = licenseHeader.replace("$YEAR", String.valueOf(YearMonth.now().getYear())); + this.yearMatcherPattern = Pattern.compile("[0-9]{4}(-[0-9]{4})?"); + } } /** Reads the license file from the given file. */ @@ -87,7 +101,14 @@ public String format(String raw) { if (!matcher.find()) { throw new IllegalArgumentException("Unable to find delimiter regex " + delimiterPattern); } else { - if (matcher.start() == licenseHeader.length() && raw.startsWith(licenseHeader)) { + if (hasYearToken) { + if (matchesLicenseWithYearToken(raw, matcher)) { + //that means we have the license like `licenseHeaderBeforeYEARToken 1990-2015 licenseHeaderAfterYEARToken` + return raw; + } else { + return licenseHeaderWithYEARTokenReplaced + raw.substring(matcher.start()); + } + } else if (matcher.start() == licenseHeader.length() && raw.startsWith(licenseHeader)) { // if no change is required, return the raw string without // creating any other new strings for maximum performance return raw; @@ -97,4 +118,10 @@ public String format(String raw) { } } } + + private boolean matchesLicenseWithYearToken(String raw, Matcher matcher) { + int startOfTheSecondPart = raw.indexOf(licenseHeaderAfterYEARToken); + return (raw.startsWith(licenseHeaderBeforeYEARToken) && startOfTheSecondPart + licenseHeaderAfterYEARToken.length() == matcher.start()) + && yearMatcherPattern.matcher(raw.substring(licenseHeaderBeforeYEARToken.length(), startOfTheSecondPart)).matches(); + } } diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index c921e86228..dc7e8c9f45 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -273,6 +273,32 @@ spotless { } ``` + + +## License header options + +The license header can contains a `$YEAR` variable that will be replaced by the current year. + +For example: +``` +/* Licensed under Apache-2.0 $YEAR. */ +``` +will produce +``` +/* Licensed under Apache-2.0 2017. */ +``` +if build is launched in 2017 + + +The step will change the license according to the following rules +* It replace the license using the current year when + * The license is missing + * The license is not formatted correctly +* It will *not* replace the license when + * The year variable is already present and is a single year, e.g. `/* Licensed under Apache-2.0 1990. */` + * The year variable is already present and is a year span, e.g. `/* Licensed under Apache-2.0 1990-2003. */` + + ## Custom rules 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 5be629bc0f..13c38d2371 100644 --- a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java @@ -16,7 +16,9 @@ package com.diffplug.spotless.generic; import java.io.File; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.YearMonth; import org.junit.Assert; import org.junit.Test; @@ -24,11 +26,17 @@ import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.ResourceHarness; import com.diffplug.spotless.SerializableEqualityTester; +import com.diffplug.spotless.StepHarness; public class LicenseHeaderStepTest extends ResourceHarness { private static final String KEY_LICENSE = "license/TestLicense"; private static final String KEY_FILE_NOTAPPLIED = "license/MissingLicense.test"; private static final String KEY_FILE_APPLIED = "license/HasLicense.test"; + private static final String KEY_LICENSE_WITH_YEAR = "license/TestLicencseWithYear"; + private static final String KEY_FILE_WITHOUT_LICENSE = "license/MissLicenseWithYear.test"; + private static final String KEY_FILE_WITH_PREVIOUS_YEAR = "license/LicenseWithPreviousYear.test"; + private static final String KEY_FILE_WITH_PREVIOUS_YEARS = "license/LicenseWithPreviousYears.test"; + private static final String KEY_FILE_WITH_CURRENT_YEAR = "license/LicenseWithYear.test"; // If this constant changes, don't forget to change the similarly-named one in // plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java as well @@ -46,6 +54,26 @@ public void fromFile() throws Throwable { assertOnResources(step, KEY_FILE_NOTAPPLIED, KEY_FILE_APPLIED); } + @Test + public void should_apply_license_containing_YEAR_variable() throws Throwable { + FormatterStep step = LicenseHeaderStep.createFromFile(createTestFile(KEY_LICENSE_WITH_YEAR), StandardCharsets.UTF_8, LICENSE_HEADER_DELIMITER); + + StepHarness.forStep(step) + .test(getTestResource(KEY_FILE_WITHOUT_LICENSE), getFileContentWithYEAR(currentYear())) + .testUnaffected(getFileContentWithYEAR(currentYear())) + .testUnaffected(getFileContentWithYEAR("2003")) + .testUnaffected(getFileContentWithYEAR("1990-2015")) + .test(getFileContentWithYEAR("not a year"), getFileContentWithYEAR(currentYear())); + } + + private String getFileContentWithYEAR(String year) throws IOException { + return getTestResource(KEY_FILE_WITH_CURRENT_YEAR).replace("__YEAR_to_replace_in_tests__", year); + } + + private String currentYear() { + return String.valueOf(YearMonth.now().getYear()); + } + @Test public void efficient() throws Throwable { FormatterStep step = LicenseHeaderStep.createFromHeader("LicenseHeader\n", "contentstart"); diff --git a/testlib/src/test/resources/license/LicenseWithYear.test b/testlib/src/test/resources/license/LicenseWithYear.test new file mode 100644 index 0000000000..6a4905bf08 --- /dev/null +++ b/testlib/src/test/resources/license/LicenseWithYear.test @@ -0,0 +1,40 @@ +/* + * Copyright (C) __YEAR_to_replace_in_tests__. ACME corp. + * This library is free software; you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation + * version 2.1 of the License. + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + * Floor, Boston, MA 02110-1301, USA. + **/ +package com.acme; + +import java.util.function.Function; + + +public class Java8Test { + public void doStuff() throws Exception { + Function example = Integer::parseInt; + example.andThen(val -> { + return val + 2; + } ); + SimpleEnum val = SimpleEnum.A; + switch (val) { + case A: + break; + case B: + break; + case C: + break; + default: + throw new Exception(); + } + } + + public enum SimpleEnum { + A, B, C; + } +} diff --git a/testlib/src/test/resources/license/MissLicenseWithYear.test b/testlib/src/test/resources/license/MissLicenseWithYear.test new file mode 100644 index 0000000000..297c16a214 --- /dev/null +++ b/testlib/src/test/resources/license/MissLicenseWithYear.test @@ -0,0 +1,28 @@ +package com.acme; + +import java.util.function.Function; + + +public class Java8Test { + public void doStuff() throws Exception { + Function example = Integer::parseInt; + example.andThen(val -> { + return val + 2; + } ); + SimpleEnum val = SimpleEnum.A; + switch (val) { + case A: + break; + case B: + break; + case C: + break; + default: + throw new Exception(); + } + } + + public enum SimpleEnum { + A, B, C; + } +} diff --git a/testlib/src/test/resources/license/TestLicencseWithYear b/testlib/src/test/resources/license/TestLicencseWithYear new file mode 100644 index 0000000000..39e6b98a52 --- /dev/null +++ b/testlib/src/test/resources/license/TestLicencseWithYear @@ -0,0 +1,12 @@ +/* + * Copyright (C) $YEAR. ACME corp. + * This library is free software; you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation + * version 2.1 of the License. + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + * Floor, Boston, MA 02110-1301, USA. + **/ \ No newline at end of file From 17021791fe7b6b840a7cf5dc8a28d0b13fbffb00 Mon Sep 17 00:00:00 2001 From: Baptiste Mesta Date: Wed, 20 Dec 2017 10:33:49 +0100 Subject: [PATCH 2/4] PR Review --- .../generic/LicenseHeaderStepTest.java | 28 +++++++++---------- ... FileWithLicenseHeaderAndPlaceholder.test} | 2 +- ...ear.test => FileWithoutLicenseHeader.test} | 0 ...cseWithYear => LicenseHeaderWithYearToken} | 0 4 files changed, 15 insertions(+), 15 deletions(-) rename testlib/src/test/resources/license/{LicenseWithYear.test => FileWithLicenseHeaderAndPlaceholder.test} (95%) rename testlib/src/test/resources/license/{MissLicenseWithYear.test => FileWithoutLicenseHeader.test} (100%) rename testlib/src/test/resources/license/{TestLicencseWithYear => LicenseHeaderWithYearToken} (100%) 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 13c38d2371..2f57af6212 100644 --- a/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java @@ -32,11 +32,11 @@ public class LicenseHeaderStepTest extends ResourceHarness { private static final String KEY_LICENSE = "license/TestLicense"; private static final String KEY_FILE_NOTAPPLIED = "license/MissingLicense.test"; private static final String KEY_FILE_APPLIED = "license/HasLicense.test"; - private static final String KEY_LICENSE_WITH_YEAR = "license/TestLicencseWithYear"; - private static final String KEY_FILE_WITHOUT_LICENSE = "license/MissLicenseWithYear.test"; - private static final String KEY_FILE_WITH_PREVIOUS_YEAR = "license/LicenseWithPreviousYear.test"; - private static final String KEY_FILE_WITH_PREVIOUS_YEARS = "license/LicenseWithPreviousYears.test"; - private static final String KEY_FILE_WITH_CURRENT_YEAR = "license/LicenseWithYear.test"; + + // files to test $YEAR token replacement + private static final String KEY_LICENSE_WITH_YEAR_TOKEN = "license/LicenseHeaderWithYearToken"; + private static final String KEY_FILE_WITHOUT_LICENSE = "license/FileWithoutLicenseHeader.test"; + private static final String KEY_FILE_WITH_LICENSE_AND_PLACEHOLDER = "license/FileWithLicenseHeaderAndPlaceholder.test"; // If this constant changes, don't forget to change the similarly-named one in // plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java as well @@ -55,19 +55,19 @@ public void fromFile() throws Throwable { } @Test - public void should_apply_license_containing_YEAR_variable() throws Throwable { - FormatterStep step = LicenseHeaderStep.createFromFile(createTestFile(KEY_LICENSE_WITH_YEAR), StandardCharsets.UTF_8, LICENSE_HEADER_DELIMITER); + public void should_apply_license_containing_YEAR_token() throws Throwable { + FormatterStep step = LicenseHeaderStep.createFromFile(createTestFile(KEY_LICENSE_WITH_YEAR_TOKEN), StandardCharsets.UTF_8, LICENSE_HEADER_DELIMITER); StepHarness.forStep(step) - .test(getTestResource(KEY_FILE_WITHOUT_LICENSE), getFileContentWithYEAR(currentYear())) - .testUnaffected(getFileContentWithYEAR(currentYear())) - .testUnaffected(getFileContentWithYEAR("2003")) - .testUnaffected(getFileContentWithYEAR("1990-2015")) - .test(getFileContentWithYEAR("not a year"), getFileContentWithYEAR(currentYear())); + .test(getTestResource(KEY_FILE_WITHOUT_LICENSE), fileWithPlaceholderContaining(currentYear())) + .testUnaffected(fileWithPlaceholderContaining(currentYear())) + .testUnaffected(fileWithPlaceholderContaining("2003")) + .testUnaffected(fileWithPlaceholderContaining("1990-2015")) + .test(fileWithPlaceholderContaining("not a year"), fileWithPlaceholderContaining(currentYear())); } - private String getFileContentWithYEAR(String year) throws IOException { - return getTestResource(KEY_FILE_WITH_CURRENT_YEAR).replace("__YEAR_to_replace_in_tests__", year); + private String fileWithPlaceholderContaining(String placeHolderContent) throws IOException { + return getTestResource(KEY_FILE_WITH_LICENSE_AND_PLACEHOLDER).replace("__PLACEHOLDER__", placeHolderContent); } private String currentYear() { diff --git a/testlib/src/test/resources/license/LicenseWithYear.test b/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test similarity index 95% rename from testlib/src/test/resources/license/LicenseWithYear.test rename to testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test index 6a4905bf08..71c12e5bd1 100644 --- a/testlib/src/test/resources/license/LicenseWithYear.test +++ b/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test @@ -1,5 +1,5 @@ /* - * Copyright (C) __YEAR_to_replace_in_tests__. ACME corp. + * Copyright (C) __PLACEHOLDER__. ACME corp. * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation * version 2.1 of the License. diff --git a/testlib/src/test/resources/license/MissLicenseWithYear.test b/testlib/src/test/resources/license/FileWithoutLicenseHeader.test similarity index 100% rename from testlib/src/test/resources/license/MissLicenseWithYear.test rename to testlib/src/test/resources/license/FileWithoutLicenseHeader.test diff --git a/testlib/src/test/resources/license/TestLicencseWithYear b/testlib/src/test/resources/license/LicenseHeaderWithYearToken similarity index 100% rename from testlib/src/test/resources/license/TestLicencseWithYear rename to testlib/src/test/resources/license/LicenseHeaderWithYearToken From fdce4c78372648832decc2fc2afa6ebcdbde03fc Mon Sep 17 00:00:00 2001 From: Baptiste Mesta Date: Fri, 22 Dec 2017 09:01:28 +0100 Subject: [PATCH 3/4] change test license file --- .../license/FileWithLicenseHeaderAndPlaceholder.test | 11 +---------- .../test/resources/license/LicenseHeaderWithYearToken | 11 +---------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test b/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test index 71c12e5bd1..68c5b3a8cc 100644 --- a/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test +++ b/testlib/src/test/resources/license/FileWithLicenseHeaderAndPlaceholder.test @@ -1,14 +1,5 @@ /* - * Copyright (C) __PLACEHOLDER__. ACME corp. - * This library is free software; you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Foundation - * version 2.1 of the License. - * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License along with this - * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth - * Floor, Boston, MA 02110-1301, USA. + * This is a fake license, __PLACEHOLDER__. ACME corp. **/ package com.acme; diff --git a/testlib/src/test/resources/license/LicenseHeaderWithYearToken b/testlib/src/test/resources/license/LicenseHeaderWithYearToken index 39e6b98a52..aa3cac89df 100644 --- a/testlib/src/test/resources/license/LicenseHeaderWithYearToken +++ b/testlib/src/test/resources/license/LicenseHeaderWithYearToken @@ -1,12 +1,3 @@ /* - * Copyright (C) $YEAR. ACME corp. - * This library is free software; you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Foundation - * version 2.1 of the License. - * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License along with this - * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth - * Floor, Boston, MA 02110-1301, USA. + * This is a fake license, $YEAR. ACME corp. **/ \ No newline at end of file From d71cfd7190aa88c7601683c37e7c1e6b593e8f4a Mon Sep 17 00:00:00 2001 From: Baptiste Mesta Date: Tue, 2 Jan 2018 19:51:05 +0100 Subject: [PATCH 4/4] PR review --- .../spotless/generic/LicenseHeaderStep.java | 26 +++++++++--------- plugin-gradle/README.md | 27 +++++++++++-------- 2 files changed, 29 insertions(+), 24 deletions(-) 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 e78e9dec6f..817bb3bc1c 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java @@ -38,9 +38,9 @@ public final class LicenseHeaderStep implements Serializable { private final Pattern delimiterPattern; private Pattern yearMatcherPattern; private boolean hasYearToken; - private String licenseHeaderBeforeYEARToken; - private String licenseHeaderAfterYEARToken; - private String licenseHeaderWithYEARTokenReplaced; + private String licenseHeaderBeforeYearToken; + private String licenseHeaderAfterYearToken; + private 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) { @@ -80,12 +80,12 @@ private LicenseHeaderStep(String licenseHeader, String delimiter) { } this.licenseHeader = licenseHeader; this.delimiterPattern = Pattern.compile('^' + delimiter, Pattern.UNIX_LINES | Pattern.MULTILINE); - hasYearToken = licenseHeader.contains("$YEAR"); - if (hasYearToken) { + this.hasYearToken = licenseHeader.contains("$YEAR"); + if (this.hasYearToken) { int yearTokenIndex = licenseHeader.indexOf("$YEAR"); - licenseHeaderBeforeYEARToken = licenseHeader.substring(0, yearTokenIndex); - licenseHeaderAfterYEARToken = licenseHeader.substring(yearTokenIndex + 5, licenseHeader.length()); - licenseHeaderWithYEARTokenReplaced = licenseHeader.replace("$YEAR", String.valueOf(YearMonth.now().getYear())); + 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}(-[0-9]{4})?"); } } @@ -103,10 +103,10 @@ public String format(String raw) { } else { if (hasYearToken) { if (matchesLicenseWithYearToken(raw, matcher)) { - //that means we have the license like `licenseHeaderBeforeYEARToken 1990-2015 licenseHeaderAfterYEARToken` + // that means we have the license like `licenseHeaderBeforeYearToken 1990-2015 licenseHeaderAfterYearToken` return raw; } else { - return licenseHeaderWithYEARTokenReplaced + raw.substring(matcher.start()); + return licenseHeaderWithYearTokenReplaced + raw.substring(matcher.start()); } } else if (matcher.start() == licenseHeader.length() && raw.startsWith(licenseHeader)) { // if no change is required, return the raw string without @@ -120,8 +120,8 @@ public String format(String raw) { } private boolean matchesLicenseWithYearToken(String raw, Matcher matcher) { - int startOfTheSecondPart = raw.indexOf(licenseHeaderAfterYEARToken); - return (raw.startsWith(licenseHeaderBeforeYEARToken) && startOfTheSecondPart + licenseHeaderAfterYEARToken.length() == matcher.start()) - && yearMatcherPattern.matcher(raw.substring(licenseHeaderBeforeYEARToken.length(), startOfTheSecondPart)).matches(); + int startOfTheSecondPart = raw.indexOf(licenseHeaderAfterYearToken); + return (raw.startsWith(licenseHeaderBeforeYearToken) && startOfTheSecondPart + licenseHeaderAfterYearToken.length() == matcher.start()) + && yearMatcherPattern.matcher(raw.substring(licenseHeaderBeforeYearToken.length(), startOfTheSecondPart)).matches(); } } diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index dc7e8c9f45..6efaf92ac5 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -277,7 +277,9 @@ spotless { ## License header options -The license header can contains a `$YEAR` variable that will be replaced by the current year. +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. + For example: ``` @@ -287,16 +289,19 @@ will produce ``` /* Licensed under Apache-2.0 2017. */ ``` -if build is launched in 2017 - - -The step will change the license according to the following rules -* It replace the license using the current year when - * The license is missing - * The license is not formatted correctly -* It will *not* replace the license when - * The year variable is already present and is a single year, e.g. `/* Licensed under Apache-2.0 1990. */` - * The year variable is already present and is a year span, e.g. `/* Licensed under Apache-2.0 1990-2003. */` +if Spotless is launched in 2017 + + +The `licenseHeader` and `licenseHeaderFile` steps will generate license headers with automatic years from the base license header according to the following rules: +* A generated license header will be updated with the current year when + * the generated license header is missing + * the generated license header is not formatted correctly +* A generated license header will _not_ be updated when + * a single year is already present, e.g. + `/* Licensed under Apache-2.0 1990. */` + * a hyphen-separated year range is already present, e.g. + `/* Licensed under Apache-2.0 1990-2003. */` + * the `$YEAR` token is otherwise missing