Gradle - Multi-Project

About

A page about multi-project setup in gradle.

Directory Layout

  • There is only one settings.gradle file at the root
  • There is one top-level build script (build.gradle) (also known as the root project) that configure common sub-projects properties
  • Each child project will usually have its own build file, but that’s not necessarily the case as a project may be just a container or grouping of other subprojects.

Example of layout

├── api
│        └── api.gradle (build.gradle file)
├── shared
│        └── shared.gradle (build.gradle file)
├── services
│        └── shared
│                 └── services-shared.gradle (build.gradle file)
│        └── webservice
│                 └── webservice.gradle (build.gradle file)
├── .../
├── build.gradle
└── settings.gradle

settings.gradle

settings.gradle is the file that describes the project structure (ie the project hierarchy) There is only one file and it's located at the root.

It's the file representation of the Settings object

Example:

rootProject.name = 'mono-repo'

// includes two sub-projects created respectively at:
//      * the ''api'' sub-directory
//      * the ''shared'' sub-directory
include 'api', 'shared'

// Changing the build file for the sub project
project('api').buildFileName = 'api.gradle'
project('shared').buildFileName = 'shared.gradle'

where:

root build.gradle

The root build.gradle is used to share common configuration between the child projects,

// The allprojects block is used to add configuration items that will apply to all sub-projects as well as the root project.
allprojects {
    repositories {
        jcenter() // a repository
    }
    task hello {
        doLast { task ->
            println "I'm $task.project.name"
        }
    }
}
// the subprojects block can be used to add configurations items for all sub-projects only
subprojects {
    version = '1.0'
}

plugins {
    id 'groovy'
    id 'org.asciidoctor.convert' version '1.5.6' apply false // apply false: adds the plugin to the overall project, but does not add it to the root project
}

dependencies {
    compile 'org.codehaus.groovy:groovy:2.4.10'

    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4', {
        exclude module: 'groovy-all'
    }
}

// Common sub-project build script  may be written into the root project.
configure(subprojects.findAll { it.name == 'sub-project1' || it.name == 'sub-project2' }) { 

    apply plugin: 'groovy'

    dependencies {
        testCompile 'org.spockframework:spock-core:1.0-groovy-2.4', {
            exclude module: 'groovy-all'
        }
    }
}

sub-project build.gradle

Many projects will name the build files after the subproject names, such as api.gradle and services.gradle from the previous example. (To be able to open quickly the needed file by name in an ide).

Example:

project('api').buildFileName = 'api.gradle'
dependencies {
    // Transitive dependency between project
    compile project(':subproject2') 
    // test dependency
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4', {
        exclude module: 'groovy-all'
    }
}

// Plugins import
plugins {
    id 'org.asciidoctor.convert' 
}

// task
asciidoctor {
    sources {
        include 'greeter.adoc'   
    }
}

// Bind the ''asciidoctor'' task into the ''build'' lifecycle of the root project
build.dependsOn 'asciidoctor'

// Add the output of a project into a distribution file
distZip {
    from project(':sub-project2').task, { 
        into "${project.name}-${version}"
    }
}
distTar {
    from project(':sub-project2').task, {
        into "${project.name}-${version}"
    }
}

Dependency

Project dependency

dependencies {
    implementation project(':shared')
    // compile project(':shared') 
}

Project Dependency Gradle Api documentation

TestReport

Gradle - Test - Aggregate all sub-project test report. Doc

subprojects {
    apply plugin: 'java'

    // Disable the test report for the individual test task
    test {
        reports.html.enabled = false
    }
}

task testReport(type: TestReport) {
    destinationDir = file("$buildDir/reports/allTests")
    // Include the results from the `test` task in all subprojects
    reportOn subprojects*.test
}

Gradlew / Command line

Projects

  • List
gradlew projects
# or
gradle projects
> Task :projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'mono-repo'
\--- Project ':sub-project1'
\--- Project ':sub-project2'

Task

  • list
# from the root
gradlew task
# or a sub-project
./gradlew :sub-project1:task
  • Execute
# from the root
gradlew :sub-projects:task
# from the sub-project 
cd sub-project
../gradlew test 
cd ..

Build

From the top directory:

gradlew build
# or a sub-project
./gradlew :sub-project1:build
  • buildDependents - Build and Test Dependent Projects
./gradlew :sub-project1:buildDependents

Sample

Documentation


Powered by ComboStrap