Skip to content

Conversation

ervinpm
Copy link

@ervinpm ervinpm commented Nov 24, 2021

nedtwigg edit: fixes #860

@nedtwigg
Copy link
Member

Great PR! I think the System.identityHashCode stuff should only be used for composite builds, which you can detect with project.gradle.includedBuilds.

If you make that change, then the tests should pass again. If they're still failing, you might need to tweak this:

protected static List<String> outcomes(BuildResult build, TaskOutcome outcome) {
return build.taskPaths(outcome).stream()
.filter(s -> !s.equals(":spotlessInternalRegisterDependencies"))
.collect(Collectors.toList());
}
protected static List<BuildTask> outcomes(BuildResult build) {
return build.getTasks().stream()
.filter(t -> !t.getPath().equals(":spotlessInternalRegisterDependencies"))
.collect(Collectors.toList());
}

@ervinpm
Copy link
Author

ervinpm commented Nov 24, 2021

the project.gradle.includeBuilds did not work, it yield 0 in size for the composite projects. I used project.subprojects instead.

@nedtwigg
Copy link
Member

I used project.subprojects instead

Hrm... A multiproject build with no included builds should not be doing the hashCode thing. I'd be very surprised if getIncludedBuilds was broken. Can you share any info about your integration test which indicates that getIncludedBuilds is broken?

@ervinpm
Copy link
Author

ervinpm commented Nov 29, 2021

Sure! I added some log lines when testing this:

System.out.println("project name: " + project.getName());
System.out.println("project builds: " + project.getGradle().getIncludedBuilds().size());
System.out.println("project root project: " + project.getRootProject().getName());
System.out.println("project root project builds: " + project.getRootProject().getGradle().getIncludedBuilds().size());
System.out.println("project root project subprojects: " + project.getRootProject().getSubprojects().size());

I have 11 projects under my root project and they are defined in settings.gradle of the root project:

include "project1", "project2", "project3", "project4", "project5", "project6", "project7", "project8", "project9", "project10", "project11"

I have spotless plugin defined in project1 and 2. This is what shows up when I do a gradle build in the root project

$./gradlew build

> Configure project :project1
project name: project1
project builds: 0
project root project: myrootproject
project root project builds: 0
project root project subprojects: 11
Including axis libraries in the build...
classpath
classpath

> Configure project :project2
project name: project2
project builds: 0
project root project: myrootproject
project root project builds: 0
project root project subprojects: 11

I hope this helps.

@nedtwigg
Copy link
Member

What you described above is a multi-project build. A composite build is a bit different, you'd have to use includeBuild in the settings.gradle, or else you can specify --include-build on the command line.

Spotless already works 100% with multiproject builds to my knowledge (I am using it on several such projects). I see from #860 that you are in fact getting the is not a subclass of the given type error, which I had previously believed to only be possible with a true composite build, not a multiproject build.

How are you applying spotless? From the settings.gradle? A plugins block in the root build.gradle? Maybe a multiple plugins blocks spread out across multiple subprojects?

@ervinpm
Copy link
Author

ervinpm commented Nov 30, 2021

Oh ok, hopefully this fixes that too. Each subproject has a plugin block with spotless in it, no plugin block in the root project or in settings.gradle. Let me know if you want me to try a specific configuration.

@nedtwigg
Copy link
Member

Each subproject has a plugin block with spotless in it

Ahhhh... Interesting. If you specified spotless in the pluginManagement block, I'm pretty sure that would be a workaround for you. I also think it would be a bit faster - sharing a single classloader across projects will help with JIT warmup which is a real factor for Spotless' performance.

The System.identityHashCode trick is kinda nasty. Composite build is a special case, so I was okay adding complexity for a complex case. Multiproject build is very common, I don't like adding this complexity to every multiproject build. But your usage is totally valid.

What do you think about trying this?

try {
  // register buildService or registerDependenciesTask
} catch (InvalidUserDataException e) {
  if (e.message.contains("is not a subclass of the given type")) {
      // try again with the System.identityHashCode trick
  }
}

That way the workaround only happens when absolutely needed, and the rest of the time users get nice predictable and repeatable task names.

@ervinpm
Copy link
Author

ervinpm commented Dec 7, 2021

Thanks for that tip on plugin management, that did work, I was traveling and did not get the chance to come back to this.

@nedtwigg nedtwigg merged commit 1d3705f into diffplug:main Dec 7, 2021
@nedtwigg
Copy link
Member

nedtwigg commented Dec 7, 2021

Published in 6.0.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Composite gradle build: spotless works in one project and not in another
2 participants