Skip to content

Commit 30ef0d4

Browse files
committed
check minimum required formatter version
(we would need to implement specific glue code for older versions)
1 parent 8b24b22 commit 30ef0d4

File tree

2 files changed

+66
-27
lines changed

2 files changed

+66
-27
lines changed

lib/src/main/java/com/diffplug/spotless/Jvm.java

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ public static int version() {
6363
public static class Support<V> {
6464
private final String fmtName;
6565
private final Comparator<? super V> fmtVersionComparator;
66-
private final NavigableMap<Integer, V> jvm2fmtVersion;
67-
private final NavigableMap<V, Integer> fmt2jvmVersion;
66+
private final NavigableMap<Integer, V> jvm2fmtMaxVersion;
67+
private final NavigableMap<Integer, V> jvm2fmtMinVersion;
68+
private final NavigableMap<V, Integer> fmtMaxVersion2jvmVersion;
6869

6970
private Support(String fromatterName) {
7071
this(fromatterName, new SemanticVersionComparator<V>());
@@ -73,40 +74,60 @@ private Support(String fromatterName) {
7374
private Support(String formatterName, Comparator<? super V> formatterVersionComparator) {
7475
fmtName = formatterName;
7576
fmtVersionComparator = formatterVersionComparator;
76-
jvm2fmtVersion = new TreeMap<Integer, V>();
77-
fmt2jvmVersion = new TreeMap<V, Integer>(formatterVersionComparator);
77+
jvm2fmtMaxVersion = new TreeMap<>();
78+
jvm2fmtMinVersion = new TreeMap<>();
79+
fmtMaxVersion2jvmVersion = new TreeMap<>(formatterVersionComparator);
7880
}
7981

8082
/**
81-
* Add supported formatter version
83+
* Add maximum supported formatter version
8284
* @param minimumJvmVersion Minimum Java version required
8385
* @param maxFormatterVersion Maximum formatter version supported by the Java version
8486
* @return this
8587
*/
8688
public Support<V> add(int minimumJvmVersion, V maxFormatterVersion) {
8789
Objects.requireNonNull(maxFormatterVersion);
88-
if (null != jvm2fmtVersion.put(minimumJvmVersion, maxFormatterVersion)) {
90+
if (null != jvm2fmtMaxVersion.put(minimumJvmVersion, maxFormatterVersion)) {
8991
throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion));
9092
}
91-
if (null != fmt2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) {
93+
if (null != fmtMaxVersion2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) {
9294
throw new IllegalArgumentException(String.format("Added duplicate entry for formatter version %s.", maxFormatterVersion));
9395
}
96+
verifyVersionRangesDoNotIntersect(jvm2fmtMaxVersion, minimumJvmVersion, maxFormatterVersion);
97+
return this;
98+
}
99+
100+
public Support<V> addMin(int minimumJvmVersion, V minFormatterVersion) {
101+
Objects.requireNonNull(minFormatterVersion);
102+
if (null != jvm2fmtMinVersion.put(minimumJvmVersion, minFormatterVersion)) {
103+
throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion));
104+
}
105+
verifyVersionRangesDoNotIntersect(jvm2fmtMinVersion, minimumJvmVersion, minFormatterVersion);
106+
return this;
107+
}
108+
109+
private void verifyVersionRangesDoNotIntersect(NavigableMap<Integer, V> jvm2fmtVersion, int minimumJvmVersion, V formatterVersion) {
94110
Map.Entry<Integer, V> lower = jvm2fmtVersion.lowerEntry(minimumJvmVersion);
95-
if ((null != lower) && (fmtVersionComparator.compare(maxFormatterVersion, lower.getValue()) <= 0)) {
96-
throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, maxFormatterVersion, lower.getKey(), lower.getValue()));
111+
if ((null != lower) && (fmtVersionComparator.compare(formatterVersion, lower.getValue()) <= 0)) {
112+
throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, formatterVersion, lower.getKey(), lower.getValue()));
97113
}
98114
Map.Entry<Integer, V> higher = jvm2fmtVersion.higherEntry(minimumJvmVersion);
99-
if ((null != higher) && (fmtVersionComparator.compare(maxFormatterVersion, higher.getValue()) >= 0)) {
100-
throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, maxFormatterVersion, higher.getKey(), higher.getValue()));
115+
if ((null != higher) && (fmtVersionComparator.compare(formatterVersion, higher.getValue()) >= 0)) {
116+
throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, formatterVersion, higher.getKey(), higher.getValue()));
101117
}
102-
return this;
103118
}
104119

