Skip to content

Commit ec85679

Browse files
authored
Homogeneize gradle and maven behavior around Formatter work tracking (#1615)
2 parents aa3ffef + 7e26167 commit ec85679

File tree

4 files changed

+78
-9
lines changed

4 files changed

+78
-9
lines changed

plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2022 DiffPlug
2+
* Copyright 2016-2023 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535
import org.gradle.work.FileChange;
3636
import org.gradle.work.InputChanges;
3737

38+
import com.diffplug.common.annotations.VisibleForTesting;
3839
import com.diffplug.common.base.StringPrinter;
3940
import com.diffplug.spotless.Formatter;
4041
import com.diffplug.spotless.PaddedCell;
@@ -92,28 +93,37 @@ public void performAction(InputChanges inputs) throws Exception {
9293
}
9394
}
9495

95-
private void processInputFile(@Nullable GitRatchet ratchet, Formatter formatter, File input) throws IOException {
96+
@VisibleForTesting
97+
void processInputFile(@Nullable GitRatchet ratchet, Formatter formatter, File input) throws IOException {
9698
File output = getOutputFile(input);
97-
getLogger().debug("Applying format to " + input + " and writing to " + output);
99+
getLogger().debug("Applying format to {} and writing to {}", input, output);
98100
PaddedCell.DirtyState dirtyState;
99101
if (ratchet != null && ratchet.isClean(getProjectDir().get().getAsFile(), getRootTreeSha(), input)) {
100102
dirtyState = PaddedCell.isClean();
101103
} else {
102-
dirtyState = PaddedCell.calculateDirtyState(formatter, input);
104+
try {
105+
dirtyState = PaddedCell.calculateDirtyState(formatter, input);
106+
} catch (IOException e) {
107+
throw new IOException("Issue processing file: " + input, e);
108+
} catch (RuntimeException e) {
109+
throw new IllegalArgumentException("Issue processing file: " + input, e);
110+
}
103111
}
104112
if (dirtyState.isClean()) {
105113
// Remove previous output if it exists
106114
Files.deleteIfExists(output.toPath());
107115
} else if (dirtyState.didNotConverge()) {
108-
getLogger().warn("Skipping '" + input + "' because it does not converge. Run {@code spotlessDiagnose} to understand why");
116+
getLogger().warn("Skipping '{}' because it does not converge. Run {@code spotlessDiagnose} to understand why", input);
109117
} else {
110118
Path parentDir = output.toPath().getParent();
111119
if (parentDir == null) {
112-
throw new IllegalStateException("Every file has a parent folder.");
120+
throw new IllegalStateException("Every file has a parent folder. But not: " + output);
113121
}
114122
Files.createDirectories(parentDir);
115123
// Need to copy the original file to the tmp location just to remember the file attributes
116124
Files.copy(input.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
125+
126+
getLogger().info(String.format("Writing clean file: %s", output));
117127
dirtyState.writeCanonicalTo(output);
118128
}
119129
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2023 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.gradle.spotless;
17+
18+
import java.io.File;
19+
import java.nio.file.Paths;
20+
21+
import org.assertj.core.api.Assertions;
22+
import org.gradle.api.file.DirectoryProperty;
23+
import org.gradle.api.logging.Logger;
24+
import org.junit.jupiter.api.Test;
25+
import org.mockito.Mockito;
26+
27+
import com.diffplug.spotless.Formatter;
28+
29+
public class SpotlessTaskImplTest {
30+
@Test
31+
public void testThrowsMessageContainsFilename() throws Exception {
32+
SpotlessTaskImpl task = Mockito.mock(SpotlessTaskImpl.class, Mockito.CALLS_REAL_METHODS);
33+
Mockito.when(task.getLogger()).thenReturn(Mockito.mock(Logger.class));
34+
35+
File projectDir = Paths.get("unitTests", "projectDir").toFile();
36+
DirectoryProperty projectDirProperty = Mockito.mock(DirectoryProperty.class, Mockito.RETURNS_DEEP_STUBS);
37+
Mockito.when(projectDirProperty.get().getAsFile()).thenReturn(projectDir);
38+
39+
Mockito.when(task.getProjectDir()).thenReturn(projectDirProperty);
40+
41+
File input = Paths.get("unitTests", "projectDir", "someInput").toFile();
42+
Formatter formatter = Mockito.mock(Formatter.class);
43+
44+
Assertions.assertThatThrownBy(() -> task.processInputFile(null, formatter, input)).hasMessageContaining(input.toString());
45+
}
46+
}

plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessApplyMojo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ protected void process(Iterable<File> files, Formatter formatter, UpToDateChecke
5454
} else {
5555
counter.checkedButAlreadyClean();
5656
}
57-
} catch (IOException e) {
57+
} catch (IOException | RuntimeException e) {
5858
throw new MojoExecutionException("Unable to format file " + file, e);
5959
}
6060

plugin-maven/src/main/java/com/diffplug/spotless/maven/SpotlessCheckMojo.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2021 DiffPlug
2+
* Copyright 2016-2023 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,9 +38,12 @@ public class SpotlessCheckMojo extends AbstractSpotlessMojo {
3838

3939
@Override
4040
protected void process(Iterable<File> files, Formatter formatter, UpToDateChecker upToDateChecker) throws MojoExecutionException {
41+
ImpactedFilesTracker counter = new ImpactedFilesTracker();
42+
4143
List<File> problemFiles = new ArrayList<>();
4244
for (File file : files) {
4345
if (upToDateChecker.isUpToDate(file.toPath())) {
46+
counter.skippedAsCleanCache();
4447
if (getLog().isDebugEnabled()) {
4548
getLog().debug("Spotless will not check an up-to-date file: " + file);
4649
}
@@ -51,14 +54,24 @@ protected void process(Iterable<File> files, Formatter formatter, UpToDateChecke
5154
PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file);
5255
if (!dirtyState.isClean() && !dirtyState.didNotConverge()) {
5356
problemFiles.add(file);
57+
counter.cleaned();
5458
} else {
59+
counter.checkedButAlreadyClean();
5560
upToDateChecker.setUpToDate(file.toPath());
5661
}
57-
} catch (IOException e) {
62+
} catch (IOException | RuntimeException e) {
5863
throw new MojoExecutionException("Unable to format file " + file, e);
5964
}
6065
}
6166

67+
// We print the number of considered files which is useful when ratchetFrom is setup
68+
if (counter.getTotal() > 0) {
69+
getLog().info(String.format("Spotless.%s is keeping %s files clean - %s needs changes to be clean, %s were already clean, %s were skipped because caching determined they were already clean",
70+
formatter.getName(), counter.getTotal(), counter.getCleaned(), counter.getCheckedButAlreadyClean(), counter.getSkippedAsCleanCache()));
71+
} else {
72+
getLog().debug(String.format("Spotless.%s has no target files. Examine your `<includes>`: https://github.com/diffplug/spotless/tree/main/plugin-maven#quickstart", formatter.getName()));
73+
}
74+
6275
if (!problemFiles.isEmpty()) {
6376
throw new MojoExecutionException(DiffMessageFormatter.builder()
6477
.runToFix("Run 'mvn spotless:apply' to fix these violations.")

0 commit comments

Comments
 (0)