From 3ab7adb515327ac3b4d9ea34c65646c6ddc95e38 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 4 Jun 2020 21:47:20 -0700 Subject: [PATCH 01/11] Refactor all gradle-specific stuff out of GitRatchet. --- .../diffplug/gradle/spotless/GitRatchet.java | 26 +++++++++----- .../gradle/spotless/GradleGitRatchet.java | 35 +++++++++++++++++++ .../spotless/RegisterDependenciesTask.java | 6 ++-- .../gradle/spotless/SpotlessTaskBase.java | 6 ++-- 4 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java index b15daacf61..c04913b23c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java @@ -40,14 +40,20 @@ import org.eclipse.jgit.treewalk.filter.IndexDiffFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.util.FS; -import org.gradle.api.Project; import com.diffplug.common.base.Errors; import com.diffplug.common.collect.HashBasedTable; import com.diffplug.common.collect.Table; import com.diffplug.spotless.FileSignature; -class GitRatchet implements AutoCloseable { +/** + * How to use: + * - For best performance, you should have one instance of GitRatchet, shared by all projects. + * - Use {@link #rootTreeShaOf(Object, String)} to turn `origin/master` into the SHA of the tree object at that reference + * - Use {@link #isClean(Object, ObjectId, File)} to see if the given file is "git clean" relative to that tree + * - If you have up-to-date checking and want the best possible performance, use {@link #subtreeShaOf(Object, ObjectId)} to optimize up-to-date checks on a per-project basis. + */ +public abstract class GitRatchet implements AutoCloseable { /** * This is the highest-level method, which all the others serve. Given the sha * of a git tree (not a commit!), and the file in question, this method returns @@ -130,17 +136,17 @@ private static boolean worktreeIsCleanCheckout(TreeWalk treeWalk) { private Repository repositoryFor(Project project) throws IOException { Repository repo = gitRoots.get(project); if (repo == null) { - if (isGitRoot(project.getProjectDir())) { - repo = createRepo(project.getProjectDir()); + if (isGitRoot(getDir(project))) { + repo = createRepo(getDir(project)); } else { - Project parentProj = project.getParent(); + Project parentProj = getParent(project); if (parentProj == null) { - repo = traverseParentsUntil(project.getProjectDir().getParentFile(), null); + repo = traverseParentsUntil(getDir(project).getParentFile(), null); if (repo == null) { throw new IllegalArgumentException("Cannot find git repository in any parent directory"); } } else { - repo = traverseParentsUntil(project.getProjectDir().getParentFile(), parentProj.getProjectDir()); + repo = traverseParentsUntil(getDir(project).getParentFile(), getDir(parentProj)); if (repo == null) { repo = repositoryFor(parentProj); } @@ -151,6 +157,10 @@ private Repository repositoryFor(Project project) throws IOException { return repo; } + protected abstract File getDir(Project project); + + protected abstract @Nullable Project getParent(Project project); + private static @Nullable Repository traverseParentsUntil(File startWith, File file) throws IOException { do { if (isGitRoot(startWith)) { @@ -204,7 +214,7 @@ public synchronized ObjectId subtreeShaOf(Project project, ObjectId rootTreeSha) ObjectId subtreeSha = subtreeShaCache.get(project); if (subtreeSha == null) { Repository repo = repositoryFor(project); - File directory = project.getProjectDir(); + File directory = getDir(project); if (repo.getWorkTree().equals(directory)) { subtreeSha = rootTreeSha; } else { diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java new file mode 100644 index 0000000000..4972162816 --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java @@ -0,0 +1,35 @@ +/* + * Copyright 2020 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.gradle.spotless; + +import java.io.File; + +import javax.annotation.Nullable; + +import org.gradle.api.Project; + +/** Gradle implementation of GitRatchet. */ +class GradleGitRatchet extends GitRatchet { + @Override + protected File getDir(Project project) { + return project.getProjectDir(); + } + + @Override + protected @Nullable Project getParent(Project project) { + return project.getParent(); + } +} diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java index 4fd4c46c9a..c7f06f7805 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,10 +106,10 @@ public void trivialFunction() throws IOException { Files.write(Integer.toString(getSteps().size()), unitOutput, StandardCharsets.UTF_8); } - GitRatchet gitRatchet = new GitRatchet(); + GradleGitRatchet gitRatchet = new GradleGitRatchet(); @Internal - GitRatchet getGitRatchet() { + GradleGitRatchet getGitRatchet() { return gitRatchet; } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java index 4f768059c3..25cedac9e5 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java @@ -76,7 +76,7 @@ public void setLineEndingsPolicy(LineEnding.Policy lineEndingsPolicy) { /*** API which performs git up-to-date tasks. */ @Nullable - GitRatchet ratchet; + GradleGitRatchet ratchet; /** The sha of the tree at repository root, used for determining if an individual *file* is clean according to git. */ ObjectId rootTreeSha; /** @@ -86,14 +86,14 @@ public void setLineEndingsPolicy(LineEnding.Policy lineEndingsPolicy) { */ private ObjectId subtreeSha = ObjectId.zeroId(); - public void setupRatchet(GitRatchet gitRatchet, String ratchetFrom) { + public void setupRatchet(GradleGitRatchet gitRatchet, String ratchetFrom) { ratchet = gitRatchet; rootTreeSha = gitRatchet.rootTreeShaOf(getProject(), ratchetFrom); subtreeSha = gitRatchet.subtreeShaOf(getProject(), rootTreeSha); } @Internal - GitRatchet getRatchet() { + GradleGitRatchet getRatchet() { return ratchet; } From 52988c84984f269ec254550da800966c43a2ef22 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 4 Jun 2020 21:48:12 -0700 Subject: [PATCH 02/11] Move GitRatchet into lib-extra so it can be used by plugin-maven. --- .../src/main/java/com/diffplug/spotless/extra}/GitRatchet.java | 2 +- .../java/com/diffplug/gradle/spotless/GradleGitRatchet.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) rename {plugin-gradle/src/main/java/com/diffplug/gradle/spotless => lib-extra/src/main/java/com/diffplug/spotless/extra}/GitRatchet.java (99%) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java similarity index 99% rename from plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java rename to lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java index c04913b23c..df6211f4f6 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchet.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.diffplug.gradle.spotless; +package com.diffplug.spotless.extra; import java.io.File; import java.io.IOException; diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java index 4972162816..fb67991847 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java @@ -21,6 +21,8 @@ import org.gradle.api.Project; +import com.diffplug.spotless.extra.GitRatchet; + /** Gradle implementation of GitRatchet. */ class GradleGitRatchet extends GitRatchet { @Override From e882b6fd460e62518193fc952ce9db7d67d484b5 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 4 Jun 2020 21:59:00 -0700 Subject: [PATCH 03/11] Fix Spotbugs warning. --- .../src/main/java/com/diffplug/spotless/extra/GitRatchet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java index df6211f4f6..ca4b2406a4 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/GitRatchet.java @@ -200,7 +200,7 @@ public synchronized ObjectId rootTreeShaOf(Project project, String reference) { rootTreeShaCache.put(repo, reference, treeSha); } return treeSha; - } catch (Exception e) { + } catch (IOException e) { throw Errors.asRuntime(e); } } @@ -225,7 +225,7 @@ public synchronized ObjectId subtreeShaOf(Project project, ObjectId rootTreeSha) subtreeShaCache.put(project, subtreeSha); } return subtreeSha; - } catch (Exception e) { + } catch (IOException e) { throw Errors.asRuntime(e); } } From 464b841eeeded9f684c28fe1453e100c6781f4b6 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 22:07:25 -0700 Subject: [PATCH 04/11] Adapt GitRatchet for Maven. --- .../spotless/maven/AbstractSpotlessMojo.java | 33 +++++++--- .../spotless/maven/FormatterConfig.java | 12 +++- .../spotless/maven/FormatterFactory.java | 15 ++++- .../spotless/maven/MavenGitRatchet.java | 62 +++++++++++++++++++ .../spotless/maven/SpotlessApplyMojo.java | 5 +- .../spotless/maven/SpotlessCheckMojo.java | 4 +- 6 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java 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 ede8e58389..e12be9dd05 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,19 @@ import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; @@ -36,6 +43,7 @@ import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.RemoteRepository; +import com.diffplug.common.collect.Iterables; import com.diffplug.spotless.Formatter; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; @@ -76,6 +84,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(defaultValue = DEFAULT_LINE_ENDINGS) private LineEnding lineEndings; + @Parameter + private String ratchetFrom; + @Parameter private LicenseHeader licenseHeader; @@ -110,12 +121,11 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter(property = "spotlessFiles") private String filePatterns; - protected abstract void process(List files, Formatter formatter) throws MojoExecutionException; + protected abstract void process(Iterable files, Formatter formatter) throws MojoExecutionException; @Override public final void execute() throws MojoExecutionException { List formatterFactories = getFormatterFactories(); - for (FormatterFactory formatterFactory : formatterFactories) { execute(formatterFactory); } @@ -123,8 +133,17 @@ public final void execute() throws MojoExecutionException { private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { List files = collectFiles(formatterFactory); - try (Formatter formatter = formatterFactory.newFormatter(files, getFormatterConfig())) { - process(files, formatter); + FormatterConfig config = getFormatterConfig(); + @Nullable + String ratchetFrom = formatterFactory.ratchetFrom(config); + Iterable toFormat; + if (ratchetFrom == null) { + toFormat = files; + } else { + toFormat = Iterables.filter(files, MavenGitRatchet.instance().isGitDirty(baseDir, ratchetFrom)); + } + try (Formatter formatter = formatterFactory.newFormatter(files, config)) { + process(toFormat, formatter); } } @@ -172,7 +191,7 @@ private FormatterConfig getFormatterConfig() { Provisioner provisioner = MavenProvisioner.create(resolver); List formatterStepFactories = getFormatterStepFactories(); FileLocator fileLocator = getFileLocator(); - return new FormatterConfig(baseDir, encoding, lineEndings, provisioner, fileLocator, formatterStepFactories); + return new FormatterConfig(baseDir, encoding, lineEndings, ratchetFrom, provisioner, fileLocator, formatterStepFactories); } private FileLocator getFileLocator() { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index bc2e5812a4..af52d1fa87 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import java.io.File; import java.util.List; +import javax.annotation.Nullable; + import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; @@ -27,14 +29,16 @@ public class FormatterConfig { private final String encoding; private final LineEnding lineEndings; + private final @Nullable String ratchetFrom; private final Provisioner provisioner; private final FileLocator fileLocator; private final List globalStepFactories; - public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Provisioner provisioner, + public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, @Nullable String ratchetFrom, Provisioner provisioner, FileLocator fileLocator, List globalStepFactories) { this.encoding = encoding; this.lineEndings = lineEndings; + this.ratchetFrom = ratchetFrom; this.provisioner = provisioner; this.fileLocator = fileLocator; this.globalStepFactories = globalStepFactories; @@ -48,6 +52,10 @@ public LineEnding getLineEndings() { return lineEndings; } + public @Nullable String getRatchetFrom() { + return ratchetFrom; + } + public Provisioner getProvisioner() { return provisioner; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index d3ad7062ca..55cf468ba2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,8 @@ import java.util.Objects; import java.util.Set; +import javax.annotation.Nullable; + import org.apache.maven.plugins.annotations.Parameter; import com.diffplug.common.collect.Sets; @@ -41,6 +43,12 @@ public abstract class FormatterFactory { @Parameter private LineEnding lineEndings; + /** Sentinel to distinguish between "don't ratchet this format" and "use spotless parent format". */ + private static final String RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL = " not set at format level "; + + @Parameter(defaultValue = RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL) + private String ratchetFrom; + @Parameter private String[] includes; @@ -128,6 +136,11 @@ private LineEnding lineEndings(FormatterConfig config) { return lineEndings == null ? config.getLineEndings() : lineEndings; } + @Nullable + String ratchetFrom(FormatterConfig config) { + return ratchetFrom == RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL ? config.getRatchetFrom() : ratchetFrom; + } + private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { return new FormatterStepConfig(encoding, licenseHeaderDelimiter(), config.getProvisioner(), config.getFileLocator()); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java new file mode 100644 index 0000000000..75c18a9bdc --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java @@ -0,0 +1,62 @@ +/* + * Copyright 2020 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.maven; + +import java.io.File; +import java.io.IOException; +import java.util.function.Predicate; + +import org.eclipse.jgit.lib.ObjectId; + +import com.diffplug.common.base.Errors; +import com.diffplug.spotless.extra.GitRatchet; + +class MavenGitRatchet extends GitRatchet { + @Override + protected File getDir(File project) { + return project; + } + + @Override + protected File getParent(File project) { + return project.getParentFile(); + } + + private static MavenGitRatchet instance = new MavenGitRatchet(); + + static MavenGitRatchet instance() { + if (instance == null) { + synchronized (MavenGitRatchet.class) { + if (instance == null) { + instance = new MavenGitRatchet(); + } + } + } + return instance; + } + + /** A predicate which returns only the "git dirty" files. */ + Predicate isGitDirty(File baseDir, String ratchetFrom) { + ObjectId sha = rootTreeShaOf(baseDir, ratchetFrom); + return file -> { + try { + return !isClean(baseDir, sha, file); + } catch (IOException e) { + throw Errors.asRuntime(e); + } + }; + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java index 3d85c27ab2..893a70f3f4 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ import java.io.File; import java.io.IOException; -import java.util.List; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; @@ -35,7 +34,7 @@ public class SpotlessApplyMojo extends AbstractSpotlessMojo { private boolean skip; @Override - protected void process(List files, Formatter formatter) throws MojoExecutionException { + protected void process(Iterable files, Formatter formatter) throws MojoExecutionException { if (skip) { getLog().info("Spotless apply skipped"); return; diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java index 4457ed5bc6..6f555890ca 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DiffPlug + * Copyright 2016-2020 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 @@ public class SpotlessCheckMojo extends AbstractSpotlessMojo { private boolean skip; @Override - protected void process(List files, Formatter formatter) throws MojoExecutionException { + protected void process(Iterable files, Formatter formatter) throws MojoExecutionException { if (skip) { getLog().info("Spotless check skipped"); return; From 6811ec3dc2dbea8157b02167fe8947a2b114704e Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 22:29:44 -0700 Subject: [PATCH 05/11] Switch from @Nullable to Optional, because I can't get @Nullable to work with the build XD --- plugin-maven/build.gradle | 1 + .../spotless/maven/AbstractSpotlessMojo.java | 12 +++++------- .../com/diffplug/spotless/maven/FormatterConfig.java | 9 ++++----- .../diffplug/spotless/maven/FormatterFactory.java | 12 +++++++----- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/plugin-maven/build.gradle b/plugin-maven/build.gradle index a98948ff8b..62a945bd71 100644 --- a/plugin-maven/build.gradle +++ b/plugin-maven/build.gradle @@ -78,6 +78,7 @@ dependencies { implementation "com.diffplug.durian:durian-core:${VER_DURIAN}" implementation "com.diffplug.durian:durian-collect:${VER_DURIAN}" + implementation "org.eclipse.jgit:org.eclipse.jgit:${VER_JGIT}" testImplementation project(":testlib") testImplementation "junit:junit:${VER_JUNIT}" 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 e12be9dd05..03ab863e89 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 @@ -24,14 +24,13 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nullable; - import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; @@ -134,13 +133,12 @@ public final void execute() throws MojoExecutionException { private void execute(FormatterFactory formatterFactory) throws MojoExecutionException { List files = collectFiles(formatterFactory); FormatterConfig config = getFormatterConfig(); - @Nullable - String ratchetFrom = formatterFactory.ratchetFrom(config); + Optional ratchetFrom = formatterFactory.ratchetFrom(config); Iterable toFormat; - if (ratchetFrom == null) { + if (!ratchetFrom.isPresent()) { toFormat = files; } else { - toFormat = Iterables.filter(files, MavenGitRatchet.instance().isGitDirty(baseDir, ratchetFrom)); + toFormat = Iterables.filter(files, MavenGitRatchet.instance().isGitDirty(baseDir, ratchetFrom.get())); } try (Formatter formatter = formatterFactory.newFormatter(files, config)) { process(toFormat, formatter); @@ -191,7 +189,7 @@ private FormatterConfig getFormatterConfig() { Provisioner provisioner = MavenProvisioner.create(resolver); List formatterStepFactories = getFormatterStepFactories(); FileLocator fileLocator = getFileLocator(); - return new FormatterConfig(baseDir, encoding, lineEndings, ratchetFrom, provisioner, fileLocator, formatterStepFactories); + return new FormatterConfig(baseDir, encoding, lineEndings, Optional.ofNullable(ratchetFrom), provisioner, fileLocator, formatterStepFactories); } private FileLocator getFileLocator() { diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java index af52d1fa87..6127d93d58 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterConfig.java @@ -19,8 +19,7 @@ import java.io.File; import java.util.List; - -import javax.annotation.Nullable; +import java.util.Optional; import com.diffplug.spotless.LineEnding; import com.diffplug.spotless.Provisioner; @@ -29,12 +28,12 @@ public class FormatterConfig { private final String encoding; private final LineEnding lineEndings; - private final @Nullable String ratchetFrom; + private final Optional ratchetFrom; private final Provisioner provisioner; private final FileLocator fileLocator; private final List globalStepFactories; - public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, @Nullable String ratchetFrom, Provisioner provisioner, + public FormatterConfig(File baseDir, String encoding, LineEnding lineEndings, Optional ratchetFrom, Provisioner provisioner, FileLocator fileLocator, List globalStepFactories) { this.encoding = encoding; this.lineEndings = lineEndings; @@ -52,7 +51,7 @@ public LineEnding getLineEndings() { return lineEndings; } - public @Nullable String getRatchetFrom() { + public Optional getRatchetFrom() { return ratchetFrom; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java index 55cf468ba2..bbed6ad1a4 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterFactory.java @@ -23,10 +23,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; -import javax.annotation.Nullable; - import org.apache.maven.plugins.annotations.Parameter; import com.diffplug.common.collect.Sets; @@ -136,9 +135,12 @@ private LineEnding lineEndings(FormatterConfig config) { return lineEndings == null ? config.getLineEndings() : lineEndings; } - @Nullable - String ratchetFrom(FormatterConfig config) { - return ratchetFrom == RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL ? config.getRatchetFrom() : ratchetFrom; + Optional ratchetFrom(FormatterConfig config) { + if (ratchetFrom == RATCHETFROM_NOT_SET_AT_FORMAT_LEVEL) { + return config.getRatchetFrom(); + } else { + return Optional.ofNullable(ratchetFrom); + } } private FormatterStepConfig stepConfig(Charset encoding, FormatterConfig config) { From 89b4a270a98a9b3df9529500b6903c9836c87c52 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 22:30:15 -0700 Subject: [PATCH 06/11] Add test for `ratchetFrom`. --- .../spotless/maven/GitRatchetMavenTest.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/GitRatchetMavenTest.java diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/GitRatchetMavenTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/GitRatchetMavenTest.java new file mode 100644 index 0000000000..ae8cac7669 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/GitRatchetMavenTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2020 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.maven; + +import java.io.IOException; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.RefDatabase; +import org.junit.Test; + +public class GitRatchetMavenTest extends MavenIntegrationHarness { + private static final String TEST_PATH = "src/markdown/test.md"; + + private Git initRepo() throws IllegalStateException, GitAPIException, IOException { + Git git = Git.init().setDirectory(rootFolder()).call(); + RefDatabase refDB = git.getRepository().getRefDatabase(); + refDB.newUpdate(Constants.R_HEADS + "main", false).setNewObjectId(ObjectId.zeroId()); + refDB.newUpdate(Constants.HEAD, false).link(Constants.R_HEADS + "main"); + refDB.newUpdate(Constants.R_HEADS + Constants.MASTER, false).delete(); + return git; + } + + @Test + public void singleProjectExhaustive() throws Exception { + try (Git git = initRepo()) { + writePom( + "", + " ", + " baseline", + " ", + " src/markdown/*.md", + " ", + " ", + " Lowercase hello", + " HELLO", + " hello", + " ", + " ", + " Lowercase world", + " WORLD", + " world", + " ", + " ", + " Lowercase world", + " MOM", + " mom", + " ", + " ", + ""); + setFile(TEST_PATH).toContent("HELLO"); + git.add().addFilepattern(TEST_PATH).call(); + git.commit().setMessage("Initial state").call(); + // tag this initial state as the baseline for spotless to ratchet from + git.tag().setName("baseline").call(); + + // so at this point we have test.md, and it would normally be dirty, + // but because it is unchanged, spotless says it is clean + assertClean(); + + // but if we change it so that it is not clean, spotless will now say it is dirty + setFile(TEST_PATH).toContent("HELLO WORLD"); + assertDirty(); + mavenRunner().withArguments("spotless:apply").runNoError(); + assertFile(TEST_PATH).hasContent("hello world"); + + // but if we make it unchanged again, it goes back to being clean + setFile(TEST_PATH).toContent("HELLO"); + assertClean(); + + // and if we make the index dirty + setFile(TEST_PATH).toContent("HELLO WORLD"); + git.add().addFilepattern(TEST_PATH).call(); + { + // and the content dirty in the same way, then it's dirty + assertDirty(); + // if we make the content something else dirty, then it's dirty + setFile(TEST_PATH).toContent("HELLO MOM"); + assertDirty(); + // if we make the content unchanged, even though index it and index are dirty, then it's clean + setFile(TEST_PATH).toContent("HELLO"); + assertClean(); + // if we delete the file, but it's still in the index, then it's clean + setFile(TEST_PATH).deleted(); + assertClean(); + } + // if we remove the file from the index + git.rm().addFilepattern(TEST_PATH).setCached(true).call(); + { + // and it's gone in real life too, then it's clean + assertClean(); + // if the content is there and unchanged, then it's clean + setFile(TEST_PATH).toContent("HELLO"); + assertClean(); + // if the content is dirty, then it's dirty + setFile(TEST_PATH).toContent("HELLO WORLD"); + assertDirty(); + } + + // new files always get checked + setFile("new.md").toContent("HELLO"); + { + assertDirty(); + // even if they are added + git.add().addFilepattern("new.md").call(); + assertDirty(); + } + } + } + + private void assertClean() throws Exception { + mavenRunner().withArguments("spotless:check").runNoError(); + } + + private void assertDirty() throws Exception { + mavenRunner().withArguments("spotless:check").runHasError(); + } +} From f3fc82c453800df80f6689a63f080ca8dffebaeb Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 22:43:04 -0700 Subject: [PATCH 07/11] Rename GitRatchet to GitRatchet, which is clearer. --- .../{GradleGitRatchet.java => GitRatchetGradle.java} | 2 +- .../gradle/spotless/RegisterDependenciesTask.java | 4 ++-- .../com/diffplug/gradle/spotless/SpotlessTaskBase.java | 6 +++--- ...{RatchetFromTest.java => GitRatchetGradleTest.java} | 2 +- .../diffplug/spotless/maven/AbstractSpotlessMojo.java | 2 +- .../{MavenGitRatchet.java => GitRatchetMaven.java} | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) rename plugin-gradle/src/main/java/com/diffplug/gradle/spotless/{GradleGitRatchet.java => GitRatchetGradle.java} (95%) rename plugin-gradle/src/test/java/com/diffplug/gradle/spotless/{RatchetFromTest.java => GitRatchetGradleTest.java} (99%) rename plugin-maven/src/main/java/com/diffplug/spotless/maven/{MavenGitRatchet.java => GitRatchetMaven.java} (86%) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java similarity index 95% rename from plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java rename to plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java index fb67991847..0fd6b6572e 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleGitRatchet.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java @@ -24,7 +24,7 @@ import com.diffplug.spotless.extra.GitRatchet; /** Gradle implementation of GitRatchet. */ -class GradleGitRatchet extends GitRatchet { +class GitRatchetGradle extends GitRatchet { @Override protected File getDir(Project project) { return project.getProjectDir(); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java index c7f06f7805..b770e66627 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/RegisterDependenciesTask.java @@ -106,10 +106,10 @@ public void trivialFunction() throws IOException { Files.write(Integer.toString(getSteps().size()), unitOutput, StandardCharsets.UTF_8); } - GradleGitRatchet gitRatchet = new GradleGitRatchet(); + GitRatchetGradle gitRatchet = new GitRatchetGradle(); @Internal - GradleGitRatchet getGitRatchet() { + GitRatchetGradle getGitRatchet() { return gitRatchet; } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java index 25cedac9e5..2435f46d78 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskBase.java @@ -76,7 +76,7 @@ public void setLineEndingsPolicy(LineEnding.Policy lineEndingsPolicy) { /*** API which performs git up-to-date tasks. */ @Nullable - GradleGitRatchet ratchet; + GitRatchetGradle ratchet; /** The sha of the tree at repository root, used for determining if an individual *file* is clean according to git. */ ObjectId rootTreeSha; /** @@ -86,14 +86,14 @@ public void setLineEndingsPolicy(LineEnding.Policy lineEndingsPolicy) { */ private ObjectId subtreeSha = ObjectId.zeroId(); - public void setupRatchet(GradleGitRatchet gitRatchet, String ratchetFrom) { + public void setupRatchet(GitRatchetGradle gitRatchet, String ratchetFrom) { ratchet = gitRatchet; rootTreeSha = gitRatchet.rootTreeShaOf(getProject(), ratchetFrom); subtreeSha = gitRatchet.subtreeShaOf(getProject(), rootTreeSha); } @Internal - GradleGitRatchet getRatchet() { + GitRatchetGradle getRatchet() { return ratchet; } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RatchetFromTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GitRatchetGradleTest.java similarity index 99% rename from plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RatchetFromTest.java rename to plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GitRatchetGradleTest.java index 387df29dbe..010f8d2112 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RatchetFromTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GitRatchetGradleTest.java @@ -34,7 +34,7 @@ import org.gradle.testkit.runner.TaskOutcome; import org.junit.Test; -public class RatchetFromTest extends GradleIntegrationHarness { +public class GitRatchetGradleTest extends GradleIntegrationHarness { private static final String TEST_PATH = "src/markdown/test.md"; private Git initRepo() throws IllegalStateException, GitAPIException, IOException { 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 03ab863e89..d3f410a754 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 @@ -138,7 +138,7 @@ private void execute(FormatterFactory formatterFactory) throws MojoExecutionExce if (!ratchetFrom.isPresent()) { toFormat = files; } else { - toFormat = Iterables.filter(files, MavenGitRatchet.instance().isGitDirty(baseDir, ratchetFrom.get())); + toFormat = Iterables.filter(files, GitRatchetMaven.instance().isGitDirty(baseDir, ratchetFrom.get())); } try (Formatter formatter = formatterFactory.newFormatter(files, config)) { process(toFormat, formatter); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java similarity index 86% rename from plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java rename to plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java index 75c18a9bdc..30cdd66361 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenGitRatchet.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java @@ -24,7 +24,7 @@ import com.diffplug.common.base.Errors; import com.diffplug.spotless.extra.GitRatchet; -class MavenGitRatchet extends GitRatchet { +class GitRatchetMaven extends GitRatchet { @Override protected File getDir(File project) { return project; @@ -35,13 +35,13 @@ protected File getParent(File project) { return project.getParentFile(); } - private static MavenGitRatchet instance = new MavenGitRatchet(); + private static GitRatchetMaven instance = new GitRatchetMaven(); - static MavenGitRatchet instance() { + static GitRatchetMaven instance() { if (instance == null) { - synchronized (MavenGitRatchet.class) { + synchronized (GitRatchetMaven.class) { if (instance == null) { - instance = new MavenGitRatchet(); + instance = new GitRatchetMaven(); } } } From 6be4e303243dc379632d37b2707e9ba1695fcdf8 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 23:31:03 -0700 Subject: [PATCH 08/11] Fix spotbugs warning. --- .../main/java/com/diffplug/spotless/maven/GitRatchetMaven.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java index 30cdd66361..0f841c2901 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java @@ -35,7 +35,7 @@ protected File getParent(File project) { return project.getParentFile(); } - private static GitRatchetMaven instance = new GitRatchetMaven(); + private static volatile GitRatchetMaven instance = new GitRatchetMaven(); static GitRatchetMaven instance() { if (instance == null) { From 44c4fd04aa5ec2d7de8e2e6e5f7a03ccfb944083 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sat, 27 Jun 2020 23:05:34 -0700 Subject: [PATCH 09/11] Add ratchet docs to the readme. --- plugin-maven/README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 66c2155209..bcba6f6e3b 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -594,7 +594,25 @@ By default, `spotless:check` is bound to the `verify` phase. You might want to - If you don't like what spotless did, `git reset --hard` - If you'd like to remove the "checkpoint" commit, `git reset --soft head~1` will make the checkpoint commit "disappear" from history, but keeps the changes in your working directory. - + + +## How can I enforce formatting gradually? + +If your project is not currently enforcing formatting, then it can be a noisy transition. Having a giant commit where every single file gets changed makes the history harder to read. To address this, you can use the `ratchet` feature: + +```xml + + origin/main + + +``` + +In this mode, Spotless will apply only to files which have changed since `origin/main`. You can ratchet from [any point you want](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), even `HEAD`. You can also set `ratchetFrom` per-format if you prefer (e.g. `...`). + +However, we strongly recommend that you use a non-local branch, such as a tag or `origin/main`. The problem with `HEAD` or any local branch is that as soon as you commit a file, that is now the canonical formatting, even if it was formatted incorrectly. By instead specifying `origin/main` or a tag, your CI server will fail unless every changed file is at least as good or better than it was before the change. + +This is especially helpful for injecting accurate copyright dates using the [license step](#license-header). + ## Can I apply Spotless to specific files? @@ -606,6 +624,8 @@ cmd> mvn spotless:apply -DspotlessFiles=my/file/pattern.java,more/generic/.*-pat The patterns are matched using `String#matches(String)` against the absolute file path. + + ## Example configurations (from real-world projects) - [Apache Avro](https://github.com/apache/avro/blob/8026c8ffe4ef67ab419dba73910636bf2c1a691c/lang/java/pom.xml#L307-L334) From dba5e9fdacb8c08a69875b2d2e31365a58c90f11 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Sun, 28 Jun 2020 15:06:39 -0700 Subject: [PATCH 10/11] Better encapsulation, per feedback from @lutovich --- .../java/com/diffplug/gradle/spotless/GitRatchetGradle.java | 2 +- .../java/com/diffplug/spotless/maven/GitRatchetMaven.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java index 0fd6b6572e..bfa84258c1 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GitRatchetGradle.java @@ -24,7 +24,7 @@ import com.diffplug.spotless.extra.GitRatchet; /** Gradle implementation of GitRatchet. */ -class GitRatchetGradle extends GitRatchet { +final class GitRatchetGradle extends GitRatchet { @Override protected File getDir(Project project) { return project.getProjectDir(); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java index 0f841c2901..a759f05b06 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/GitRatchetMaven.java @@ -24,7 +24,9 @@ import com.diffplug.common.base.Errors; import com.diffplug.spotless.extra.GitRatchet; -class GitRatchetMaven extends GitRatchet { +final class GitRatchetMaven extends GitRatchet { + private GitRatchetMaven() {} + @Override protected File getDir(File project) { return project; From a5d1453010efb62e73e77374950d4cbe9afdc6dd Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Mon, 29 Jun 2020 11:00:27 -0700 Subject: [PATCH 11/11] Update changelog. --- plugin-maven/CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 6aaebb196a..8e999a4897 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -4,8 +4,9 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [Unreleased] ### Added -* `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config` or `configFile` with the option `parser` or `filepath` ([#620](https://github.com/diffplug/spotless/pull/620)). +* You can now ratchet a project's style by limiting Spotless only to files which have changed since a given [git reference](https://javadoc.io/static/org.eclipse.jgit/org.eclipse.jgit/5.6.1.202002131546-r/org/eclipse/jgit/lib/Repository.html#resolve-java.lang.String-), e.g. `ratchetFrom 'origin/main'`. ([#590](https://github.com/diffplug/spotless/pull/590)) * Huge speed improvement for multi-module projects thanks to improved cross-project classloader caching ([#571](https://github.com/diffplug/spotless/pull/571), fixes [#559](https://github.com/diffplug/spotless/issues/559)). +* `prettier` will now autodetect the parser (and formatter) to use based on the filename, unless you override this using `config` or `configFile` with the option `parser` or `filepath` ([#620](https://github.com/diffplug/spotless/pull/620)). ## [1.31.3] - 2020-06-17 ### Changed