diff --git a/lib/build.gradle b/lib/build.gradle index bfa54aaa13..f6e0446f73 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -108,8 +108,8 @@ dependencies { gsonCompileOnly 'com.google.code.gson:gson:2.10.1' - cleanthatCompileOnly 'io.github.solven-eu.cleanthat:java:2.2' - compatCleanthat2Dot1CompileAndTestOnly 'io.github.solven-eu.cleanthat:java:2.2' + cleanthatCompileOnly 'io.github.solven-eu.cleanthat:java:2.6' + compatCleanthat2Dot1CompileAndTestOnly 'io.github.solven-eu.cleanthat:java:2.6' } // we'll hold the core lib to a high standard diff --git a/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java b/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java index c94fd3c7c4..d7148f8892 100644 --- a/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java +++ b/lib/src/cleanthat/java/com/diffplug/spotless/glue/java/JavaCleanthatRefactorerFunc.java @@ -42,15 +42,17 @@ public class JavaCleanthatRefactorerFunc implements FormatterFunc { private String jdkVersion; private List included; private List excluded; + private boolean includeDraft; - public JavaCleanthatRefactorerFunc(String jdkVersion, List included, List excluded) { + public JavaCleanthatRefactorerFunc(String jdkVersion, List included, List excluded, boolean includeDraft) { this.jdkVersion = jdkVersion == null ? IJdkVersionConstants.JDK_8 : jdkVersion; this.included = included == null ? Collections.emptyList() : included; this.excluded = excluded == null ? Collections.emptyList() : excluded; + this.includeDraft = includeDraft; } public JavaCleanthatRefactorerFunc() { - this(IJdkVersionConstants.JDK_8, Arrays.asList(JavaRefactorerProperties.WILDCARD), Arrays.asList()); + this(IJdkVersionConstants.JDK_8, Arrays.asList("SafeAndConsensual"), Arrays.asList(), false); } @Override @@ -79,9 +81,11 @@ private String doApply(String input) throws InterruptedException, IOException { refactorerProperties.setIncluded(included); refactorerProperties.setExcluded(excluded); + refactorerProperties.setIncludeDraft(includeDraft); + JavaRefactorer refactorer = new JavaRefactorer(engineProperties, refactorerProperties); - LOGGER.debug("Processing sourceJdk={} included={} excluded={}", jdkVersion, included, excluded); + LOGGER.debug("Processing sourceJdk={} included={} excluded={}", jdkVersion, included, excluded, includeDraft); LOGGER.debug("Available mutators: {}", JavaRefactorer.getAllIncluded()); // Spotless calls steps always with LF eol. diff --git a/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java b/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java index 2ef68f4f85..c1e5ae1fa4 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/CleanthatJavaStep.java @@ -40,7 +40,7 @@ public final class CleanthatJavaStep { private static final String MAVEN_COORDINATE = "io.github.solven-eu.cleanthat:java"; // CleanThat changelog is available at https://github.com/solven-eu/cleanthat/blob/master/CHANGES.MD - private static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME).add(11, "2.2"); + private static final Jvm.Support JVM_SUPPORT = Jvm. support(NAME).add(11, "2.6"); // prevent direct instantiation private CleanthatJavaStep() {} @@ -52,7 +52,7 @@ public static FormatterStep create(Provisioner provisioner) { /** Creates a step which apply default CleanThat mutators. */ public static FormatterStep create(String version, Provisioner provisioner) { - return create(MAVEN_COORDINATE, version, defaultSourceJdk(), defaultExcludedMutators(), defaultMutators(), provisioner); + return create(MAVEN_COORDINATE, version, defaultSourceJdk(), defaultMutators(), defaultExcludedMutators(), defaultIncludeDraft(), provisioner); } public static String defaultSourceJdk() { @@ -62,16 +62,21 @@ public static String defaultSourceJdk() { return "1.7"; } - public static List defaultExcludedMutators() { - return List.of(); - } - /** - * By default, we include all available rules + * By default, we include only safe and consensual mutators * @return */ public static List defaultMutators() { - return List.of("eu.solven.cleanthat.engine.java.refactorer.mutators.composite.SafeAndConsensualMutators"); + // see ICleanthatStepParametersProperties.SAFE_AND_CONSENSUAL + return List.of("SafeAndConsensual"); + } + + public static List defaultExcludedMutators() { + return List.of(); + } + + public static boolean defaultIncludeDraft() { + return false; } /** Creates a step which apply selected CleanThat mutators. */ @@ -80,6 +85,7 @@ public static FormatterStep create(String groupArtifact, String sourceJdkVersion, List excluded, List included, + boolean includeDraft, Provisioner provisioner) { Objects.requireNonNull(groupArtifact, "groupArtifact"); if (groupArtifact.chars().filter(ch -> ch == ':').count() != 1) { @@ -88,7 +94,7 @@ public static FormatterStep create(String groupArtifact, Objects.requireNonNull(version, "version"); Objects.requireNonNull(provisioner, "provisioner"); return FormatterStep.createLazy(NAME, - () -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, excluded, included, provisioner), + () -> new JavaRefactorerState(NAME, groupArtifact, version, sourceJdkVersion, excluded, included, includeDraft, provisioner), JavaRefactorerState::createFormat); } @@ -111,9 +117,10 @@ static final class JavaRefactorerState implements Serializable { final String sourceJdkVersion; final List included; final List excluded; + final boolean includeDraft; JavaRefactorerState(String stepName, String version, Provisioner provisioner) throws IOException { - this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultExcludedMutators(), defaultMutators(), provisioner); + this(stepName, MAVEN_COORDINATE, version, defaultSourceJdk(), defaultExcludedMutators(), defaultMutators(), defaultIncludeDraft(), provisioner); } JavaRefactorerState(String stepName, @@ -122,8 +129,12 @@ static final class JavaRefactorerState implements Serializable { String sourceJdkVersion, List included, List excluded, + boolean includeDraft, Provisioner provisioner) throws IOException { - JVM_SUPPORT.assertFormatterSupported(version); + // https://github.com/diffplug/spotless/issues/1583 + if (!version.endsWith("-SNAPSHOT")) { + JVM_SUPPORT.assertFormatterSupported(version); + } ModuleHelper.doOpenInternalPackagesIfRequired(); this.jarState = JarState.from(groupArtifact + ":" + version, provisioner); this.stepName = stepName; @@ -132,6 +143,7 @@ static final class JavaRefactorerState implements Serializable { this.sourceJdkVersion = sourceJdkVersion; this.included = included; this.excluded = excluded; + this.includeDraft = includeDraft; } @SuppressWarnings("PMD.UseProperClassLoader") @@ -142,16 +154,24 @@ FormatterFunc createFormat() { Method formatterMethod; try { Class formatterClazz = classLoader.loadClass("com.diffplug.spotless.glue.java.JavaCleanthatRefactorerFunc"); - Constructor formatterConstructor = formatterClazz.getConstructor(String.class, List.class, List.class); + Constructor formatterConstructor = formatterClazz.getConstructor(String.class, List.class, List.class, boolean.class); - formatter = formatterConstructor.newInstance(sourceJdkVersion, included, excluded); + formatter = formatterConstructor.newInstance(sourceJdkVersion, included, excluded, includeDraft); formatterMethod = formatterClazz.getMethod("apply", String.class); } catch (ReflectiveOperationException e) { throw new IllegalStateException("Issue executing the formatter", e); } - return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> { - return (String) formatterMethod.invoke(formatter, input); - }); + + // https://github.com/diffplug/spotless/issues/1583 + if (!version.endsWith("-SNAPSHOT")) { + return JVM_SUPPORT.suggestLaterVersionOnError(version, input -> { + return (String) formatterMethod.invoke(formatter, input); + }); + } else { + return input -> { + return (String) formatterMethod.invoke(formatter, input); + }; + } } } diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index afba5abdc7..0b2185ba61 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -3,6 +3,10 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`). ## [Unreleased] +### Added +* Add `includeDraft` option, to include draft mutators from composite mutators ([#1574](https://github.com/diffplug/spotless/pull/1574)) +### Changes +* Bump default `cleanthat` version to latest `2.2` -> `2.6` ([#1574](https://github.com/diffplug/spotless/pull/1574)) * Bump default `cleanthat` version to latest `2.1` -> `2.2` ([#1569](https://github.com/diffplug/spotless/pull/1569)) ## [6.15.0] - 2023-02-10 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 7ab94ba7e4..f351dd6188 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 @@ -288,6 +288,8 @@ public class CleanthatJavaConfig { private List excludedMutators = new ArrayList<>(CleanthatJavaStep.defaultExcludedMutators()); + private boolean includeDraft = CleanthatJavaStep.defaultIncludeDraft(); + CleanthatJavaConfig() { addStep(createStep()); } @@ -341,11 +343,17 @@ public CleanthatJavaConfig excludeMutator(String mutator) { return this; } + public CleanthatJavaConfig includeDraft(boolean includeDraft) { + this.includeDraft = includeDraft; + replaceStep(createStep()); + return this; + } + private FormatterStep createStep() { return CleanthatJavaStep.create( groupArtifact, version, - sourceJdk, mutators, excludedMutators, provisioner()); + sourceJdk, mutators, excludedMutators, includeDraft, provisioner()); } } diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 8d4c67a9b6..4912e4ff52 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,7 +3,10 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +* Add `includeDraft` option, to include draft mutators from composite mutators ([#XXX](https://github.com/diffplug/spotless/pull/XXX)) ### Changes +* Bump default `cleanthat` version to latest `2.2` -> `2.6` ([#1574](https://github.com/diffplug/spotless/pull/1574)) * Bump default `cleanthat` version to latest `2.1` -> `2.2` ([#1569](https://github.com/diffplug/spotless/pull/1569)) ## [2.33.0] - 2023-02-10 diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/CleanthatJava.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/CleanthatJava.java index d7dd1f2530..4133409919 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/CleanthatJava.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/CleanthatJava.java @@ -41,11 +41,14 @@ public class CleanthatJava implements FormatterStepFactory { @Parameter private List excludedMutators = CleanthatJavaStep.defaultExcludedMutators(); + @Parameter + private boolean includeDraft = CleanthatJavaStep.defaultIncludeDraft(); + @Override public FormatterStep newFormatterStep(FormatterStepConfig config) { String groupArtifact = this.groupArtifact != null ? this.groupArtifact : CleanthatJavaStep.defaultGroupArtifact(); String version = this.version != null ? this.version : CleanthatJavaStep.defaultVersion(); - return CleanthatJavaStep.create(groupArtifact, version, sourceJdk, mutators, excludedMutators, config.getProvisioner()); + return CleanthatJavaStep.create(groupArtifact, version, sourceJdk, mutators, excludedMutators, includeDraft, config.getProvisioner()); } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/CleanthatJavaRefactorerTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/CleanthatJavaRefactorerTest.java index a32ac337e4..379397f55b 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/CleanthatJavaRefactorerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/CleanthatJavaRefactorerTest.java @@ -25,6 +25,17 @@ class CleanthatJavaRefactorerTest extends MavenIntegrationHarness { private static final Logger LOGGER = LoggerFactory.getLogger(CleanthatJavaRefactorerTest.class); + @Test + void testEnableDraft() throws Exception { + writePomWithJavaSteps( + "", + " 11", + " true", + ""); + + runTest("MultipleMutators.dirty.java", "MultipleMutators.clean.onlyOptionalIsPresent.java"); + } + @Test void testLiteralsFirstInComparisons() throws Exception { writePomWithJavaSteps( diff --git a/testlib/src/main/resources/java/cleanthat/MultipleMutators.clean.onlyOptionalIsPresent.java b/testlib/src/main/resources/java/cleanthat/MultipleMutators.clean.onlyOptionalIsPresent.java new file mode 100644 index 0000000000..0829602dc1 --- /dev/null +++ b/testlib/src/main/resources/java/cleanthat/MultipleMutators.clean.onlyOptionalIsPresent.java @@ -0,0 +1,14 @@ +package eu.solven.cleanthat.engine.java.refactorer.cases.do_not_format_me; + +import java.util.Optional; + +public class LiteralsFirstInComparisonsCases { + + public boolean isHardcoded(String input) { + return input.equals("hardcoded"); + } + + public boolean isPresent(Optional optional) { + return optional.isPresent(); + } +}