From 11942894f214eb487bfae241299cdcb32587b469 Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Tue, 9 Jun 2026 14:35:27 +0200 Subject: [PATCH 1/6] Add tests for years surrounded by whitespace in license header --- .../gradle/spotless/LicenseHeaderTest.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java index a8ac2dd9cc..9055d82f37 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 DiffPlug + * Copyright 2016-2026 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +43,8 @@ private void setLicenseStep(String licenseLine) throws IOException { "}"); } - private void assertUnchanged(String year) throws IOException { - assertTransform(year, year); + private void assertUnchanged(String yearBefore, String yearAfter) throws IOException { + assertTransform(yearBefore, yearAfter); } private void assertTransform(String yearBefore, String yearAfter) throws IOException { @@ -56,13 +56,32 @@ private void assertTransform(String yearBefore, String yearAfter) throws IOExcep private void testSuiteUpdateWithLatest(boolean update) throws IOException { if (update) { assertTransform("2003", "2003-" + NOW); + assertTransform(" 2003", "2003-" + NOW); + assertTransform("2003 ", "2003-" + NOW); + assertTransform(" 2003 ", "2003-" + NOW); + assertTransform("2003-2005", "2003-" + NOW); + assertTransform(" 2003-2005", "2003-" + NOW); + assertTransform("2003-2005 ", "2003-" + NOW); + assertTransform(" 2003-2005 ", "2003-" + NOW); } else { - assertUnchanged("2003"); - assertUnchanged("2003-2005"); + assertUnchanged("2003", "2003"); + assertUnchanged(" 2003", "2003"); // MSITARZ This one fails with clean 'main' code + assertUnchanged("2003 ", "2003"); + assertUnchanged(" 2003 ", "2003"); + + assertUnchanged("2003-2005", "2003-2005"); + assertUnchanged(" 2003-2005", "2003-2005"); // MSITARZ This one fails with clean 'main' code + assertUnchanged("2003-2005 ", "2003-2005"); + assertUnchanged(" 2003-2005 ", "2003-2005"); } - assertUnchanged(NOW); + assertUnchanged(NOW, NOW); + assertUnchanged(" " + NOW, NOW); + assertUnchanged(NOW + " ", NOW); + assertUnchanged(" " + NOW + " ", NOW); + assertTransform("", NOW); + assertTransform(" ", NOW); } @Test From a427333c150e27f54ca9e5b03f4144eedb9a1c8f Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Fri, 12 Jun 2026 15:31:22 +0200 Subject: [PATCH 2/6] Fix handling of years surrounded by whitespace in license header --- .../java/com/diffplug/spotless/generic/LicenseHeaderStep.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 edb4d73f6f..91ef59a21b 100644 --- a/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java +++ b/lib/src/main/java/com/diffplug/spotless/generic/LicenseHeaderStep.java @@ -380,7 +380,7 @@ private String calculateYearBySearching(String content) { String secondYear = null; if (updateYearWithLatest) { secondYear = firstYear.equals(yearToday) ? null : yearToday; - } else { + } else if (yearMatcher.end() + 1 < content.length()) { String contentWithSecondYear = content.substring(yearMatcher.end() + 1); int endOfLine = contentWithSecondYear.indexOf('\n'); if (endOfLine != -1) { From 4120d3abd4857022e4fa512bb423738a77b8b618 Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Fri, 12 Jun 2026 15:52:38 +0200 Subject: [PATCH 3/6] Update CHANGES.md, plugin-gradle/CHANGES.md and plugin-maven/CHANGES.md --- CHANGES.md | 1 + plugin-gradle/CHANGES.md | 1 + plugin-maven/CHANGES.md | 2 ++ 3 files changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 125aaa7327..5b774fe0b9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( - `FenceStep.preserveWithin` now forwards lints from nested steps while still suppressing lints inside preserved blocks. ([#2962](https://github.com/diffplug/spotless/pull/2962)) - Support `ktfmt` 0.63 and use its new builder API for formatting options to better avoid future breaking changes. - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) ### Changes - Bump default `greclipse` version to latest `4.35` -> `4.39`. ([#2924](https://github.com/diffplug/spotless/pull/2924)) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 03d3f6d8b7..488a1d4d0f 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -11,6 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( - `toggleOffOn` no longer disables lint-only steps such as `forbidWildcardImports`. ([#2962](https://github.com/diffplug/spotless/pull/2962)) - Prevent build caches from interfering when executing under the `-PspotlessIdeHook` mode. ([#2365](https://github.com/diffplug/spotless/issues/2365)) - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) ### Changes - Bump default `greclipse` version to latest `4.35` -> `4.39`. ([#2924](https://github.com/diffplug/spotless/pull/2924)) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index e5d7df51e0..fadbe0a493 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -6,6 +6,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Fixed - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) - `` no longer disables lint-only steps such as ``. ([#2962](https://github.com/diffplug/spotless/pull/2962)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) + ### Added - Add support for AsciiDoc formatting via `adocfmt`. ([#2960](https://github.com/diffplug/spotless/pull/2960)) - `` step now supports arbitrary formatter options via ``. ([#2968](https://github.com/diffplug/spotless/pull/2968)) From dbd462dbae46760cd5947b1c043e6f59e04c4588 Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Fri, 12 Jun 2026 15:56:59 +0200 Subject: [PATCH 4/6] Add missing . in all CHANGES.md --- CHANGES.md | 2 +- plugin-gradle/CHANGES.md | 2 +- plugin-maven/CHANGES.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5b774fe0b9..dba135171f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( - `FenceStep.preserveWithin` now forwards lints from nested steps while still suppressing lints inside preserved blocks. ([#2962](https://github.com/diffplug/spotless/pull/2962)) - Support `ktfmt` 0.63 and use its new builder API for formatting options to better avoid future breaking changes. - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) -- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace. ([#2973](https://github.com/diffplug/spotless/pull/2973)) ### Changes - Bump default `greclipse` version to latest `4.35` -> `4.39`. ([#2924](https://github.com/diffplug/spotless/pull/2924)) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 488a1d4d0f..d4387c43e5 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -11,7 +11,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( - `toggleOffOn` no longer disables lint-only steps such as `forbidWildcardImports`. ([#2962](https://github.com/diffplug/spotless/pull/2962)) - Prevent build caches from interfering when executing under the `-PspotlessIdeHook` mode. ([#2365](https://github.com/diffplug/spotless/issues/2365)) - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) -- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace. ([#2973](https://github.com/diffplug/spotless/pull/2973)) ### Changes - Bump default `greclipse` version to latest `4.35` -> `4.39`. ([#2924](https://github.com/diffplug/spotless/pull/2924)) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index fadbe0a493..45b18fce23 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -6,7 +6,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ### Fixed - Parse standard git year output in LicenseHeaderStep. ([#2940](https://github.com/diffplug/spotless/issues/2940)) - `` no longer disables lint-only steps such as ``. ([#2962](https://github.com/diffplug/spotless/pull/2962)) -- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace ([#2973](https://github.com/diffplug/spotless/pull/2973)) +- Fix `StringIndexOutOfBoundsException` in scenarios where copyright year is surrounded by whitespace. ([#2973](https://github.com/diffplug/spotless/pull/2973)) ### Added - Add support for AsciiDoc formatting via `adocfmt`. ([#2960](https://github.com/diffplug/spotless/pull/2960)) From 787819d8f8640c011d245dafee492fc5bffb0405 Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Fri, 12 Jun 2026 15:58:33 +0200 Subject: [PATCH 5/6] Remove unneeded debug comments --- .../java/com/diffplug/gradle/spotless/LicenseHeaderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java index 9055d82f37..bd307774fd 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java @@ -66,12 +66,12 @@ private void testSuiteUpdateWithLatest(boolean update) throws IOException { assertTransform(" 2003-2005 ", "2003-" + NOW); } else { assertUnchanged("2003", "2003"); - assertUnchanged(" 2003", "2003"); // MSITARZ This one fails with clean 'main' code + assertUnchanged(" 2003", "2003"); assertUnchanged("2003 ", "2003"); assertUnchanged(" 2003 ", "2003"); assertUnchanged("2003-2005", "2003-2005"); - assertUnchanged(" 2003-2005", "2003-2005"); // MSITARZ This one fails with clean 'main' code + assertUnchanged(" 2003-2005", "2003-2005"); assertUnchanged("2003-2005 ", "2003-2005"); assertUnchanged(" 2003-2005 ", "2003-2005"); } From b4d9ec0b41f4b9fedf6874a8a4becac286403ec4 Mon Sep 17 00:00:00 2001 From: Maciej Sitarz Date: Fri, 12 Jun 2026 16:34:02 +0200 Subject: [PATCH 6/6] Revert the changes to `assertUnchanged()` and use `assertTransform()` when needed --- .../gradle/spotless/LicenseHeaderTest.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java index bd307774fd..c06958cbd5 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/LicenseHeaderTest.java @@ -43,8 +43,8 @@ private void setLicenseStep(String licenseLine) throws IOException { "}"); } - private void assertUnchanged(String yearBefore, String yearAfter) throws IOException { - assertTransform(yearBefore, yearAfter); + private void assertUnchanged(String year) throws IOException { + assertTransform(year, year); } private void assertTransform(String yearBefore, String yearAfter) throws IOException { @@ -65,20 +65,20 @@ private void testSuiteUpdateWithLatest(boolean update) throws IOException { assertTransform("2003-2005 ", "2003-" + NOW); assertTransform(" 2003-2005 ", "2003-" + NOW); } else { - assertUnchanged("2003", "2003"); - assertUnchanged(" 2003", "2003"); - assertUnchanged("2003 ", "2003"); - assertUnchanged(" 2003 ", "2003"); - - assertUnchanged("2003-2005", "2003-2005"); - assertUnchanged(" 2003-2005", "2003-2005"); - assertUnchanged("2003-2005 ", "2003-2005"); - assertUnchanged(" 2003-2005 ", "2003-2005"); + assertUnchanged("2003"); + assertTransform(" 2003", "2003"); + assertTransform("2003 ", "2003"); + assertTransform(" 2003 ", "2003"); + + assertUnchanged("2003-2005"); + assertTransform(" 2003-2005", "2003-2005"); + assertTransform("2003-2005 ", "2003-2005"); + assertTransform(" 2003-2005 ", "2003-2005"); } - assertUnchanged(NOW, NOW); - assertUnchanged(" " + NOW, NOW); - assertUnchanged(NOW + " ", NOW); - assertUnchanged(" " + NOW + " ", NOW); + assertUnchanged(NOW); + assertTransform(" " + NOW, NOW); + assertTransform(NOW + " ", NOW); + assertTransform(" " + NOW + " ", NOW); assertTransform("", NOW); assertTransform(" ", NOW);