From 646ba3d0be70bbd19ebaaa3ceb3a86a31255d5be Mon Sep 17 00:00:00 2001 From: xzxiaoshan <365384722@qq.com> Date: Fri, 23 Oct 2026 17:18:46 +0800 Subject: [PATCH] feat: add maxLineLength option to googleJavaFormat step Expose the column-limit setting that google-java-format 1.37.0 added via JavaFormatterOptions.Style.builder().maxLineLength(int): - Gradle: googleJavaFormat('1.37.0').maxLineLength(240) - Maven: 1.37.0240 The step rejects maxLineLength with gjf older than 1.37.0 at configuration time with a clear error message. The glue code keeps compiling against gjf 1.28.0 (so older versions and JDK 17 keep working) and calls the 1.37.0 builder API reflectively. google-java-format 1.37.0 turned JavaFormatterOptions.Style from an enum into a record, which removed Style.valueOf(String) and broke the existing glue with a NoSuchMethodError. Style names are now resolved against the GOOGLE/AOSP constants, which exist as static fields in both shapes, so the step works again on 1.37.0+ regardless of maxLineLength. Fixes #3151 --- CHANGES.md | 3 + .../java/GoogleJavaFormatFormatterFunc.java | 56 +++++++++++++-- .../spotless/java/GoogleJavaFormatStep.java | 71 ++++++++++++++++--- plugin-gradle/CHANGES.md | 3 + plugin-gradle/README.md | 3 +- .../gradle/spotless/JavaExtension.java | 14 +++- .../GoogleJavaFormatIntegrationTest.java | 26 +++++++ plugin-maven/CHANGES.md | 3 + plugin-maven/README.md | 1 + .../spotless/maven/java/GoogleJavaFormat.java | 8 ++- .../maven/java/GoogleJavaFormatTest.java | 16 +++++ .../JavaCodeFormattedMaxLineLength240.test | 11 +++ .../java/GoogleJavaFormatStepTest.java | 33 +++++++++ 13 files changed, 231 insertions(+), 17 deletions(-) create mode 100644 testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test diff --git a/CHANGES.md b/CHANGES.md index 9929ccf7a6..3c0974788b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +### Features +- `googleJavaFormat` gained a `maxLineLength` option, which overrides the 100-column limit prescribed by the GOOGLE and AOSP styles. It requires `google-java-format` `1.37.0` or later, and the step now also works at all with `1.37.0+` (upstream changed `JavaFormatterOptions.Style` from an enum to a record in `1.37.0`). ([#3151](https://github.com/diffplug/spotless/issues/3151)) + ## [4.10.4] - 2026-10-08 ### Changes diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java index d13f8d9d40..501db11974 100644 --- a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java +++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 DiffPlug + * Copyright 2023-2026 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.glue.java; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Objects; import javax.annotation.Nonnull; @@ -46,19 +48,65 @@ public class GoogleJavaFormatFormatterFunc implements FormatterFunc { private final boolean reorderImports; - public GoogleJavaFormatFormatterFunc(@Nonnull String version, @Nonnull String style, boolean reflowStrings, boolean reorderImports, boolean formatJavadoc) { + public GoogleJavaFormatFormatterFunc(@Nonnull String version, @Nonnull String style, boolean reflowStrings, boolean reorderImports, boolean formatJavadoc, int maxLineLength) { this.version = Objects.requireNonNull(version); - this.formatterStyle = Style.valueOf(Objects.requireNonNull(style)); + this.formatterStyle = toStyle(style); this.reflowStrings = reflowStrings; this.reorderImports = reorderImports; - JavaFormatterOptions.Builder builder = JavaFormatterOptions.builder().style(formatterStyle); + Style effectiveStyle = formatterStyle; + if (maxLineLength > 0) { + effectiveStyle = withMaxLineLength(formatterStyle, maxLineLength, version); + } + JavaFormatterOptions.Builder builder = JavaFormatterOptions.builder().style(effectiveStyle); if (!formatJavadoc) { builder = builder.formatJavadoc(false); } this.formatter = new Formatter(builder.build()); } + /** + * Parses a style name without calling {@code Style.valueOf}, which existed only while + * {@code Style} was an enum (google-java-format {@literal <=} 1.36); since 1.37 it is a record, + * but the {@code GOOGLE} and {@code AOSP} constants are present in both. + */ + @Nonnull + private static Style toStyle(@Nonnull String style) { + switch (Objects.requireNonNull(style)) { + case "GOOGLE": + return Style.GOOGLE; + case "AOSP": + return Style.AOSP; + default: + throw new IllegalArgumentException("style must be GOOGLE or AOSP, but was: " + style); + } + } + + /** + * Sets the column limit on the style's builder. That builder exists only in google-java-format + * 1.37.0+, while this glue code is compiled against 1.28.0 so that it keeps working on older + * versions, hence the reflection (https://github.com/diffplug/spotless/issues/3151). + * Methods are looked up on the public {@code Style$Builder} type rather than on the runtime + * class of the builder, because the runtime class generated by AutoBuilder is package-private. + */ + @Nonnull + private static Style withMaxLineLength(@Nonnull Style style, int maxLineLength, @Nonnull String version) { + try { + Method createBuilder = Style.class.getMethod("builder"); + Class builderType = createBuilder.getReturnType(); + Object builder = createBuilder.invoke(null); + builder = builderType.getMethod(style == Style.AOSP ? "aosp" : "google").invoke(builder); + builder = builderType.getMethod("maxLineLength", int.class).invoke(builder, maxLineLength); + return (Style) builderType.getMethod("build").invoke(builder); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException( + "maxLineLength requires google-java-format 1.37.0 or later (you are using " + version + ")", e); + } catch (IllegalAccessException | InvocationTargetException e) { + Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e; + throw new IllegalArgumentException("Failed to apply maxLineLength " + maxLineLength, cause); + } + } + @Override @Nonnull public String apply(@Nonnull String input) throws Exception { diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java index 079955a731..aeacd3a1f1 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java @@ -18,6 +18,7 @@ import java.io.Serial; import java.io.Serializable; import java.lang.reflect.Constructor; +import java.util.Arrays; import java.util.Objects; import com.diffplug.spotless.FormatterFunc; @@ -34,6 +35,10 @@ public final class GoogleJavaFormatStep implements Serializable { private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false; private static final boolean DEFAULT_REORDER_IMPORTS = false; private static final boolean DEFAULT_FORMAT_JAVADOC = true; + /** 0 means "not set", i.e. use whatever column limit the formatter's style prescribes. */ + private static final int DEFAULT_MAX_LINE_LENGTH = 0; + /** The first version which made `JavaFormatterOptions.Style` configurable, see [#3151](https://github.com/diffplug/spotless/issues/3151). */ + static final String MIN_VERSION_FOR_MAX_LINE_LENGTH = "1.37.0"; private static final String NAME = "google-java-format"; private static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format"; @@ -44,19 +49,22 @@ public final class GoogleJavaFormatStep implements Serializable { private final boolean reflowLongStrings; private final boolean reorderImports; private final boolean formatJavadoc; + private final int maxLineLength; private GoogleJavaFormatStep(JarState.Promised jarState, String version, String style, boolean reflowLongStrings, boolean reorderImports, - boolean formatJavadoc) { + boolean formatJavadoc, + int maxLineLength) { this.jarState = jarState; this.version = version; this.style = style; this.reflowLongStrings = reflowLongStrings; this.reorderImports = reorderImports; this.formatJavadoc = formatJavadoc; + this.maxLineLength = maxLineLength; } /** Creates a step which formats everything - code, import order, and unused imports. */ @@ -89,14 +97,22 @@ public static FormatterStep create(String groupArtifact, String version, String /** Creates a step which formats everything - groupArtifact, code, import order, and unused imports - and optionally reflows long strings. */ public static FormatterStep create(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc) { - return createInternally(NAME, groupArtifact, version, style, provisioner, reflowLongStrings, reorderImports, formatJavadoc, false); + return create(groupArtifact, version, style, provisioner, reflowLongStrings, reorderImports, formatJavadoc, DEFAULT_MAX_LINE_LENGTH); + } + + /** + * Creates a step which formats everything - groupArtifact, code, import order, and unused imports - and optionally reflows long strings. + * A positive {@code maxLineLength} overrides the column limit prescribed by the style, and requires google-java-format {@code 1.37.0} or later. + */ + public static FormatterStep create(String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc, int maxLineLength) { + return createInternally(NAME, groupArtifact, version, style, provisioner, reflowLongStrings, reorderImports, formatJavadoc, maxLineLength, false); } static FormatterStep createRemoveUnusedImportsOnly(Provisioner provisioner) { - return createInternally(RemoveUnusedImportsStep.NAME, MAVEN_COORDINATE, defaultVersion(), defaultStyle(), provisioner, defaultReflowLongStrings(), defaultReorderImports(), defaultFormatJavadoc(), true); + return createInternally(RemoveUnusedImportsStep.NAME, MAVEN_COORDINATE, defaultVersion(), defaultStyle(), provisioner, defaultReflowLongStrings(), defaultReorderImports(), defaultFormatJavadoc(), DEFAULT_MAX_LINE_LENGTH, true); } - private static FormatterStep createInternally(String name, String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc, boolean removeImports) { + private static FormatterStep createInternally(String name, String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings, boolean reorderImports, boolean formatJavadoc, int maxLineLength, boolean removeImports) { Objects.requireNonNull(groupArtifact, "groupArtifact"); if (groupArtifact.chars().filter(ch -> ch == ':').count() != 1) { throw new IllegalArgumentException("groupArtifact must be in the form 'groupId:artifactId'"); @@ -104,8 +120,14 @@ private static FormatterStep createInternally(String name, String groupArtifact, Objects.requireNonNull(version, "version"); Objects.requireNonNull(style, "style"); Objects.requireNonNull(provisioner, "provisioner"); + if (maxLineLength < 0) { + throw new IllegalArgumentException("maxLineLength must be positive, but was: " + maxLineLength); + } + if (maxLineLength > 0 && compareVersions(version, MIN_VERSION_FOR_MAX_LINE_LENGTH) < 0) { + throw new IllegalArgumentException("maxLineLength requires google-java-format " + MIN_VERSION_FOR_MAX_LINE_LENGTH + " or later (you are using " + version + ")"); + } - GoogleJavaFormatStep step = new GoogleJavaFormatStep(JarState.promise(() -> JarState.from(groupArtifact + ":" + version, provisioner)), version, style, reflowLongStrings, reorderImports, formatJavadoc); + GoogleJavaFormatStep step = new GoogleJavaFormatStep(JarState.promise(() -> JarState.from(groupArtifact + ":" + version, provisioner)), version, style, reflowLongStrings, reorderImports, formatJavadoc, maxLineLength); if (removeImports) { return FormatterStep.create(name, step, @@ -150,8 +172,36 @@ public static boolean defaultFormatJavadoc() { return DEFAULT_FORMAT_JAVADOC; } + public static int defaultMaxLineLength() { + return DEFAULT_MAX_LINE_LENGTH; + } + + /** Compares dotted numeric versions, e.g. {@code compareVersions("1.36.1", "1.37.0") < 0}. */ + private static int compareVersions(String left, String right) { + int[] lhs = parseVersion(left); + int[] rhs = parseVersion(right); + int numberOfElements = Math.max(lhs.length, rhs.length); + lhs = Arrays.copyOf(lhs, numberOfElements); + rhs = Arrays.copyOf(rhs, numberOfElements); + for (int i = 0; i < numberOfElements; i++) { + if (lhs[i] != rhs[i]) { + return lhs[i] > rhs[i] ? 1 : -1; + } + } + return 0; + } + + private static int[] parseVersion(String version) { + try { + String withoutSuffix = version.endsWith("-SNAPSHOT") ? version.substring(0, version.length() - "-SNAPSHOT".length()) : version; + return Arrays.stream(withoutSuffix.split("\\.")).mapToInt(Integer::parseInt).toArray(); + } catch (Exception e) { + throw new IllegalArgumentException("Not a semantic version: " + version, e); + } + } + private State equalityState() { - return new State(version, style, jarState.get(), reflowLongStrings, reorderImports, formatJavadoc); + return new State(version, style, jarState.get(), reflowLongStrings, reorderImports, formatJavadoc, maxLineLength); } private static final class State implements Serializable { @@ -164,13 +214,15 @@ private static final class State implements Serializable { private final boolean reflowLongStrings; private final boolean reorderImports; private final boolean formatJavadoc; + private final int maxLineLength; State(String version, String style, JarState jarState, boolean reflowLongStrings, boolean reorderImports, - boolean formatJavadoc) { + boolean formatJavadoc, + int maxLineLength) { JVM_SUPPORT.assertFormatterSupported(version); ModuleHelper.doOpenInternalPackagesIfRequired(); this.jarState = jarState; @@ -179,13 +231,14 @@ private static final class State implements Serializable { this.reflowLongStrings = reflowLongStrings; this.reorderImports = reorderImports; this.formatJavadoc = formatJavadoc; + this.maxLineLength = maxLineLength; } FormatterFunc createFormat() throws Exception { final ClassLoader classLoader = jarState.getClassLoader(); Class formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatFormatterFunc"); - Constructor constructor = formatterFunc.getConstructor(String.class, String.class, boolean.class, boolean.class, boolean.class); - FormatterFunc googleJavaFormatFormatterFunc = (FormatterFunc) constructor.newInstance(version, style, reflowLongStrings, reorderImports, formatJavadoc); + Constructor constructor = formatterFunc.getConstructor(String.class, String.class, boolean.class, boolean.class, boolean.class, int.class); + FormatterFunc googleJavaFormatFormatterFunc = (FormatterFunc) constructor.newInstance(version, style, reflowLongStrings, reorderImports, formatJavadoc, maxLineLength); return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatFormatterFunc); } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index d3249bf262..6c821ca4d1 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -4,6 +4,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +### Features +- `googleJavaFormat` gained `maxLineLength(int)`, which overrides the 100-column limit prescribed by the GOOGLE and AOSP styles. It requires `google-java-format` `1.37.0` or later. ([#3151](https://github.com/diffplug/spotless/issues/3151)) + ## [8.10.4] - 2026-10-08 ### Changes diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index 258fd6450b..886bb7248d 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -380,8 +380,9 @@ spotless { googleJavaFormat() // optional: you can specify a specific version (>= 1.8) and/or switch to AOSP style // and/or reflow long strings + // and/or override the 100-column limit (requires google-java-format 1.37.0+) // and/or use custom group artifact (you probably don't need this) - googleJavaFormat('1.8').aosp().reflowLongStrings().formatJavadoc(false).reorderImports(false).groupArtifact('com.google.googlejavaformat:google-java-format') + googleJavaFormat('1.8').aosp().reflowLongStrings().maxLineLength(120).formatJavadoc(false).reorderImports(false).groupArtifact('com.google.googlejavaformat:google-java-format') ``` ### palantir-java-format diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java index 9411811322..8fa5c20b88 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java @@ -211,6 +211,7 @@ public class GoogleJavaFormatConfig { boolean reflowLongStrings; boolean reorderImports; boolean formatJavadoc = true; + int maxLineLength = GoogleJavaFormatStep.defaultMaxLineLength(); GoogleJavaFormatConfig(String version) { this.version = Objects.requireNonNull(version); @@ -261,6 +262,16 @@ public GoogleJavaFormatConfig formatJavadoc(boolean formatJavadoc) { return this; } + /** + * Overrides the column limit prescribed by the style (100 for both GOOGLE and AOSP). + * Requires google-java-format 1.37.0 or later. + */ + public GoogleJavaFormatConfig maxLineLength(int maxLineLength) { + this.maxLineLength = maxLineLength; + replaceStep(createStep()); + return this; + } + private FormatterStep createStep() { return GoogleJavaFormatStep.create( groupArtifact, @@ -269,7 +280,8 @@ private FormatterStep createStep() { provisioner(), reflowLongStrings, reorderImports, - formatJavadoc); + formatJavadoc, + maxLineLength); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java index dde872d3e5..869126a170 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java @@ -15,6 +15,8 @@ */ package com.diffplug.gradle.spotless; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + import java.io.IOException; import org.junit.jupiter.api.Test; @@ -101,4 +103,28 @@ void integrationWithSkipJavadocFormatting() throws IOException { "googleJavaFormat()"); checkRunsThenUpToDate(); } + + @Test + void integrationWithMaxLineLength() throws IOException { + assumeTrue(Jvm.version() >= 21, "google-java-format 1.37.0 requires JVM 21+"); + + setFile("build.gradle").toLines( + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "", + "spotless {", + " java {", + " target file('test.java')", + " googleJavaFormat('1.37.0').maxLineLength(240)", + " }", + "}"); + + setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); + gradleRunner().withArguments("spotlessApply").build(); + assertFile("test.java").sameAsResource("java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test"); + + checkRunsThenUpToDate(); + } } diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 46c259e6e9..3576459072 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -4,6 +4,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] +### Features +- `` gained a `` parameter, which overrides the 100-column limit prescribed by the GOOGLE and AOSP styles. It requires `google-java-format` `1.37.0` or later. ([#3151](https://github.com/diffplug/spotless/issues/3151)) + ## [3.10.4] - 2026-10-08 ### Changes diff --git a/plugin-maven/README.md b/plugin-maven/README.md index de25140289..f034c527de 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -343,6 +343,7 @@ Types in `java.lang` and in the file's own package are shortened without adding 1.8 true + 120 false false. diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java index d0a2b24954..8b88ab3d57 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/GoogleJavaFormat.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 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. @@ -41,6 +41,9 @@ public class GoogleJavaFormat implements FormatterStepFactory { @Parameter private Boolean formatJavadoc; + @Parameter + private Integer maxLineLength; + @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { String groupArtifact = this.groupArtifact != null ? this.groupArtifact : GoogleJavaFormatStep.defaultGroupArtifact(); @@ -49,6 +52,7 @@ public FormatterStep newFormatterStep(FormatterStepConfig config) { boolean reflowLongStrings = this.reflowLongStrings != null ? this.reflowLongStrings : GoogleJavaFormatStep.defaultReflowLongStrings(); boolean reorderImports = this.reorderImports != null ? this.reorderImports : GoogleJavaFormatStep.defaultReorderImports(); boolean formatJavadoc = this.formatJavadoc != null ? this.formatJavadoc : GoogleJavaFormatStep.defaultFormatJavadoc(); - return GoogleJavaFormatStep.create(groupArtifact, version, style, config.getProvisioner(), reflowLongStrings, reorderImports, formatJavadoc); + int maxLineLength = this.maxLineLength != null ? this.maxLineLength : GoogleJavaFormatStep.defaultMaxLineLength(); + return GoogleJavaFormatStep.create(groupArtifact, version, style, config.getProvisioner(), reflowLongStrings, reorderImports, formatJavadoc, maxLineLength); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java index 0723d73c0e..eed60d531b 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java @@ -15,8 +15,11 @@ */ package com.diffplug.spotless.maven.java; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + import org.junit.jupiter.api.Test; +import com.diffplug.spotless.Jvm; import com.diffplug.spotless.java.GoogleJavaFormatStep; import com.diffplug.spotless.maven.MavenIntegrationHarness; @@ -76,6 +79,19 @@ void specificVersionSkipJavadocFormatting() throws Exception { runTest("java/googlejavaformat/JavaCodeFormattedSkipJavadocFormatting.test"); } + @Test + void specificVersionMaxLineLength() throws Exception { + assumeTrue(Jvm.version() >= 21, "google-java-format 1.37.0 requires JVM 21+"); + + writePomWithJavaSteps( + "", + " 1.37.0", + " 240", + ""); + + runTest("java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test"); + } + private void runTest(String targetResource) throws Exception { runTest(targetResource, "java/googlejavaformat/JavaCodeUnformatted.test"); } diff --git a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test new file mode 100644 index 0000000000..2000494af2 --- /dev/null +++ b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test @@ -0,0 +1,11 @@ +import mylib.UsedA; +import mylib.UsedB; + +public class Java { + /** Some javadoc. */ + public static void main(String[] args) { + System.out.println("A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length."); + UsedB.someMethod(); + UsedA.someMethod(); + } +} diff --git a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java index cae19f4bca..ebd992490b 100644 --- a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.java; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_20; import static org.junit.jupiter.api.condition.JRE.JAVA_21; import static org.junit.jupiter.api.condition.JRE.JAVA_25; @@ -140,6 +142,37 @@ void behaviorWithReorderImports() throws Exception { } } + @Test + @EnabledForJreRange(min = JAVA_21) + void behavior137() throws Exception { + FormatterStep step = GoogleJavaFormatStep.create("1.37.0", TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test"); + } + + @Test + @EnabledForJreRange(min = JAVA_21) + void behaviorWithMaxLineLength() throws Exception { + FormatterStep step = GoogleJavaFormatStep.create( + GoogleJavaFormatStep.defaultGroupArtifact(), + "1.37.0", + GoogleJavaFormatStep.defaultStyle(), + TestProvisioner.mavenCentral(), + GoogleJavaFormatStep.defaultReflowLongStrings(), + GoogleJavaFormatStep.defaultReorderImports(), + GoogleJavaFormatStep.defaultFormatJavadoc(), + 240); + StepHarness.forStep(step) + .testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormattedMaxLineLength240.test"); + } + + @Test + void maxLineLengthRequiresVersion1Dot37OrLater() { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.36.1", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false, false, true, 120)); + assertTrue(error.getMessage().contains("maxLineLength requires google-java-format 1.37.0 or later"), error.getMessage()); + } + @Test @EnabledForJreRange(max = JAVA_20) void equality() throws Exception {