105120
/** @return Highest formatter version recommended for this JVM (null, if JVM not supported) */
106121
@Nullable
107122
public V getRecommendedFormatterVersion() {
108-
Integer configuredJvmVersionOrNull = jvm2fmtVersion.floorKey(Jvm.version());
109-
return (null == configuredJvmVersionOrNull) ? null : jvm2fmtVersion.get(configuredJvmVersionOrNull);
123+
Integer configuredJvmVersionOrNull = jvm2fmtMaxVersion.floorKey(Jvm.version());
124+
return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMaxVersion.get(configuredJvmVersionOrNull);
125+
}
126+
127+
@Nullable
128+
public V getMinimumRequiredFormatterVersion() {
129+
Integer configuredJvmVersionOrNull = jvm2fmtMinVersion.floorKey(Jvm.version());
130+
return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMinVersion.get(configuredJvmVersionOrNull);
110131
}
111132

112133
/**
@@ -123,10 +144,17 @@ public void assertFormatterSupported(V formatterVersion) {
123144
}
124145

125146
private String buildUnsupportedFormatterMessage(V fmtVersion) {
147+
// check if the jvm version is to low for the formatter version
126148
int requiredJvmVersion = getRequiredJvmVersion(fmtVersion);
127149
if (Jvm.version() < requiredJvmVersion) {
128150
return buildUpgradeJvmMessage(fmtVersion) + "Upgrade your JVM or try " + toString();
129151
}
152+
// check if the formatter version is too low for the jvm version
153+
V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
154+
if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
155+
return String.format("You are running Spotless on JVM %d, which requires %s of at least %s (you are using %s).%n", Jvm.version(), fmtName, minimumFormatterVersion, fmtVersion);
156+
}
157+
// otherwise all is well
130158
return "";
131159
}
132160

@@ -137,7 +165,7 @@ private String buildUpgradeJvmMessage(V fmtVersion) {
137165
if (null != recommendedFmtVersionOrNull) {
138166
builder.append(String.format(", which limits you to %s %s.%n", fmtName, recommendedFmtVersionOrNull));
139167
} else {
140-
Entry<V, Integer> nextFmtVersionOrNull = fmt2jvmVersion.ceilingEntry(fmtVersion);
168+
Entry<V, Integer> nextFmtVersionOrNull = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion);
141169
if (null != nextFmtVersionOrNull) {
142170
builder.append(String.format(". %s %s requires JVM %d+", fmtName, fmtVersion, nextFmtVersionOrNull.getValue()));
143171
}
@@ -147,12 +175,12 @@ private String buildUpgradeJvmMessage(V fmtVersion) {
147175
}
148176

149177
private int getRequiredJvmVersion(V fmtVersion) {
150-
Entry<V, Integer> entry = fmt2jvmVersion.ceilingEntry(fmtVersion);
178+
Entry<V, Integer> entry = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion);
151179
if (null == entry) {
152-
entry = fmt2jvmVersion.lastEntry();
180+
entry = fmtMaxVersion2jvmVersion.lastEntry();
153181
}
154182
if (null != entry) {
155-
V maxKnownFmtVersion = jvm2fmtVersion.get(entry.getValue());
183+
V maxKnownFmtVersion = jvm2fmtMaxVersion.get(entry.getValue());
156184
if (fmtVersionComparator.compare(fmtVersion, maxKnownFmtVersion) <= 0) {
157185
return entry.getValue();
158186
}
@@ -170,15 +198,15 @@ public FormatterFunc suggestLaterVersionOnError(V formatterVersion, FormatterFun
170198
Objects.requireNonNull(formatterVersion);
171199
Objects.requireNonNull(originalFunc);
172200
final String hintUnsupportedProblem = buildUnsupportedFormatterMessage(formatterVersion);
173-
final String proposeDiffererntFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem;
174-
return proposeDiffererntFormatter.isEmpty() ? originalFunc : new FormatterFunc() {
201+
final String proposeDifferentFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem;
202+
return proposeDifferentFormatter.isEmpty() ? originalFunc : new FormatterFunc() {
175203

176204
@Override
177205
public String apply(String unix, File file) throws Exception {
178206
try {
179207
return originalFunc.apply(unix, file);
180208
} catch (Exception e) {
181-
throw new Exception(proposeDiffererntFormatter, e);
209+
throw new Exception(proposeDifferentFormatter, e);
182210
}
183211
}
184212

@@ -187,7 +215,7 @@ public String apply(String input) throws Exception {
187215
try {
188216
return originalFunc.apply(input);
189217
} catch (Exception e) {
190-
throw new Exception(proposeDiffererntFormatter, e);
218+
throw new Exception(proposeDifferentFormatter, e);
191219
}
192220
}
193221

@@ -196,16 +224,25 @@ public String apply(String input) throws Exception {
196224

197225
private String buildUpgradeFormatterMessage(V fmtVersion) {
198226
StringBuilder builder = new StringBuilder();
227+
// check if the formatter is not supported on this jvm
228+
V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
199229
V recommendedFmtVersionOrNull = getRecommendedFormatterVersion();
200-
if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) {
230+
if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
231+
builder.append(String.format("You are running Spotless on JVM %d, which requires %s of at least %s.%n", Jvm.version(), fmtName, minimumFormatterVersion));
232+
builder.append(String.format("You are using %s %s.%n", fmtName, fmtVersion));
233+
if (null != recommendedFmtVersionOrNull) {
234+
builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull));
235+
}
236+
// check if the formatter is outdated on this jvm
237+
} else if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) {
201238
builder.append(String.format("%s %s is currently being used, but outdated.%n", fmtName, fmtVersion));
202239
builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull));
203240
builder.append(String.format("%s %s requires JVM %d+.", fmtName, recommendedFmtVersionOrNull, getRequiredJvmVersion(recommendedFmtVersionOrNull)));
204241
} else {
205-
V higherFormatterVersionOrNull = fmt2jvmVersion.higherKey(fmtVersion);
242+
V higherFormatterVersionOrNull = fmtMaxVersion2jvmVersion.higherKey(fmtVersion);
206243
if (null != higherFormatterVersionOrNull) {
207244
builder.append(buildUpgradeJvmMessage(fmtVersion));
208-
Integer higherJvmVersion = fmt2jvmVersion.get(higherFormatterVersionOrNull);
245+
Integer higherJvmVersion = fmtMaxVersion2jvmVersion.get(higherFormatterVersionOrNull);
209246
builder.append(String.format("If you upgrade your JVM to %d+, then you can use %s %s, which may have fixed this problem.", higherJvmVersion, fmtName, higherFormatterVersionOrNull));
210247
}
211248
}
@@ -215,7 +252,7 @@ private String buildUpgradeFormatterMessage(V fmtVersion) {
215252
@Override
216253
public String toString() {
217254
return String.format("%s alternatives:%n", fmtName) +
218-
jvm2fmtVersion.entrySet().stream().map(
255+
jvm2fmtMaxVersion.entrySet().stream().map(
219256
e -> String.format("- Version %s requires JVM %d+", e.getValue(), e.getKey())).collect(Collectors.joining(System.lineSeparator()));
220257
}
221258

lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public static FormatterStep create(String groupArtifact, String version, String
6969
State::createFormat);
7070
}
7171

72-
static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "1.15.0");
72+
static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
73+
.addMin(11, "1.8") // spotless requires java 11, so the min version of google java format we can support is 1.8
74+
.add(11, "1.15.0"); // default version
7375

7476
public static String defaultGroupArtifact() {
7577
return MAVEN_COORDINATE;

0 commit comments

Comments
 (0)