Getting rid of binary dependencies with composite builds in Gradle 3.1
Since the advent of Gradle, there have been 2 ways to break your assembly into components: through binary dependencies and using multi-project builds. Each of these methods has its pros and cons. In the case of binary dependencies, there is a need to publish artifacts, which complicates the assembly. When using a multi-project assembly, it becomes
more difficult to isolate the components from each other.
Composite assemblies
In the upcoming version 3.1 in Gradle, a new approach to organizing assemblies consisting of several components appears: composite assemblies ( orig . Composite Builds).
Composite assemblies allow you to:
- Quickly put the corrected version of the library sources in another project without the need to assemble it, publish and edit the assembly.
- Divide large projects into several small, isolated assemblies, on each of which you can work individually or simultaneously.
- Separate plug-in development to build the system from the project, it is used (analogue
buildSrc)
Let's look at a simple example of using the new feature.
To do this, create a simple projection:
--app/
|-src/main/java/Main.java
|-build.gradle
- lib/
|-src/main/java/A.java
|-build.gradle
|-settings.gradlelib / build.gradle:
apply plugin: 'java'
group "ru.shadam"
version "1.0"
task wrapper(type: Wrapper) {
gradleVersion = '3.1-rc-1'
}app / build.gradle
apply plugin: 'java'
apply plugin: 'application'
mainClassName='Main'
dependencies {
compile 'ru.shadam:lib1:1.0'
}
task wrapper(type: Wrapper) {
gradleVersion = '3.1-rc-1'
}Now, if we try to run appusing the command, ./gradlew runGradle will swear at an unresolved dependency:
$ ./gradlew run
:compileJava
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all dependencies for configuration ':compileClasspath'.
> Cannot resolve external dependency ru.shadam:lib1:1.0 because no repositories are defined.
Required by:
project :
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1.027 secsBut, if we add a new flag - include-build, then Gradle will resolve the dependencies automatically:
$ ./gradlew run --include-build ../lib1
[composite-build] Configuring build: C:\Users\sala\projects\gradle-compose\lib1
:compileJava
:lib1:compileJava UP-TO-DATE
:lib1:processResources UP-TO-DATE
:lib1:classes UP-TO-DATE
:lib1:jar UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Hello
BUILD SUCCESSFUL
Total time: 1.092 secsAdvanced use cases.
Embed --include-build in the script
The above option is more suitable for single use - here and now. I don’t want to specify flags every time - even if I sew them in a wrapper.
For this, gradle suggests using a configuration using settings.gradle. So, the above flag can be replaced with the following settings.gradle:
includeBuild('../lib1')Lookups
What if the project that you want to include does not specify the coordinates of the artifact? (group, version)
Substitutions come to the rescue:
includeBuild('../lib1') {
dependencySubstitution {
substitute('ru.shadam:lib1') with project(':')
}
}This feature allows you to substitute any dependency on the ru.shadam:lib1dependency on the project lib1.
Dependencies between tasks
In the case of a composite assembly, projects are isolated from each other, so you cannot declare dependencies between assemblies directly.
In this regard, a new syntax has appeared for accessing included assemblies. For example, you can determine the dependence on the task of the included assembly:
task run {
dependsOn gradle.includedBuild('lib1').task(':jar')
}What doesn't work yet?
- Projects that have published artifacts that do not match the default configuration are not supported as included projects. link
- While there is no support in the IDE (but support for generating a project using the command
./gradlew idea) - Native builds are not supported.
Team plans
- Add the ability to call tasks directly from included assemblies.
- Add the ability to execute included builds in parallel
- Add change detection in enabled assemblies when using a flag
-t. - Make the implicit buildSrc project an included build.