diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 73eb026796..f65f5e61d4 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -7,6 +7,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147)) ### Fixed * `licenseHeader` default pattern for Java files is updated to `(package|import|public|class|module) `. ([#1614](https://github.com/diffplug/spotless/pull/1614)) +### Changes +* Enable incremental up-to-date checking by default. ([#1621](https://github.com/diffplug/spotless/pull/1621)) ## [2.34.0] - 2023-02-27 ### Added diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 426b00184e..4af6308b89 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -1262,7 +1262,7 @@ To define what lines to skip at the beginning of such files, fill the `skipLines ## Incremental up-to-date checking and formatting -**This feature is turned off by default.** +**This feature is enabled by default starting from version 2.35.0.** Execution of `spotless:check` and `spotless:apply` for large projects can take time. By default, Spotless Maven plugin needs to read and format each source file. diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index f6aab0eabb..2c0d6e35e6 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -187,7 +187,7 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { private String setLicenseHeaderYearsFromGitHistory; @Parameter - private UpToDateChecking upToDateChecking; + private UpToDateChecking upToDateChecking = UpToDateChecking.enabled(); protected abstract void process(Iterable files, Formatter formatter, UpToDateChecker upToDateChecker) throws MojoExecutionException; @@ -373,9 +373,9 @@ private UpToDateChecker createUpToDateChecker(Iterable formatters) { } final UpToDateChecker checker; if (upToDateChecking != null && upToDateChecking.isEnabled()) { - getLog().info("Up-to-date checking enabled"); checker = UpToDateChecker.forProject(project, indexFile, formatters, getLog()); } else { + getLog().info("Up-to-date checking disabled"); checker = UpToDateChecker.noop(project, indexFile, getLog()); } return UpToDateChecker.wrapWithBuildContext(checker, buildContext); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/PluginFingerprint.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/PluginFingerprint.java index 9efd6f2586..34a01e235a 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/PluginFingerprint.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/PluginFingerprint.java @@ -21,6 +21,7 @@ import java.util.Objects; import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginManagement; import org.apache.maven.project.MavenProject; import com.diffplug.spotless.Formatter; @@ -43,10 +44,7 @@ private PluginFingerprint(String value) { } static PluginFingerprint from(MavenProject project, Iterable formatters) { - Plugin spotlessPlugin = project.getPlugin(SPOTLESS_PLUGIN_KEY); - if (spotlessPlugin == null) { - throw new IllegalArgumentException("Spotless plugin absent from the project: " + project); - } + Plugin spotlessPlugin = findSpotlessPlugin(project); byte[] digest = digest(spotlessPlugin, formatters); String value = Base64.getEncoder().encodeToString(digest); return new PluginFingerprint(value); @@ -86,6 +84,24 @@ public String toString() { return "PluginFingerprint[" + value + "]"; } + private static Plugin findSpotlessPlugin(MavenProject project) { + // Try to find the plugin instance from XML element + Plugin plugin = project.getPlugin(SPOTLESS_PLUGIN_KEY); + if (plugin == null) { + // Try to find the plugin instance from XML element. Useful when + // the current module is a parent of a multimodule project + PluginManagement pluginManagement = project.getPluginManagement(); + if (pluginManagement != null) { + plugin = pluginManagement.getPluginsAsMap().get(SPOTLESS_PLUGIN_KEY); + } + } + + if (plugin == null) { + throw new IllegalArgumentException("Spotless plugin absent from the project: " + project); + } + return plugin; + } + private static byte[] digest(Plugin plugin, Iterable formatters) { try (ObjectDigestOutputStream out = ObjectDigestOutputStream.create()) { out.writeObject(plugin.getVersion()); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/UpToDateChecking.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/UpToDateChecking.java index d5eb6aa941..f044b847c9 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/UpToDateChecking.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/incremental/UpToDateChecking.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 DiffPlug + * Copyright 2021-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,4 +38,10 @@ public boolean isEnabled() { public Path getIndexFile() { return indexFile == null ? null : new File(indexFile).toPath(); } + + public static UpToDateChecking enabled() { + UpToDateChecking upToDateChecking = new UpToDateChecking(); + upToDateChecking.enabled = true; + return upToDateChecking; + } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java index 1c9521c402..a93b4ffdd0 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MultiModuleProjectTest.java @@ -32,31 +32,31 @@ class MultiModuleProjectTest extends MavenIntegrationHarness { @Test void testConfigurationDependency() throws Exception { /* - create a multi-module project with the following stucture: + create a multi-module project with the following structure: /junit-tmp-dir ├── config - │   ├── pom.xml - │   └── src/main/resources/configs - │   ├── eclipse-formatter.xml - │   └── scalafmt.conf + │ ├── pom.xml + │ └── src/main/resources/configs + │ ├── eclipse-formatter.xml + │ └── scalafmt.conf ├── mvnw ├── mvnw.cmd ├── one - │   ├── pom.xml - │   └── src - │   ├── main/java/test1.java - │   └── test/java/test2.java + │ ├── pom.xml + │ └── src + │ ├── main/java/test1.java + │ └── test/java/test2.java ├── two - │   ├── pom.xml - │   └── src - │   ├── main/java/test1.java - │   └── test/java/test2.java + │ ├── pom.xml + │ └── src + │ ├── main/java/test1.java + │ └── test/java/test2.java ├── three - │   ├── pom.xml - │   └── src - │   ├── main/scala/test1.scala - │   └── test/scala/test2.scala + │ ├── pom.xml + │ └── src + │ ├── main/scala/test1.scala + │ └── test/scala/test2.scala ├── pom.xml ├── .mvn ├── mvnw diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/PluginFingerprintTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/PluginFingerprintTest.java index c344580d37..ae61dec331 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/PluginFingerprintTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/PluginFingerprintTest.java @@ -23,9 +23,12 @@ import java.io.ByteArrayInputStream; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginManagement; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.ReaderFactory; @@ -106,7 +109,7 @@ void emptyFingerprint() { } @Test - void failsWhenProjectDoesNotContainSpotlessPlugin() { + void failsForProjectWithoutSpotlessPlugin() { MavenProject projectWithoutSpotless = new MavenProject(); assertThatThrownBy(() -> PluginFingerprint.from(projectWithoutSpotless, FORMATTERS)) @@ -114,6 +117,37 @@ void failsWhenProjectDoesNotContainSpotlessPlugin() { .hasMessageContaining("Spotless plugin absent from the project"); } + @Test + void buildsFingerprintForProjectWithSpotlessPluginInBuildPlugins() { + MavenProject project = new MavenProject(); + Plugin spotlessPlugin = new Plugin(); + spotlessPlugin.setGroupId("com.diffplug.spotless"); + spotlessPlugin.setArtifactId("spotless-maven-plugin"); + spotlessPlugin.setVersion("1.2.3"); + project.getBuild().addPlugin(spotlessPlugin); + + PluginFingerprint fingerprint = PluginFingerprint.from(project, Collections.emptyList()); + + assertThat(fingerprint).isNotNull(); + } + + @Test + void buildsFingerprintForProjectWithSpotlessPluginInPluginManagement() { + MavenProject project = new MavenProject(); + Plugin spotlessPlugin = new Plugin(); + spotlessPlugin.setGroupId("com.diffplug.spotless"); + spotlessPlugin.setArtifactId("spotless-maven-plugin"); + spotlessPlugin.setVersion("1.2.3"); + project.getBuild().addPlugin(spotlessPlugin); + PluginManagement pluginManagement = new PluginManagement(); + pluginManagement.addPlugin(spotlessPlugin); + project.getBuild().setPluginManagement(pluginManagement); + + PluginFingerprint fingerprint = PluginFingerprint.from(project, Collections.emptyList()); + + assertThat(fingerprint).isNotNull(); + } + private MavenProject mavenProject(String spotlessVersion) throws Exception { String xml = createPomXmlContent(spotlessVersion, new String[0], new String[0]); return new MavenProject(readPom(xml)); diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/UpToDateCheckingTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/UpToDateCheckingTest.java index 0a9fe8f2d4..cfc17594ca 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/UpToDateCheckingTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/incremental/UpToDateCheckingTest.java @@ -31,8 +31,10 @@ class UpToDateCheckingTest extends MavenIntegrationHarness { + private static final String DISABLED_MESSAGE = "Up-to-date checking disabled"; + @Test - void upToDateCheckingDisabledByDefault() throws Exception { + void upToDateCheckingEnabledByDefault() throws Exception { writePom( "", " ", @@ -41,75 +43,53 @@ void upToDateCheckingDisabledByDefault() throws Exception { List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).doesNotContain("Up-to-date checking enabled"); + assertThat(output).doesNotContain(DISABLED_MESSAGE); assertFormatted(files); } @Test - void enableUpToDateChecking() throws Exception { + void explicitlyEnableUpToDateChecking() throws Exception { writePomWithUpToDateCheckingEnabled(true); List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).contains("Up-to-date checking enabled"); + assertThat(output).doesNotContain(DISABLED_MESSAGE); assertFormatted(files); } @Test - void enableUpToDateCheckingWithPluginDependencies() throws Exception { - writePomWithPluginManagementAndDependency(); + void explicitlyDisableUpToDateChecking() throws Exception { + writePomWithUpToDateCheckingEnabled(false); List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).contains("Up-to-date checking enabled"); + assertThat(output).contains(DISABLED_MESSAGE); assertFormatted(files); } @Test - void enableUpToDateCheckingWithPluginDependenciesMaven3_6_3() throws Exception { + void enableUpToDateCheckingWithPluginDependencies() throws Exception { writePomWithPluginManagementAndDependency(); - setFile(".mvn/wrapper/maven-wrapper.properties").toContent("distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip\n"); - List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).contains("Up-to-date checking enabled"); + assertThat(output).doesNotContain(DISABLED_MESSAGE); assertFormatted(files); } - private void writePomWithPluginManagementAndDependency() throws IOException { - setFile("pom.xml").toContent(createPomXmlContent("/pom-test-management.xml.mustache", - null, - null, - new String[]{ - "", - " ", - "", - "", - " true", - ""}, - new String[]{ - "", - " ", - " javax.inject", - " javax.inject", - " 1", - " ", - ""}, - null)); - } - @Test - void disableUpToDateChecking() throws Exception { - writePomWithUpToDateCheckingEnabled(false); + void enableUpToDateCheckingWithPluginDependenciesMaven3_6_3() throws Exception { + writePomWithPluginManagementAndDependency(); + + setFile(".mvn/wrapper/maven-wrapper.properties").toContent("distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip\n"); List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).doesNotContain("Up-to-date checking enabled"); + assertThat(output).doesNotContain(DISABLED_MESSAGE); assertFormatted(files); } @@ -124,7 +104,7 @@ void enableUpToDateCheckingCustomIndexFile() throws Exception { List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).contains("Up-to-date checking enabled"); + assertThat(output).doesNotContain(DISABLED_MESSAGE); assertFormatted(files); assertThat(indexFile.getParent()).exists(); assertThat(indexFile).exists(); @@ -143,7 +123,7 @@ void disableUpToDateCheckingCustomIndexFile() throws Exception { List files = writeUnformattedFiles(1); String output = runSpotlessApply(); - assertThat(output).doesNotContain("Up-to-date checking enabled"); + assertThat(output).contains(DISABLED_MESSAGE); assertFormatted(files); assertThat(indexFile.getParent()).exists(); assertThat(indexFile).doesNotExist(); @@ -215,6 +195,25 @@ void spotlessCheckRecordsUnformattedFiles() throws Exception { assertSpotlessCheckSkipped(files, checkOutput3); } + private void writePomWithPluginManagementAndDependency() throws IOException { + setFile("pom.xml").toContent(createPomXmlContent("/pom-test-management.xml.mustache", + null, + null, + new String[]{ + "", + " ", + ""}, + new String[]{ + "", + " ", + " javax.inject", + " javax.inject", + " 1", + " ", + ""}, + null)); + } + private void writePomWithUpToDateCheckingEnabled(boolean enabled) throws IOException { writePom( "",