16
16
package com .diffplug .spotless .cli ;
17
17
18
18
import java .nio .charset .Charset ;
19
- import java .nio .file .Files ;
20
19
import java .nio .file .Path ;
21
20
import java .util .List ;
21
+ import java .util .function .BiConsumer ;
22
22
import java .util .stream .Collectors ;
23
23
24
24
import javax .annotation .Nonnull ;
25
25
26
26
import com .diffplug .spotless .Formatter ;
27
27
import com .diffplug .spotless .FormatterStep ;
28
28
import com .diffplug .spotless .LineEnding ;
29
+ import com .diffplug .spotless .LintState ;
29
30
import com .diffplug .spotless .ThrowingEx ;
30
31
import com .diffplug .spotless .cli .core .TargetResolver ;
31
32
import com .diffplug .spotless .cli .execution .SpotlessExecutionStrategy ;
@@ -70,41 +71,70 @@ public Integer executeSpotlessAction(@Nonnull List<FormatterStep> formatterSteps
70
71
.steps (formatterSteps )
71
72
.build ()) {
72
73
73
- boolean success = targetResolver .resolveTargets ()
74
+ ResultType resultType = targetResolver .resolveTargets () // TODO result
74
75
.parallel () // needed?
75
- .map (target -> this .executeFormatter (formatter , target ))
76
- .filter (result -> result .success && result .updated != null )
77
- .peek (this ::writeBack )
78
- .allMatch (result -> result .success );
76
+ .map (path -> ThrowingEx .get (() -> new Result (path , LintState .of (formatter , path .toFile ())))) // TODO handle suppressions, see SpotlessTaskImpl
77
+ .map (result -> this .handleResult (formatter , result ))
78
+ .reduce (ResultType .CLEAN , ResultType ::combineWith );
79
79
System .out .println ("Hello " + getClass ().getSimpleName () + ", abc! Files: " + new TargetResolver (targets ).resolveTargets ().collect (Collectors .toList ()));
80
- System .out .println ("success : " + success );
80
+ System .out .println ("result : " + resultType );
81
81
formatterSteps .forEach (step -> System .out .println ("Step: " + step ));
82
82
return 0 ;
83
83
}
84
84
}
85
85
86
- private Result executeFormatter (Formatter formatter , Path target ) {
87
- System .out .println ("Formatting file: " + target + " in Thread " + Thread .currentThread ().getName ());
88
- String targetContent = ThrowingEx .get (() -> Files .readString (target , Charset .defaultCharset ())); // TODO charset!
89
-
90
- String computed = formatter .compute (targetContent , target .toFile ());
91
- // computed is null if file already up to date
92
- return new Result (target , true , computed );
93
- }
94
-
95
- private void writeBack (Result result ) {
96
- if (result .updated != null ) {
97
- ThrowingEx .run (() -> Files .writeString (result .target , result .updated , Charset .defaultCharset ())); // TODO charset!
86
+ private ResultType handleResult (Formatter formatter , Result result ) {
87
+ if (result .lintState .isClean ()) {
88
+ System .out .println ("File is clean: " + result .target .toFile ().getName ());
89
+ return ResultType .CLEAN ;
90
+ }
91
+ if (result .lintState .getDirtyState ().didNotConverge ()) {
92
+ System .out .println ("File did not converge: " + result .target .toFile ().getName ());
93
+ return ResultType .DID_NOT_CONVERGE ;
94
+ }
95
+ this .spotlessMode .action .accept (formatter , result );
96
+ return ResultType .DIRTY ;
97
+
98
+ /*
99
+ if (lintState.getDirtyState().isClean()) {
100
+ // Remove previous output if it exists
101
+ Files.deleteIfExists(cleanFile.toPath());
102
+ } else if (lintState.getDirtyState().didNotConverge()) {
103
+ getLogger().warn("Skipping '{}' because it does not converge. Run {@code spotlessDiagnose} to understand why", relativePath);
104
+ } else {
105
+ Path parentDir = cleanFile.toPath().getParent();
106
+ if (parentDir == null) {
107
+ throw new IllegalStateException("Every file has a parent folder. But not: " + cleanFile);
108
+ }
109
+ Files.createDirectories(parentDir);
110
+ // Need to copy the original file to the tmp location just to remember the file attributes
111
+ Files.copy(input.toPath(), cleanFile.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
112
+
113
+ getLogger().info(String.format("Writing clean file: %s", cleanFile));
114
+ lintState.getDirtyState().writeCanonicalTo(cleanFile);
115
+ }
116
+ if (!lintState.isHasLints()) {
117
+ Files.deleteIfExists(lintFile.toPath());
118
+ } else {
119
+ LinkedHashMap<String, List<Lint>> lints = lintState.getLintsByStep(formatter);
120
+ SerializableMisc.toFile(lints, lintFile);
98
121
}
99
- // System.out.println("Writing back to file:" + result.target + " with content:\n" + result.updated);
122
+ */
100
123
}
101
124
125
+ // private void writeBack(Result result) {
126
+ // if (result.updated != null) {
127
+ // ThrowingEx.run(() -> Files.writeString(result.target, result.updated, Charset.defaultCharset())); // TODO charset!
128
+ // }
129
+ // System.out.println("Writing back to file:" + result.target + " with content:\n" + result.updated);
130
+ // }
131
+
102
132
public static void main (String ... args ) {
103
133
if (args .length == 0 ) {
104
134
// args = new String[]{"--version"};
105
135
// args = new String[]{"license-header", "--header-file", "CHANGES.md", "--delimiter-for", "java", "license-header", "--header", "abc"};
106
136
107
- args = new String []{"--target" , "src/poc/java/**/*.java" , "--encoding=UTF-8" , "license-header" , "--header" , "abc" , "--delimiter-for" , "java" , "license-header" , "--header-file" , "TestHeader.txt" };
137
+ args = new String []{"--mode=CHECK" , "-- target" , "src/poc/java/**/*.java" , "--encoding=UTF-8" , "license-header" , "--header" , "abc" , "--delimiter-for" , "java" , "license-header" , "--header-file" , "TestHeader.txt" };
108
138
// args = new String[]{"--version"};
109
139
}
110
140
int exitCode = new CommandLine (new SpotlessCLI ())
@@ -115,18 +145,46 @@ public static void main(String... args) {
115
145
}
116
146
117
147
private enum SpotlessMode {
118
- CHECK , APPLY
148
+ CHECK (((formatter , result ) -> {
149
+ if (result .lintState .isHasLints ()) {
150
+ result .lintState .asStringOneLine (result .target .toFile (), formatter );
151
+ } else {
152
+ System .out .println (String .format ("%s is violating formatting rules." , result .target ));
153
+ }
154
+ })), APPLY (((formatter , result ) -> ThrowingEx .run (() -> result .lintState .getDirtyState ().writeCanonicalTo (result .target .toFile ()))));
155
+
156
+ private final BiConsumer <Formatter , Result > action ;
157
+
158
+ SpotlessMode (BiConsumer <Formatter , Result > action ) {
159
+ this .action = action ;
160
+ }
161
+
162
+ }
163
+
164
+ private enum ResultType {
165
+ CLEAN , DIRTY , DID_NOT_CONVERGE ;
166
+
167
+ ResultType combineWith (ResultType other ) {
168
+ if (this == other ) {
169
+ return this ;
170
+ }
171
+ if (this == DID_NOT_CONVERGE || other == DID_NOT_CONVERGE ) {
172
+ return DID_NOT_CONVERGE ;
173
+ }
174
+ if (this == DIRTY || other == DIRTY ) {
175
+ return DIRTY ;
176
+ }
177
+ throw new IllegalStateException ("Unexpected combination of result types: " + this + " and " + other );
178
+ }
119
179
}
120
180
121
181
private static final class Result {
122
182
private final Path target ;
123
- private final boolean success ;
124
- private final String updated ;
183
+ private final LintState lintState ;
125
184
126
- public Result (Path target , boolean success , String updated ) {
185
+ public Result (Path target , LintState lintState ) {
127
186
this .target = target ;
128
- this .success = success ;
129
- this .updated = updated ;
187
+ this .lintState = lintState ;
130
188
}
131
189
}
132
190
}
0 commit comments