Wednesday, September 27, 2017

How to allow / workaround nested composite Gradle builds

Leave a Comment

I'm running into the same issue as reported here:

I have a Java project A which depends on project B (module), and project B dependes on project C (another module). For project A I would like to setup "includeBuild ../projectB" and for project B I would like too setup "includeBuild ../projectC" so that I could develop everything in Eclipse + Buildship 2.0 without the need to run Gradle for every small change in each of the projecta A, B and C.

But if I setup this I get: "Included build '%s' cannot have included builds.".

Expected Behavior

Recursive "includeBuild" would recursively include dependent projects.

Current Behavior

I get "Included build '%s' cannot have included builds.".

Your Environment

Gradle 3.5, Buildship 2.0, Eclipse 3.6

How can I resolve / work around this issue? In my instance, I have utility project that includes email functionality (using JavaMail). The email functionality is needed in the data project and a UI project. The UI project also depends on the data project.

2 Answers

Answers 1

Have you considered

  1. Ensuring that none of the individual builds are composite builds
  2. Having an "uber" build which is a composite of everything

Note that the settings.gradle is itself a groovy script, so you could create a dynamic composite, eg all sub-folders with a build.gradle under a parent.

uber/settings.gradle

new File("c:/someFolder").listFiles().each { File f ->     if (f.directory && new File(f, 'build.gradle').exists()) {         includeBuild f     } } 

Eg

c:/someFolder/project1/build.gradle c:/someFolder/project1/src/main/java/**/*.java c:/someFolder/project2/build.gradle c:/someFolder/project2/src/main/java/**/*.java c:/uber/settings.gradle (as above) 

Answers 2

Adding another answer for a different approach...

Each settings.gradle could add a check to before includeBuild to see if it's already inside a composite. If it's already inside a composite, it doesn't includeBuild.

See here for extra info on the composite check

Eg

project2/settings.gradle

boolean inComposite = gradle.parent != null if (!inComposite) {     includeBuild '../project1' } 

project3/settings.gradle

boolean inComposite = gradle.parent != null if (!inComposite) {     includeBuild '../project1'     includeBuild '../project2' } 

project4/settings.gradle

boolean inComposite = gradle.parent != null if (!inComposite) {     includeBuild '../project1'     includeBuild '../project2'     includeBuild '../project3' } 

etc etc

Using this approach you could run gradle from wherever you like and it should behave as expected (ie substitute dependencies with local projects)

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment