gradlegradle-multi-project-build

Gradle multi project build with empty projects


When applying a multi-project Gradle structure to our project, my settings.gradle looks like this:

include "source:compA:api"
include "source:compA:core"
include "source:compB"

gradle projects give me

Root project 'tmp'
\--- Project ':source'
     +--- Project ':source:compA'
     |    +--- Project ':source:compA:api'
     |    \--- Project ':source:compA:core'
     \--- Project ':source:compB'

This is exactly the directory structure!
In my root directory I have a build.gradle which applies the java plugin to all subprojects:

subprojects {
    apply plugin: 'java'
}

When building I end up having artifacts for :source:compA which are empty because this is actually not a project just the subdirectories api and core are proper Java projects.

What's the best way to avoid having an empty artifact?


Solution

  • You can try using the trick they use in Gradle's own settings.gradle file. Note how each of the sub projects are located in the 'subprojects/${projectName}' folder, but the subprojects folder itself is not a project.

    So in your case you'd do something like:

    include "source:compA-api"
    include "source:compA-core"
    include "source:compB"
    
    project(':source:compA-api').projectDir = new File(settingsDir, 'source/compA/api')
    project(':source:compA-core').projectDir = new File(settingsDir, 'source/compA/core')
    

    I have intentionally omitted the colon between compA and api to make sure source:compA does not get evaluated as a project container.

    Alternatively, you can try excluding the source:compA project from having the java plugin applied to it, by doing something like:

    def javaProjects() { 
      return subprojects.findAll { it.name != 'compA' }
    } 
    
    configure(javaProjects()) { 
      apply plugin: 'java' 
    } 
    

    Edit: Alternatively you can try something like this (adjust to your liking):

    def javaProjects() { 
      return subprojects.findAll { new File(it.projectDir, "src").exists() }
    } 
    
    configure(javaProjects()) { 
      apply plugin: 'java' 
    }