How to aggregate subproject jars/distributions in a root project with base plugin only?


we have a multi project build and want to aggregate all jars and distributions from all subprojects to a build directory under the rootProject. The rootProject has no source code and the subprojects are in different languages (Java, JavaScript and possibly others), so we thought to only apply the base and distribution plugin to the rootProject.

How could we aggregate all generated jars with their dependencies, all the files for non compiled languages and their distributions to a rootProject folder and build a distribution from that?

We currently have more than 30 subprojects with more coming, so this should be automatically applied to all subprojects without explicitly naming them.

Project layout:

|----> build (directory for aggregation)
|----> common-lib (Java library project)
        |----> build
|----> dataGenerator (Java application, dependent on common-lib, generates data)
|----> dataSink (Java application, dependent on common-lib, saves data)
|----> webserver (Java application, dependent on common-lib, queries data from sink)
\----> webclient (JavaScript client application)

build.gradle of root project:

apply plugin: 'base'
apply plugin: 'distribution'

You could add something like this to the root project.

task copyJars(type: Copy) {
    from subprojects.collect { it.tasks.withType(Jar) }
    into "$buildDir/allJars"

You could replace withType(Jar) with withType(AbstractArchiveTask) and this would get all Jar, Zip, and Tar files.

You’d likely also want a consolidated Javadoc, test and coverage reports.

One (ugly) way to achieve is to put something like this in your root build:

task aggregatedJavadoc(type: Javadoc) {
    group = 'aggregation'
    description = 'Generates aggregated Javadoc API documentation.'

    title = "$description $version API"
    destinationDir = file("$buildDir/docs/javadoc")

    def sourceProjects = subprojects.findAll { it.plugins.hasPlugin('java') || it.plugins.hasPlugin('groovy')}
    source sourceProjects.collect { it.sourceSets.main.allJava }
    classpath = files(sourceProjects.collect { it.sourceSets.main.runtimeClasspath })

    options.overview = 'gradle/api/overview.html'

For the tests/coverage just run an extra reporting task with the outputs of all test tasks in all subprojects.