3

I know you can access different modules (included using include) in a project via org.gradle.api.Project#getSubprojects(), and I know you can get the name and directories of separate builds that have been included (using includeBuild) via org.gradle.api.invocation.Gradle#getIncludedBuilds().

But how can my plugin get information such as the locations of Java source files and class files for projects included using includeBuild?

My goal here is to determine which files have changed in the current git branch (which I can do), and then collect their corresponding class files into a jar file that's used for our patching mechanism that inserts the patch jars at the front of the classpath rather than redeploying the whole application.

Brad Mace
  • 27,194
  • 17
  • 102
  • 148
  • Can you maybe provide more details on what _specifically_ you’re trying to achieve? I can hardly imagine why a Gradle plugin should worry about included builds at all. It may worry about dependencies and _maybe_ whether they’re coming from an included build or from somewhere else. But how those dependencies are/were created shouldn’t be relevant to the including build; otherwise the corresponding project should probably rather take care of producing them itself in the first place. Maybe I’m missing something, though ;-) – Chriki Jan 10 '22 at 21:06
  • @Chriki updated. it's a weird legacy scenario I'm looking to get away from eventually but can't quite yet. – Brad Mace Jan 10 '22 at 21:59
  • Does this help what you are after - https://stackoverflow.com/a/56663716/11543023 – djmonki Jan 11 '22 at 07:28
  • @djmonki using inputs and outputs seems like it could be the proper way to handle this, but I don't understand it well enough to see how to go about it yet – Brad Mace Jan 11 '22 at 14:30
  • @Brad Mace, thanks for the update. I’m sorry, I still don’t quite understand what specifically you’d like to eventually achieve. I’ve anyway given it a shot and tried to answer your question on how Gradle plugins (or builds in general) can access information from included builds. – Chriki Jan 12 '22 at 20:46

1 Answers1

3

I don’t think it is a goal of Gradle to provide including builds with detailed information on included builds. Currently, the Gradle docs basically only state two goals for such composite builds:

  • combine builds that are usually developed independently, […]
  • decompose a large multi-project build into smaller, more isolated chunks […]

Actually, isolation between the involved builds seems to be an important theme in general:

Included builds do not share any configuration with the composite build, or the other included builds. Each included build is configured and executed in isolation.

For that reason, it also doesn’t seem to be possible or even desired to let an including build consume any build configurations (like task outputs) of an included build. That would only couple the builds and hence thwart the isolation goal.

Included builds interact with other builds only via dependency substitution:

If any build in the composite has a dependency that can be satisfied by the included build, then that dependency will be replaced by a project dependency on the included build.

So, if you’d like to consume specific parts of an included build from the including build, then you have to do multiple things:

  • Have a configuration in the included build which produces these “specific parts” as an artifact.
  • Have a configuration in the including build which consumes the artifact as a dependency.
  • Make sure that both configurations are compatible wrt. their capabilities so that dependency substitution works.
  • Let some task in the including build use the dependency artifact in whatever way you need.

Those things happen kind of automatically when you have a simple dependency between two Gradle projects, like a Java application depending on a Java library. But you can define your own kinds of dependencies, too.

The question is: would that really be worth the effort? Can’t you maybe solve your goal more easily or at least without relying on programmatically retrieved information on included builds? For example: if you know that your included build produces class files under build/classes/java/main, then maybe just take the classes of interest from there via org.gradle.api.initialization.IncludedBuild#getProjectDir().

I know, this may not be the answer you had hoped to get. I still hope it’s useful.

Chriki
  • 15,638
  • 3
  • 51
  • 66