diff --git a/CHANGES.md b/CHANGES.md index c0deba72dc..ec06be1db5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,9 @@ 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] +### Changes +* **POTENTIALLY BREAKING** Converted `googleJavaFormat` to a compile-only dependency and drop support for versions < `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) +* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) ## [2.37.0] - 2023-03-13 ### Added diff --git a/lib/build.gradle b/lib/build.gradle index 9a6e7913d5..e712df9850 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -10,6 +10,7 @@ apply from: rootProject.file('gradle/java-publish.gradle') def NEEDS_GLUE = [ 'sortPom', 'palantirJavaFormat', + 'googleJavaFormat', 'ktfmt', 'ktlint', 'flexmark', @@ -70,6 +71,8 @@ dependencies { palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' // this version needs to stay compilable against Java 8 for CI Job testNpm + googleJavaFormatCompileOnly 'com.google.googlejavaformat:google-java-format:1.8' // minimum required version due to api changes before then + // used jackson-based formatters jacksonCompileOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.2' jacksonCompileOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2' 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 new file mode 100644 index 0000000000..f45394979a --- /dev/null +++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java @@ -0,0 +1,70 @@ +/* + * Copyright 2023 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.glue.java; + +import java.util.Objects; + +import javax.annotation.Nonnull; + +import com.google.googlejavaformat.java.Formatter; +import com.google.googlejavaformat.java.FormatterException; +import com.google.googlejavaformat.java.ImportOrderer; +import com.google.googlejavaformat.java.JavaFormatterOptions; +import com.google.googlejavaformat.java.RemoveUnusedImports; +import com.google.googlejavaformat.java.StringWrapper; + +import com.diffplug.spotless.FormatterFunc; + +public class GoogleJavaFormatFormatterFunc implements FormatterFunc { + + @Nonnull + private final Formatter formatter; + + @Nonnull + private final String version; + + @Nonnull + private final JavaFormatterOptions.Style formatterStyle; + + private final boolean reflowStrings; + + public GoogleJavaFormatFormatterFunc(@Nonnull String version, @Nonnull String style, boolean reflowStrings) { + this.version = Objects.requireNonNull(version); + this.formatterStyle = JavaFormatterOptions.Style.valueOf(Objects.requireNonNull(style)); + this.reflowStrings = reflowStrings; + + this.formatter = new Formatter(JavaFormatterOptions.builder() + .style(formatterStyle) + .build()); + } + + @Override + @Nonnull + public String apply(@Nonnull String input) throws Exception { + String formatted = formatter.formatSource(input); + String removedUnused = RemoveUnusedImports.removeUnusedImports(formatted); + String sortedImports = ImportOrderer.reorderImports(removedUnused, formatterStyle); + return reflowLongStrings(sortedImports); + } + + private String reflowLongStrings(String input) throws FormatterException { + if (reflowStrings) { + return StringWrapper.wrap(input, formatter); + } else { + return input; + } + } +} diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java new file mode 100644 index 0000000000..de21a18795 --- /dev/null +++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java @@ -0,0 +1,40 @@ +/* + * Copyright 2023 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.glue.java; + +import java.util.Objects; + +import javax.annotation.Nonnull; + +import com.google.googlejavaformat.java.RemoveUnusedImports; + +import com.diffplug.spotless.FormatterFunc; + +public class GoogleJavaFormatRemoveUnusedImporterFormatterFunc implements FormatterFunc { + + @Nonnull + private final String version; + + public GoogleJavaFormatRemoveUnusedImporterFormatterFunc(@Nonnull String version) { + this.version = Objects.requireNonNull(version); + } + + @Override + @Nonnull + public String apply(@Nonnull String input) throws Exception { + return RemoveUnusedImports.removeUnusedImports(input); + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/Jvm.java b/lib/src/main/java/com/diffplug/spotless/Jvm.java index c9c71b72df..7c9ad5b47a 100644 --- a/lib/src/main/java/com/diffplug/spotless/Jvm.java +++ b/lib/src/main/java/com/diffplug/spotless/Jvm.java @@ -63,8 +63,9 @@ public static int version() { public static class Support { private final String fmtName; private final Comparator fmtVersionComparator; - private final NavigableMap jvm2fmtVersion; - private final NavigableMap fmt2jvmVersion; + private final NavigableMap jvm2fmtMaxVersion; + private final NavigableMap jvm2fmtMinVersion; + private final NavigableMap fmtMaxVersion2jvmVersion; private Support(String fromatterName) { this(fromatterName, new SemanticVersionComparator()); @@ -73,40 +74,60 @@ private Support(String fromatterName) { private Support(String formatterName, Comparator formatterVersionComparator) { fmtName = formatterName; fmtVersionComparator = formatterVersionComparator; - jvm2fmtVersion = new TreeMap(); - fmt2jvmVersion = new TreeMap(formatterVersionComparator); + jvm2fmtMaxVersion = new TreeMap<>(); + jvm2fmtMinVersion = new TreeMap<>(); + fmtMaxVersion2jvmVersion = new TreeMap<>(formatterVersionComparator); } /** - * Add supported formatter version + * Add maximum supported formatter version * @param minimumJvmVersion Minimum Java version required * @param maxFormatterVersion Maximum formatter version supported by the Java version * @return this */ public Support add(int minimumJvmVersion, V maxFormatterVersion) { Objects.requireNonNull(maxFormatterVersion); - if (null != jvm2fmtVersion.put(minimumJvmVersion, maxFormatterVersion)) { + if (null != jvm2fmtMaxVersion.put(minimumJvmVersion, maxFormatterVersion)) { throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion)); } - if (null != fmt2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) { + if (null != fmtMaxVersion2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) { throw new IllegalArgumentException(String.format("Added duplicate entry for formatter version %s.", maxFormatterVersion)); } + verifyVersionRangesDoNotIntersect(jvm2fmtMaxVersion, minimumJvmVersion, maxFormatterVersion); + return this; + } + + public Support addMin(int minimumJvmVersion, V minFormatterVersion) { + Objects.requireNonNull(minFormatterVersion); + if (null != jvm2fmtMinVersion.put(minimumJvmVersion, minFormatterVersion)) { + throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion)); + } + verifyVersionRangesDoNotIntersect(jvm2fmtMinVersion, minimumJvmVersion, minFormatterVersion); + return this; + } + + private void verifyVersionRangesDoNotIntersect(NavigableMap jvm2fmtVersion, int minimumJvmVersion, V formatterVersion) { Map.Entry lower = jvm2fmtVersion.lowerEntry(minimumJvmVersion); - if ((null != lower) && (fmtVersionComparator.compare(maxFormatterVersion, lower.getValue()) <= 0)) { - throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, maxFormatterVersion, lower.getKey(), lower.getValue())); + if ((null != lower) && (fmtVersionComparator.compare(formatterVersion, lower.getValue()) <= 0)) { + throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, formatterVersion, lower.getKey(), lower.getValue())); } Map.Entry higher = jvm2fmtVersion.higherEntry(minimumJvmVersion); - if ((null != higher) && (fmtVersionComparator.compare(maxFormatterVersion, higher.getValue()) >= 0)) { - throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, maxFormatterVersion, higher.getKey(), higher.getValue())); + if ((null != higher) && (fmtVersionComparator.compare(formatterVersion, higher.getValue()) >= 0)) { + throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, formatterVersion, higher.getKey(), higher.getValue())); } - return this; } /** @return Highest formatter version recommended for this JVM (null, if JVM not supported) */ @Nullable public V getRecommendedFormatterVersion() { - Integer configuredJvmVersionOrNull = jvm2fmtVersion.floorKey(Jvm.version()); - return (null == configuredJvmVersionOrNull) ? null : jvm2fmtVersion.get(configuredJvmVersionOrNull); + Integer configuredJvmVersionOrNull = jvm2fmtMaxVersion.floorKey(Jvm.version()); + return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMaxVersion.get(configuredJvmVersionOrNull); + } + + @Nullable + public V getMinimumRequiredFormatterVersion() { + Integer configuredJvmVersionOrNull = jvm2fmtMinVersion.floorKey(Jvm.version()); + return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMinVersion.get(configuredJvmVersionOrNull); } /** @@ -123,10 +144,17 @@ public void assertFormatterSupported(V formatterVersion) { } private String buildUnsupportedFormatterMessage(V fmtVersion) { + // check if the jvm version is to low for the formatter version int requiredJvmVersion = getRequiredJvmVersion(fmtVersion); if (Jvm.version() < requiredJvmVersion) { return buildUpgradeJvmMessage(fmtVersion) + "Upgrade your JVM or try " + toString(); } + // check if the formatter version is too low for the jvm version + V minimumFormatterVersion = getMinimumRequiredFormatterVersion(); + if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) { + return String.format("You are running Spotless on JVM %d. This requires %s of at least %s (you are using %s).%n", Jvm.version(), fmtName, minimumFormatterVersion, fmtVersion); + } + // otherwise all is well return ""; } @@ -137,7 +165,7 @@ private String buildUpgradeJvmMessage(V fmtVersion) { if (null != recommendedFmtVersionOrNull) { builder.append(String.format(", which limits you to %s %s.%n", fmtName, recommendedFmtVersionOrNull)); } else { - Entry nextFmtVersionOrNull = fmt2jvmVersion.ceilingEntry(fmtVersion); + Entry nextFmtVersionOrNull = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion); if (null != nextFmtVersionOrNull) { builder.append(String.format(". %s %s requires JVM %d+", fmtName, fmtVersion, nextFmtVersionOrNull.getValue())); } @@ -147,12 +175,12 @@ private String buildUpgradeJvmMessage(V fmtVersion) { } private int getRequiredJvmVersion(V fmtVersion) { - Entry entry = fmt2jvmVersion.ceilingEntry(fmtVersion); + Entry entry = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion); if (null == entry) { - entry = fmt2jvmVersion.lastEntry(); + entry = fmtMaxVersion2jvmVersion.lastEntry(); } if (null != entry) { - V maxKnownFmtVersion = jvm2fmtVersion.get(entry.getValue()); + V maxKnownFmtVersion = jvm2fmtMaxVersion.get(entry.getValue()); if (fmtVersionComparator.compare(fmtVersion, maxKnownFmtVersion) <= 0) { return entry.getValue(); } @@ -170,15 +198,15 @@ public FormatterFunc suggestLaterVersionOnError(V formatterVersion, FormatterFun Objects.requireNonNull(formatterVersion); Objects.requireNonNull(originalFunc); final String hintUnsupportedProblem = buildUnsupportedFormatterMessage(formatterVersion); - final String proposeDiffererntFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem; - return proposeDiffererntFormatter.isEmpty() ? originalFunc : new FormatterFunc() { + final String proposeDifferentFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem; + return proposeDifferentFormatter.isEmpty() ? originalFunc : new FormatterFunc() { @Override public String apply(String unix, File file) throws Exception { try { return originalFunc.apply(unix, file); } catch (Exception e) { - throw new Exception(proposeDiffererntFormatter, e); + throw new Exception(proposeDifferentFormatter, e); } } @@ -187,7 +215,7 @@ public String apply(String input) throws Exception { try { return originalFunc.apply(input); } catch (Exception e) { - throw new Exception(proposeDiffererntFormatter, e); + throw new Exception(proposeDifferentFormatter, e); } } @@ -196,16 +224,25 @@ public String apply(String input) throws Exception { private String buildUpgradeFormatterMessage(V fmtVersion) { StringBuilder builder = new StringBuilder(); + // check if the formatter is not supported on this jvm + V minimumFormatterVersion = getMinimumRequiredFormatterVersion(); V recommendedFmtVersionOrNull = getRecommendedFormatterVersion(); - if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) { + if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) { + builder.append(String.format("You are running Spotless on JVM %d. This requires %s of at least %s.%n", Jvm.version(), fmtName, minimumFormatterVersion)); + builder.append(String.format("You are using %s %s.%n", fmtName, fmtVersion)); + if (null != recommendedFmtVersionOrNull) { + builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull)); + } + // check if the formatter is outdated on this jvm + } else if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) { builder.append(String.format("%s %s is currently being used, but outdated.%n", fmtName, fmtVersion)); builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull)); builder.append(String.format("%s %s requires JVM %d+.", fmtName, recommendedFmtVersionOrNull, getRequiredJvmVersion(recommendedFmtVersionOrNull))); } else { - V higherFormatterVersionOrNull = fmt2jvmVersion.higherKey(fmtVersion); + V higherFormatterVersionOrNull = fmtMaxVersion2jvmVersion.higherKey(fmtVersion); if (null != higherFormatterVersionOrNull) { builder.append(buildUpgradeJvmMessage(fmtVersion)); - Integer higherJvmVersion = fmt2jvmVersion.get(higherFormatterVersionOrNull); + Integer higherJvmVersion = fmtMaxVersion2jvmVersion.get(higherFormatterVersionOrNull); builder.append(String.format("If you upgrade your JVM to %d+, then you can use %s %s, which may have fixed this problem.", higherJvmVersion, fmtName, higherFormatterVersionOrNull)); } } @@ -215,7 +252,7 @@ private String buildUpgradeFormatterMessage(V fmtVersion) { @Override public String toString() { return String.format("%s alternatives:%n", fmtName) + - jvm2fmtVersion.entrySet().stream().map( + jvm2fmtMaxVersion.entrySet().stream().map( e -> String.format("- Version %s requires JVM %d+", e.getValue(), e.getKey())).collect(Collectors.joining(System.lineSeparator())); } 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 6390c619a9..d7ba26f384 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,14 @@ package com.diffplug.spotless.java; import java.io.Serializable; -import java.lang.reflect.Method; +import java.lang.reflect.Constructor; import java.util.Objects; import com.diffplug.spotless.FormatterFunc; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.JarState; import com.diffplug.spotless.Jvm; -import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; -import com.diffplug.spotless.ThrowingEx.BiFunction; -import com.diffplug.spotless.ThrowingEx.Function; /** Wraps up google-java-format as a FormatterStep. */ public class GoogleJavaFormatStep { @@ -37,27 +34,6 @@ private GoogleJavaFormatStep() {} private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false; static final String NAME = "google-java-format"; static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format"; - static final String FORMATTER_CLASS = "com.google.googlejavaformat.java.Formatter"; - static final String FORMATTER_METHOD = "formatSource"; - - private static final String OPTIONS_CLASS = "com.google.googlejavaformat.java.JavaFormatterOptions"; - private static final String OPTIONS_BUILDER_METHOD = "builder"; - private static final String OPTIONS_BUILDER_CLASS = "com.google.googlejavaformat.java.JavaFormatterOptions$Builder"; - private static final String OPTIONS_BUILDER_STYLE_METHOD = "style"; - private static final String OPTIONS_BUILDER_BUILD_METHOD = "build"; - private static final String OPTIONS_Style = "com.google.googlejavaformat.java.JavaFormatterOptions$Style"; - - private static final String REMOVE_UNUSED_CLASS = "com.google.googlejavaformat.java.RemoveUnusedImports"; - private static final String REMOVE_UNUSED_METHOD = "removeUnusedImports"; - - private static final String REMOVE_UNUSED_IMPORT_JavadocOnlyImports = "com.google.googlejavaformat.java.RemoveUnusedImports$JavadocOnlyImports"; - private static final String REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep = "KEEP"; - - private static final String IMPORT_ORDERER_CLASS = "com.google.googlejavaformat.java.ImportOrderer"; - private static final String IMPORT_ORDERER_METHOD = "reorderImports"; - - private static final String STRING_WRAPPER_CLASS = "com.google.googlejavaformat.java.StringWrapper"; - private static final String STRING_WRAPPER_METHOD = "wrap"; /** Creates a step which formats everything - code, import order, and unused imports. */ public static FormatterStep create(Provisioner provisioner) { @@ -93,7 +69,10 @@ public static FormatterStep create(String groupArtifact, String version, String State::createFormat); } - static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME).add(8, "1.7").add(11, "1.15.0"); + static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME) + .addMin(11, "1.8") // we only support google-java-format >= 1.8 due to api changes + .addMin(16, "1.10.0") // java 16 requires at least 1.10.0 due to jdk api changes in JavaTokenizer + .add(11, "1.16.0"); // default version public static String defaultGroupArtifact() { return MAVEN_COORDINATE; @@ -144,120 +123,24 @@ static final class State implements Serializable { this.reflowLongStrings = reflowLongStrings; } - @SuppressWarnings({"unchecked", "rawtypes"}) FormatterFunc createFormat() throws Exception { - ClassLoader classLoader = jarState.getClassLoader(); - - // instantiate the formatter and get its format method - Class optionsClass = classLoader.loadClass(OPTIONS_CLASS); - Class optionsBuilderClass = classLoader.loadClass(OPTIONS_BUILDER_CLASS); - Method optionsBuilderMethod = optionsClass.getMethod(OPTIONS_BUILDER_METHOD); - Object optionsBuilder = optionsBuilderMethod.invoke(null); - - Class optionsStyleClass = classLoader.loadClass(OPTIONS_Style); - Object styleConstant = Enum.valueOf((Class) optionsStyleClass, style); - Method optionsBuilderStyleMethod = optionsBuilderClass.getMethod(OPTIONS_BUILDER_STYLE_METHOD, optionsStyleClass); - optionsBuilderStyleMethod.invoke(optionsBuilder, styleConstant); - - Method optionsBuilderBuildMethod = optionsBuilderClass.getMethod(OPTIONS_BUILDER_BUILD_METHOD); - Object options = optionsBuilderBuildMethod.invoke(optionsBuilder); - - Class formatterClazz = classLoader.loadClass(FORMATTER_CLASS); - Object formatter = formatterClazz.getConstructor(optionsClass).newInstance(options); - Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class); + 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); + FormatterFunc googleJavaFormatFormatterFunc = (FormatterFunc) constructor.newInstance(version, style, reflowLongStrings); - Function removeUnused = constructRemoveUnusedFunction(classLoader); - - Class importOrdererClass = classLoader.loadClass(IMPORT_ORDERER_CLASS); - Method importOrdererMethod = importOrdererClass.getMethod(IMPORT_ORDERER_METHOD, String.class); - - BiFunction reflowLongStrings = this.reflowLongStrings ? constructReflowLongStringsFunction(classLoader, formatterClazz) : (s, f) -> s; - - return JVM_SUPPORT.suggestLaterVersionOnError(version, (input -> { - String formatted = (String) formatterMethod.invoke(formatter, input); - String removedUnused = removeUnused.apply(formatted); - String sortedImports = (String) importOrdererMethod.invoke(null, removedUnused); - String reflowedLongStrings = reflowLongStrings.apply(sortedImports, formatter); - return fixWindowsBug(reflowedLongStrings, version); - })); + return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatFormatterFunc); } FormatterFunc createRemoveUnusedImportsOnly() throws Exception { ClassLoader classLoader = jarState.getClassLoader(); - Function removeUnused = constructRemoveUnusedFunction(classLoader); - return JVM_SUPPORT.suggestLaterVersionOnError(version, (input -> fixWindowsBug(removeUnused.apply(input), version))); - } - - private static Function constructRemoveUnusedFunction(ClassLoader classLoader) - throws NoSuchMethodException, ClassNotFoundException { - Class removeUnusedClass = classLoader.loadClass(REMOVE_UNUSED_CLASS); - Class removeJavadocOnlyClass; - try { - // google-java-format 1.7 or lower - removeJavadocOnlyClass = classLoader.loadClass(REMOVE_UNUSED_IMPORT_JavadocOnlyImports); - } catch (ClassNotFoundException e) { - // google-java-format 1.8+ - removeJavadocOnlyClass = null; - } + Class formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatRemoveUnusedImporterFormatterFunc"); + Constructor constructor = formatterFunc.getConstructor(String.class); //version + FormatterFunc googleJavaFormatRemoveUnusedImporterFormatterFunc = (FormatterFunc) constructor.newInstance(version); - Function removeUnused; - if (removeJavadocOnlyClass != null) { - @SuppressWarnings({"unchecked", "rawtypes"}) - Object removeJavadocConstant = Enum.valueOf((Class) removeJavadocOnlyClass, REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep); - Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class, removeJavadocOnlyClass); - removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x, removeJavadocConstant); - } else { - Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class); - removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x); - } - return removeUnused; + return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatRemoveUnusedImporterFormatterFunc); } - private static BiFunction constructReflowLongStringsFunction(ClassLoader classLoader, Class formatterClazz) throws NoSuchMethodException { - Class stringWrapperClass; - try { - stringWrapperClass = classLoader.loadClass(STRING_WRAPPER_CLASS); - } catch (ClassNotFoundException e) { - // google-java-format 1.7 or lower, which happen to be LATEST_VERSION_JRE_8, so rely on suggestJre11 for the error - return (s, f) -> { - throw e; - }; - } - Method stringWrapperMethod = stringWrapperClass.getMethod(STRING_WRAPPER_METHOD, String.class, formatterClazz); - return (s, f) -> (String) stringWrapperMethod.invoke(null, s, f); - } } - private static final boolean IS_WINDOWS = LineEnding.PLATFORM_NATIVE.str().equals("\r\n"); - - /** - * google-java-format-1.1's removeUnusedImports does *wacky* stuff on Windows. - * The beauty of normalizing all line endings to unix! - */ - static String fixWindowsBug(String input, String version) { - if (IS_WINDOWS && version.equals("1.1")) { - int firstImport = input.indexOf("\nimport "); - if (firstImport == 0) { - return input; - } else if (firstImport > 0) { - int numToTrim = 0; - char prevChar; - do { - ++numToTrim; - prevChar = input.charAt(firstImport - numToTrim); - } while (Character.isWhitespace(prevChar) && (firstImport - numToTrim) > 0); - if (firstImport - numToTrim == 0) { - // import was the very first line, and we'd like to maintain a one-line gap - ++numToTrim; - } else if (prevChar == ';' || prevChar == '/') { - // import came after either license or a package declaration - --numToTrim; - } - if (numToTrim > 0) { - return input.substring(0, firstImport - numToTrim + 2) + input.substring(firstImport + 1); - } - } - } - return input; - } } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 2c85978621..ef7b1b8dae 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -3,6 +3,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`). ## [Unreleased] +### Changes +* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions < `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) +* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) ## [6.17.0] - 2023-03-13 ### Added diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md index fffdb38518..616aacdb1f 100644 --- a/plugin-gradle/README.md +++ b/plugin-gradle/README.md @@ -187,8 +187,8 @@ spotless { spotless { java { googleJavaFormat() - // optional: you can specify a specific version and/or switch to AOSP style - // and/or reflow long strings (requires at least 1.8) + // optional: you can specify a specific version (>= 1.8) and/or switch to AOSP style + // and/or reflow long strings // and/or use custom group artifact (you probably don't need this) googleJavaFormat('1.8').aosp().reflowLongStrings().groupArtifact('com.google.googlejavaformat:google-java-format') ``` diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java index d5422a3631..bd521bd864 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ void noConfigOnHelp() throws IOException { "apply plugin: 'java'", "spotless {", " java {", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}", "", diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java index 4006752af2..396a884cc5 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 DiffPlug + * Copyright 2020-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ public void helpConfigures() throws IOException { "apply plugin: 'java'", "spotless {", " java {", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); gradleRunner().withArguments("help").build(); @@ -55,7 +55,7 @@ public void helpConfiguresIfTasksAreCreated() throws IOException { "apply plugin: 'java'", "spotless {", " java {", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}", "tasks.named('spotlessJavaApply').get()"); @@ -72,7 +72,7 @@ public void jvmLocalCache() throws IOException { "spotless {", " java {", " target file('test.java')", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java index a5ce2d11cd..d342348a5b 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 DiffPlug + * Copyright 2020-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ void spotlessApplyShouldPreservePermissions() throws IOException { "spotless {", " java {", " target file('test.java')", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); 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 1f5cb6af05..5c7fe54f59 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ void integration() throws IOException { "spotless {", " java {", " target file('test.java')", - " googleJavaFormat('1.2')", + " googleJavaFormat('1.10.0')", " }", "}"); @@ -41,8 +41,8 @@ void integration() throws IOException { checkRunsThenUpToDate(); replace("build.gradle", - "googleJavaFormat('1.2')", - "googleJavaFormat('1.3')"); + "googleJavaFormat('1.10.0')", + "googleJavaFormat()"); checkRunsThenUpToDate(); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java index 459b871b94..4062aae51d 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ void independent() throws IOException { "", "def underTest = new JavaExtension(spotless)", "underTest.target file('test.java')", - "underTest.googleJavaFormat('1.2')", + "underTest.googleJavaFormat()", "", "def independent = underTest.createIndependentApplyTask('independent')"); setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java index 898008c27a..e6569b2647 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ void integration() throws IOException { "", "spotless {", " java {", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); setFile("src/main/java/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java index 086a2ddb1d..98761b472a 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,7 @@ void createSubproject(String name) throws IOException { "spotless {", " java {", " target file('test.java')", - " googleJavaFormat('1.2')", + " googleJavaFormat('1.16.0')", " }", "}"); setFile(name + "/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); @@ -71,7 +71,7 @@ public void hasRootSpotless() throws IOException { "spotless {", " java {", " target file('test.java')", - " googleJavaFormat('1.2')", + " googleJavaFormat('1.16.0')", " }", "}"); setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); @@ -88,7 +88,7 @@ public void predeclaredFails() throws IOException { "spotless { predeclareDeps() }"); createNSubprojects(); Assertions.assertThat(gradleRunner().withArguments("spotlessApply").buildAndFail().getOutput()) - .contains("Add a step with [com.google.googlejavaformat:google-java-format:1.2] into the `spotlessPredeclare` block in the root project."); + .contains("Add a step with [com.google.googlejavaformat:google-java-format:1.16.0] into the `spotlessPredeclare` block in the root project."); } @Test @@ -100,7 +100,7 @@ public void predeclaredSucceeds() throws IOException { "repositories { mavenCentral() }", "spotless { predeclareDeps() }", "spotlessPredeclare {", - " java { googleJavaFormat('1.2') }", + " java { googleJavaFormat('1.16.0') }", "}"); createNSubprojects(); gradleRunner().withArguments("spotlessApply").build(); @@ -115,7 +115,7 @@ public void predeclaredFromBuildscriptSucceeds() throws IOException { "repositories { mavenCentral() }", "spotless { predeclareDepsFromBuildscript() }", "spotlessPredeclare {", - " java { googleJavaFormat('1.2') }", + " java { googleJavaFormat('1.16.0') }", "}"); createNSubprojects(); gradleRunner().withArguments("spotlessApply").build(); @@ -129,7 +129,7 @@ public void predeclaredOrdering() throws IOException { "}", "repositories { mavenCentral() }", "spotlessPredeclare {", - " java { googleJavaFormat('1.2') }", + " java { googleJavaFormat('1.16.0') }", "}", "spotless { predeclareDepsFromBuildscript() }"); createNSubprojects(); @@ -145,7 +145,7 @@ public void predeclaredUndeclared() throws IOException { "}", "repositories { mavenCentral() }", "spotlessPredeclare {", - " java { googleJavaFormat('1.2') }", + " java { googleJavaFormat('1.16.0') }", "}"); createNSubprojects(); Assertions.assertThat(gradleRunner().withArguments("spotlessApply").buildAndFail().getOutput()) diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java index 480de4f01b..76d0449060 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,11 +32,11 @@ void duplicateConfigs() throws IOException { "spotless {", " java {", " target 'src/main/java/**/*.java'", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", " format 'javaDupe', com.diffplug.gradle.spotless.JavaExtension, {", " target 'src/boop/java/**/*.java'", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java index 01fb048b66..d1df8b5f96 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 DiffPlug + * Copyright 2020-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ void genericFormatTest() throws IOException { "spotless {", " format 'customJava', JavaExtension, {", " target '*.java'", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", "}"); setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); @@ -53,7 +53,7 @@ void withinBlocksTourDeForce() throws IOException { " custom 'lowercase', { str -> str.toLowerCase() }", " }", " withinBlocks 'java only', '\\n```java\\n', '\\n```\\n', JavaExtension, {", - " googleJavaFormat('1.2')", + " googleJavaFormat()", " }", " }", "}"); diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 33e85b9f26..421b5e56e7 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,6 +3,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Changes +* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions < `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) +* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630)) ## [2.35.0] - 2023-03-13 ### Added diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 6d13bc87f3..5971721e24 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -213,9 +213,9 @@ any other maven phase (i.e. compile) then it can be configured as below; ```xml - 1.8 + 1.8 - true + true com.google.googlejavaformat:google-java-format diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java index cabbf7c5c0..5af146c736 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java @@ -33,7 +33,7 @@ void testMultipleDependenciesExcludingTransitives() throws Exception { void testSingleDependencyIncludingTransitives() throws Exception { writePomWithJavaSteps( "", - " 1.2", + " 1.10.0", ""); assertResolveDependenciesWorks(); } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java index 55cd586582..11cca5994a 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ private void integration(String patterns, boolean firstFormatted, boolean second " src/**/java/**/*.java", "", "", - " 1.2", + " 1.10.0", ""); setFile(testFile(1)).toResource(fixture(false)); 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 98a83d612c..407d089999 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 @@ -24,7 +24,7 @@ class GoogleJavaFormatTest extends MavenIntegrationHarness { void specificVersionDefaultStyle() throws Exception { writePomWithJavaSteps( "", - " 1.2", + " 1.10.0", ""); runTest("java/googlejavaformat/JavaCodeFormatted.test"); @@ -34,7 +34,7 @@ void specificVersionDefaultStyle() throws Exception { void specificVersionSpecificStyle() throws Exception { writePomWithJavaSteps( "", - " 1.2", + " 1.10.0", " ", ""); @@ -45,7 +45,7 @@ void specificVersionSpecificStyle() throws Exception { void specificVersionReflowLongStrings() throws Exception { writePomWithJavaSteps( "", - " 1.8", + " 1.10.0", " true", ""); diff --git a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test index 7f7483f1bc..7a83a0a12c 100644 --- a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test +++ b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test @@ -1,4 +1,3 @@ - import mylib.UsedA; import mylib.UsedB; diff --git a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test index dd1493b8c8..25ccbc25f5 100644 --- a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test +++ b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test @@ -1,4 +1,3 @@ - import mylib.UsedA; import mylib.UsedB; 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 ff64b574e1..694e390727 100644 --- a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java @@ -17,12 +17,11 @@ import static org.junit.jupiter.api.condition.JRE.JAVA_13; import static org.junit.jupiter.api.condition.JRE.JAVA_15; +import static org.junit.jupiter.api.condition.JRE.JAVA_16; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; -import com.diffplug.common.base.StringPrinter; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.Jvm; import com.diffplug.spotless.ResourceHarness; @@ -53,7 +52,7 @@ void behavior18() throws Exception { @Test void behavior() throws Exception { - FormatterStep step = GoogleJavaFormatStep.create("1.2", TestProvisioner.mavenCentral()); + FormatterStep step = GoogleJavaFormatStep.create("1.10.0", TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test") .testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test") @@ -62,8 +61,25 @@ void behavior() throws Exception { } @Test - void behaviorWithAospStyle() throws Exception { + void versionBelowMinimumRequiredVersionIsNotAllowed() throws Exception { FormatterStep step = GoogleJavaFormatStep.create("1.2", "AOSP", TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResourceExceptionMsg("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test") + .contains("you are using 1.2"); + } + + @Test + @EnabledForJreRange(min = JAVA_16) + void versionBelowOneDotTenIsNotAllowed() throws Exception { + FormatterStep step = GoogleJavaFormatStep.create("1.9", "AOSP", TestProvisioner.mavenCentral()); + StepHarness.forStep(step) + .testResourceExceptionMsg("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test") + .contains("you are using 1.9"); + } + + @Test + void behaviorWithAospStyle() throws Exception { + FormatterStep step = GoogleJavaFormatStep.create("1.10.0", "AOSP", TestProvisioner.mavenCentral()); StepHarness.forStep(step) .testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormattedAOSP.test") .testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormattedAOSP.test") @@ -85,7 +101,7 @@ void behaviorWithReflowLongStrings() throws Exception { @Test void behaviorWithCustomGroupArtifact() throws Exception { - FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.2", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false); + FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.10.0", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false); StepHarness.forStep(step) .testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test") .testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test") @@ -96,7 +112,7 @@ void behaviorWithCustomGroupArtifact() throws Exception { @Test void equality() throws Exception { new SerializableEqualityTester() { - String version = "1.2"; + String version = "1.10.0"; String style = ""; boolean reflowLongStrings = false; @@ -105,7 +121,7 @@ protected void setupTest(API api) { // same version == same api.areDifferentThan(); // change the version, and it's different - version = "1.1"; + version = "1.11.0"; api.areDifferentThan(); // change the style, and it's different style = "AOSP"; @@ -147,42 +163,4 @@ protected FormatterStep create() { }.testEquals(); } - @Test - void fixWindowsBugForGfj1Point1() { - fixWindowsBugTestcase(""); - fixWindowsBugTestcase( - "", - "import somepackage;", - ""); - fixWindowsBugTestcase( - "import somepackage;", - "", - "public class SomeClass {}"); - fixWindowsBugTestcase( - "/** Some license */", - "import somepackage;", - "", - "public class SomeClass {}"); - fixWindowsBugTestcase( - "package thispackage;", - "", - "import somepackage;", - "", - "public class SomeClass {}"); - fixWindowsBugTestcase( - "/*", - " * A License.", - " */", - "", - "package thispackage;", - "", - "import somepackage;", - "", - "public class SomeClass {}"); - } - - private void fixWindowsBugTestcase(String... lines) { - String input = StringPrinter.buildStringFromLines(lines); - Assertions.assertEquals(input, GoogleJavaFormatStep.fixWindowsBug(input, "1.1")); - } }