I'm trying to make a dist of a multi project build. The root project looks something like this:
apply plugin: 'distribution'
version 1.0
distributions {
main {
baseName = 'someName'
contents {
from 'nodes'
into 'nodes'
}
}
}
It just copies a folder with some files to the dist.
I now want each subproject to inject its stuff into the dist. I want to add each subprojects jar, any dependecies, and possibly some other files etc...
I have no idea how to inject from the subproject to the root. Should I even do something like that? What i mean is something like this:
subprojects {
apply java...
...
// pseudocode
jack into the root project dist plugin
put my produced jars and dependencies in a folder with my name
...
}
Does anyone have any examples, or just point me in the right direction?
thanks!
buildSrc should be preferred over script plugins as it is easier to maintain, refactor and test the code. buildSrc uses the same source code conventions applicable to Java and Groovy projects. It also provides direct access to the Gradle API.
The subproject producer defines a task named buildInfo that generates a properties file containing build information e.g. the project version. You can then map the task provider to its output file and Gradle will automatically establish a task dependency. Example 2.
The Distribution Plugin facilitates building archives that serve as distributions of the project. Distribution archives typically contain the executable application and other supporting files, such as documentation.
I was looking for the same thing. With some peeking at the API docs and Gradle' own build files, I came to the following:
apply plugin: 'distribution'
distributions {
main {
contents {
into('bin') {
from { project(':subproject1').startScripts.outputs.files }
from { project(':subproject2').startScripts.outputs.files }
fileMode = 0755
}
into('lib') {
def libs = []
libs << project(':subproject1').configurations.runtime - project(':runner').configurations.runtime
libs << project(':subproject2').configurations.runtime
from libs
from project(':subproject1').jar
from project(':subproject2').jar
}
}
}
}
The contents {} closure is a CopySpec, knowing that makes using the distribution plugin way simpler :)
Check out Gradle' own subprojects/distributions/distributions.gradle file for some great examples of using the CopySpec.
This works.
Sadly, currently I've no clue on how to scale this to more than two projects in a clean way. Atleast we're one step closer :)
I found a solution that has been working well for me. The key is that you add a separate subproject for creating the dist. This subproject is sibling to the other subprojects. That is, do not try to script the distribution in your top-level build.gradle
file.
Let's call the new subproject dist
. The first thing to do is to add it to your top-level settings.gradle
file in your multi-project root:
include "subproject1", "subproject2", "subproject3", ....... , "dist"
Your dist
project must at minimum include:
build.gradle
- to be detailed below src/main/dist/at_least_one_dummy_file.txt
- the distribution plugin always requires a src/main/$distribution.name
directory. Having a non-empty one with a distribution.name
of main
tricks the plugin into following all the transitive dependencies of all the main
sourcesets of all the sibling projects.Next, the build.gradle
file for the dist
project:
/* Hook in all sibling project jars and their transitive dependencies */
apply plugin: 'java'
dependencies {
compile project(':subproject1')
compile project(':subproject2')
compile project(':subproject3')
. . .
}
/* Distribution */
apply plugin: 'java-library-distribution'
distributions {
main {
baseName = "your-top-level-project-name"
contents {
exclude "dist-${version}.jar"
. . .
}
}
}
Then run gradle distZip
. The ZIP
file in dist/build/distributions
will have a lib
subdirectory with every single JAR
you want: the sibling project JAR
s and their transitive dependencies.
Because of the trickery we used, the distribution plugin will make an empty JAR
called dist-${version}.jar
. For cosmetic reasons, I remove it with the exclude
call above, but it is harmless. You could also use a second exclude
call to remove the at_least_one_dummy_file.txt
if there really is no content under src/main/dist
that you want to include. If you do not want add any artifacts and/or remove the ones mentioned here, then you don't even need a contents
section at all.
I also have found ways of selectively including different artifacts based on whether this is a "dev" or "prod" distribution, a la Maven profiles. If you want me to add that, please post in comments and I will.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With