Home > Blockchain >  Creating combined distribution for composite Gradle build
Creating combined distribution for composite Gradle build

Time:12-17

I've got a modular Java project that combines libraries and CLI tools:

  • cli-tools/
    • create-patch
    • find-conflicts
  • modules/
    • core
    • analysis

I'm trying to create a combined distribution from the cli-tools project which contains all the dependency jars and all the launch scripts generated by the application plugin. I've got the build dependencies working, and my local jars are being included, but the launch scripts are not being included, and neither is anything from the runtimeClasspaths. My logging statement shows no plugins on any of the subprojects, even though their tasks are being executed, so maybe my method of checking for plugins is wrong?

// cli-tools/build.gradle.kts:

tasks.named("distZip").configure {
    subprojects.forEach {
        dependsOn(it.path.plus(":startScripts"))
    }
}

distributions {
    main {
        distributionBaseName.set("patch-tools")
        contents {
            project.subprojects.forEach { sub ->
                val subLibs = sub.buildDir.resolve("libs")
                if (subLibs.exists())
                    into("lib") {
                        from(subLibs)
                    }

                sub.logger.info("plugins of {}: {}", sub.name, sub.plugins)
                if (sub.pluginManager.hasPlugin("application")) {
                    into("lib") {
                        from(sub.configurations.findByName("runtimeClasspath"))
                    }
                    into("bin") {
                        from(sub.buildDir.resolve("scripts"))
                    }

                }
            }
        }
    }
}

How can I get this working so launch scripts and transitive dependencies are included in the distribution?

CodePudding user response:

I think that this line:

dependsOn(it.path.plus(":startScripts"))

should rather be:

dependsOn(":startScripts")

... because one cannot mix path with module name; there's also no sub-modules available. However, by the question it's not perfectly clear, if :startScripts is a task or a module.

CodePudding user response:

Instead of trying to manually collect the individual pieces of the subproject distributions from the subproject build directories, I would recommend to rather let the subprojects create their complete distributions first and then to let the parent project combine those into a new one. This also has the advantage that you won’t miss any non-default/special pieces of the subproject distributions in the combined distribution (like docs or other directories).

Here’s how your cli-tools/build.gradle.kts could then look like:

plugins {
    distribution
}

tasks.named<Zip>("distZip") {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

distributions {
    main {
        distributionBaseName.set("patch-tools")
        project.subprojects.forEach { sub ->
            sub.afterEvaluate {
                tasks.all { task ->
                    if (task.name == "installDist") {
                        contents.from(task)
                    }
                    true
                }
            }
        }
    }
}

The distZip task (via the distribution contents CopySpec) now automatically depends on the installDist tasks of the subprojects and produces a combined distribution from their outputs.

(successfully tested with Gradle 7.3.2)

  • Related