1.1 Composite Builds
Sometimes there might be situations where you are working on a project that is made up of multiple libraries managed by yourself or your team. In situations like this, you might want to test how a change in one project will affect another project without deploying updates to an artifact repository. This is where the concept of Gradle composite builds comes into play.
Enabling Composite Builds
Composite builds are a concept which we use to describe a project which is made from multiple separated projects. This is typically beneficial for testing changes as previously mentioned. To enable these, its typically recommended you define your compositions in your settings.gradle
or settings.gradle.kts
file. For the purposes of this guide, we will be relying on the kts
file definition.
// Functions
fun composite(block: () -> Unit) {
if (File(".composite-enabled").exists()) {
block()
}
}
fun useLocal(
module: String,
projectName: String = module.substringAfter(":"),
) {
includeBuild("../$projectName") {
dependencySubstitution {
substitute(module(module)).using(project(":"))
}
}
}
// Usage
composite {
// For modules with the same project name
useLocal("com.example:module")
// For modules where the project name differs from the module name
useLocal("com.example:other-module", "other-module-project")
}
This function will search the parent directory of the current project for the local build, if you use this function as written you will need to make sure both this project and the dependency project are stored in the same directory as each other.
Extending Composite Support
If you want to take things a step further, it is possible to write custom Bash commands that you can use to generate or delete composite files for you. This works best if you work in a terminal environment which supports defining custom commands like ZSH.
Put the following code in your .zshrc
file, or whichever config file is used for your shell.
# Enables composition in current directory
composite() {
echo > .composite-enabled
}
# Disables composition in current directory
decomposite() {
rm -f .composite-enabled
}
# Enables composition for all directories in the current working directory
composite-all() {
for dir in ./*/; do
cd $dir
composite
done
cd -
}
# Disables composition for all directories in the current working directory
decomposite-all() {
for dir in ./*/; do
cd $dir
decomposite
done
cd -
}
By running these commands in your terminal, you can set up composition for one or many projects at the same time. As long as these commands are also present in your environment, you may also set these up as part of automated tasks, these can be configured in many build systems including Gradle, as well as NPM, and Make,