Skip to content

Predeclared dependencies (opt-in feature/restriction) #984

Closed
@nedtwigg

Description

@nedtwigg

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

private FormatterStep createStep() {
return GoogleJavaFormatStep.create(
groupArtifact,
version,

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);

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);

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();

FormatterFunc createFormat() throws Exception {
ClassLoader classLoader = jarState.getClassLoader();

* The lifetime of the underlying cacheloader is controlled by {@link SpotlessCache}.
*/
public ClassLoader getClassLoader() {
return SpotlessCache.instance().classloader(this);
}

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:

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
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions