diff --git a/lib/src/main/java/com/diffplug/spotless/Formatter.java b/lib/src/main/java/com/diffplug/spotless/Formatter.java index 3470a3dc69..46793e24f6 100644 --- a/lib/src/main/java/com/diffplug/spotless/Formatter.java +++ b/lib/src/main/java/com/diffplug/spotless/Formatter.java @@ -39,13 +39,16 @@ public final class Formatter implements Serializable, AutoCloseable { private static final long serialVersionUID = 1L; + // The name is used for logging purpose. It does not convey any applicative purpose + private String name; private LineEnding.Policy lineEndingsPolicy; private Charset encoding; private Path rootDir; private List steps; private FormatExceptionPolicy exceptionPolicy; - private Formatter(LineEnding.Policy lineEndingsPolicy, Charset encoding, Path rootDirectory, List steps, FormatExceptionPolicy exceptionPolicy) { + private Formatter(String name, LineEnding.Policy lineEndingsPolicy, Charset encoding, Path rootDirectory, List steps, FormatExceptionPolicy exceptionPolicy) { + this.name = name; this.lineEndingsPolicy = Objects.requireNonNull(lineEndingsPolicy, "lineEndingsPolicy"); this.encoding = Objects.requireNonNull(encoding, "encoding"); this.rootDir = Objects.requireNonNull(rootDirectory, "rootDir"); @@ -55,6 +58,7 @@ private Formatter(LineEnding.Policy lineEndingsPolicy, Charset encoding, Path ro // override serialize output private void writeObject(ObjectOutputStream out) throws IOException { + out.writeObject(name); out.writeObject(lineEndingsPolicy); out.writeObject(encoding.name()); out.writeObject(rootDir.toString()); @@ -65,6 +69,7 @@ private void writeObject(ObjectOutputStream out) throws IOException { // override serialize input @SuppressWarnings("unchecked") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + name = (String) in.readObject(); lineEndingsPolicy = (LineEnding.Policy) in.readObject(); encoding = Charset.forName((String) in.readObject()); rootDir = Paths.get((String) in.readObject()); @@ -78,6 +83,10 @@ private void readObjectNoData() throws ObjectStreamException { throw new UnsupportedOperationException(); } + public String getName() { + return name; + } + public LineEnding.Policy getLineEndingsPolicy() { return lineEndingsPolicy; } @@ -103,6 +112,8 @@ public static Formatter.Builder builder() { } public static class Builder { + // optional parameters + private String name = "unnamed"; // required parameters private LineEnding.Policy lineEndingsPolicy; private Charset encoding; @@ -112,6 +123,11 @@ public static class Builder { private Builder() {} + public Builder name(String name) { + this.name = name; + return this; + } + public Builder lineEndingsPolicy(LineEnding.Policy lineEndingsPolicy) { this.lineEndingsPolicy = lineEndingsPolicy; return this; @@ -138,7 +154,7 @@ public Builder exceptionPolicy(FormatExceptionPolicy exceptionPolicy) { } public Formatter build() { - return new Formatter(lineEndingsPolicy, encoding, rootDir, steps, + return new Formatter(name, lineEndingsPolicy, encoding, rootDir, steps, exceptionPolicy == null ? FormatExceptionPolicy.failOnlyOnError() : exceptionPolicy); } } @@ -253,6 +269,7 @@ public String compute(String unix, File file) { public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + name.hashCode(); result = prime * result + encoding.hashCode(); result = prime * result + lineEndingsPolicy.hashCode(); result = prime * result + rootDir.hashCode(); @@ -273,7 +290,8 @@ public boolean equals(Object obj) { return false; } Formatter other = (Formatter) obj; - return encoding.equals(other.encoding) && + return name.equals(other.name) && + encoding.equals(other.encoding) && lineEndingsPolicy.equals(other.lineEndingsPolicy) && rootDir.equals(other.rootDir) && steps.equals(other.steps) && diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java index 6f2279b2e0..c23cea0845 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTask.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. @@ -184,6 +184,7 @@ String formatName() { Formatter buildFormatter() { return Formatter.builder() + .name(formatName()) .lineEndingsPolicy(lineEndingsPolicy.get()) .encoding(Charset.forName(encoding)) .rootDir(getProjectDir().get().getAsFile().toPath()) diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index ad79193ad8..c9e0f420a5 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,6 +3,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +* A synthesis log with the number of considered files is added after each formatter execution ([#1507](https://github.com/diffplug/spotless/pull/1507)) ## [2.31.0] - 2023-01-26 ### Added 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 d5fbe60370..b78e987d34 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-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. @@ -101,7 +101,9 @@ public final Formatter newFormatter(Supplier> filesToFormat, Form formatterSteps.add(pair.out()); } + String formatterName = this.getClass().getSimpleName(); return Formatter.builder() + .name(formatterName) .encoding(formatterEncoding) .lineEndingsPolicy(formatterLineEndingPolicy) .exceptionPolicy(new FormatExceptionPolicyStrict()) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/ImpactedFilesTracker.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ImpactedFilesTracker.java new file mode 100644 index 0000000000..60eb8af762 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ImpactedFilesTracker.java @@ -0,0 +1,56 @@ +/* + * 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.maven; + +/** + * Tracks the number of processed files, typically by a single Formatter for a whole repository + */ +class ImpactedFilesTracker { + protected int nbskippedAsCleanCache = 0; + protected int nbCheckedButAlreadyClean = 0; + protected int nbCleaned = 0; + + /** + * Some cache mechanism may indicate some content is clean, without having to execute the cleaning process + */ + public void skippedAsCleanCache() { + nbskippedAsCleanCache++; + } + + public int getSkippedAsCleanCache() { + return nbskippedAsCleanCache; + } + + public void checkedButAlreadyClean() { + nbCheckedButAlreadyClean++; + } + + public int getCheckedButAlreadyClean() { + return nbCheckedButAlreadyClean; + } + + public void cleaned() { + nbCleaned++; + } + + public int getCleaned() { + return nbCleaned; + } + + public int getTotal() { + return nbskippedAsCleanCache + nbCheckedButAlreadyClean + nbCleaned; + } +} 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 7a15d01b17..f7f23d6d75 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-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. @@ -33,8 +33,11 @@ public class SpotlessApplyMojo extends AbstractSpotlessMojo { @Override protected void process(Iterable files, Formatter formatter, UpToDateChecker upToDateChecker) throws MojoExecutionException { + ImpactedFilesTracker counter = new ImpactedFilesTracker(); + for (File file : files) { if (upToDateChecker.isUpToDate(file.toPath())) { + counter.skippedAsCleanCache(); if (getLog().isDebugEnabled()) { getLog().debug("Spotless will not format an up-to-date file: " + file); } @@ -44,8 +47,12 @@ protected void process(Iterable files, Formatter formatter, UpToDateChecke try { PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file); if (!dirtyState.isClean() && !dirtyState.didNotConverge()) { + getLog().info(String.format("Writing clean file: %s", file)); dirtyState.writeCanonicalTo(file); buildContext.refresh(file); + counter.cleaned(); + } else { + counter.checkedButAlreadyClean(); } } catch (IOException e) { throw new MojoExecutionException("Unable to format file " + file, e); @@ -53,5 +60,13 @@ protected void process(Iterable files, Formatter formatter, UpToDateChecke upToDateChecker.setUpToDate(file.toPath()); } + + // We print the number of considered files which is useful when ratchetFrom is setup + if (counter.getTotal() > 0) { + getLog().info(String.format("Spotless.%s is keeping %s files clean - %s were changed to be clean, %s were already clean, %s were skipped because caching determined they were already clean", + formatter.getName(), counter.getTotal(), counter.getCleaned(), counter.getCheckedButAlreadyClean(), counter.getSkippedAsCleanCache())); + } else { + getLog().warn(String.format("Spotless.%s has no target files. Examine your ``: https://github.com/diffplug/spotless/tree/main/plugin-maven#quickstart", formatter.getName())); + } } } diff --git a/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java b/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java index 98a709c59f..9a9eb4042b 100644 --- a/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java +++ b/testlib/src/main/java/com/diffplug/spotless/StepHarnessWithFile.java @@ -38,6 +38,7 @@ private StepHarnessWithFile(ResourceHarness harness, Formatter formatter) { /** Creates a harness for testing steps which do depend on the file. */ public static StepHarnessWithFile forStep(ResourceHarness harness, FormatterStep step) { return new StepHarnessWithFile(harness, Formatter.builder() + .name(step.getName()) .encoding(StandardCharsets.UTF_8) .lineEndingsPolicy(LineEnding.UNIX.createPolicy()) .steps(Collections.singletonList(step))