-
Notifications
You must be signed in to change notification settings - Fork 484
Description
We have a strange feature in the Spotless gradle plugin: googleJavaFormat('1.8')
The exact chain by which that 1.8
becomes a dependency that gets declared to Gradle is this:
the stacktrace
spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java
Lines 168 to 171 in f9d66c4
private FormatterStep createStep() { | |
return GoogleJavaFormatStep.create( | |
groupArtifact, | |
version, |
spotless/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
Lines 137 to 139 in 2ca0db1
State(String stepName, String groupArtifact, String version, String style, Provisioner provisioner, boolean reflowLongStrings) throws Exception { | |
JVM_SUPPORT.assertFormatterSupported(version); | |
this.jarState = JarState.from(groupArtifact + ":" + version, provisioner); |
spotless/lib/src/main/java/com/diffplug/spotless/JarState.java
Lines 65 to 68 in 2ca0db1
private static JarState provisionWithTransitives(boolean withTransitives, Collection<String> mavenCoordinates, Provisioner provisioner) throws IOException { | |
Objects.requireNonNull(mavenCoordinates, "mavenCoordinates"); | |
Objects.requireNonNull(provisioner, "provisioner"); | |
Set<File> jars = provisioner.provisionWithTransitives(withTransitives, mavenCoordinates); |
spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java
Lines 33 to 44 in 2ca0db1
static Provisioner forProject(Project project) { | |
Objects.requireNonNull(project); | |
return (withTransitives, mavenCoords) -> { | |
try { | |
Configuration config = project.getConfigurations().create("spotless" | |
+ new Request(withTransitives, mavenCoords).hashCode()); | |
mavenCoords.stream() | |
.map(project.getDependencies()::create) | |
.forEach(config.getDependencies()::add); | |
config.setDescription(mavenCoords.toString()); | |
config.setTransitive(withTransitives); | |
return config.resolve(); |
spotless/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
Lines 147 to 148 in 2ca0db1
FormatterFunc createFormat() throws Exception { | |
ClassLoader classLoader = jarState.getClassLoader(); |
spotless/lib/src/main/java/com/diffplug/spotless/JarState.java
Lines 86 to 90 in 2ca0db1
* The lifetime of the underlying cacheloader is controlled by {@link SpotlessCache}. | |
*/ | |
public ClassLoader getClassLoader() { | |
return SpotlessCache.instance().classloader(this); | |
} |
spotless/lib/src/main/java/com/diffplug/spotless/SpotlessCache.java
Lines 68 to 71 in 2ca0db1
synchronized ClassLoader classloader(Serializable key, JarState state) { | |
SerializedKey serializedKey = new SerializedKey(key); | |
return cache | |
.computeIfAbsent(serializedKey, k -> new FeatureClassLoader(state.jarUrls(), this.getClass().getClassLoader())); |
In every Spotless before 6.0
, we resolved all formatter dependencies against the buildscript
repositories in the root project. That changed in 6.0 because of these two PRs:
- Resolve dependencies from "project" repositories, not buildscript #980 changed that to resolve against the normal project repositories in the root project
- Resolve dependencies per-project #983 changed that to resolve against the normal project repositories of each project where spotless was used
If you want the old behavior back, we're happy to take a PR which adds it as a feature like so.
// build.gradle (root project only)
spotless {
predeclareDeps()
// predeclareDepsFromBuildscript() to get pre-6.0 behavior
}
spotlessPredeclare {
// now you have to declare every formatter (including version) that you plan to use
// you don't need to set the target, that part doesn't matter
java { googleJavaFormat('1.4') }
}
// works/build.gradle
spotless {
java { googleJavaFormat('1.4') } // ok
}
// error/build.gradle
spotless {
java { googleJavaFormat('1.3') } // throws error at configuration time
}