Reputation: 8738
This is a strange question, but it's not theoretical...
I'd like to make a Gradle project that uses a buildSrc
with a java project inside. That java project defines some classes used in the build process.
The nasty trick is, the Gradle project produces a bunch of outputs, including modified classes that belong to the Java project of the buildSrc
itself.
Is there any way to express this with Gradle?
The only solution I have in mind right now is: run the whole build script twice in a row. Is there any way to avoid that? For example, by generating the modified code for buildSrc
, re-compiling the buildSrc
and then generating the additional outputs of the main Gradle project?
Upvotes: 4
Views: 1157
Reputation: 8738
Okay, building on Michael Easter's awesome example, I can have the main-level build call a GradleBuild
on one of its own tasks:
task generateNewCode() << {
println("tracer top build")
// BuildTool is a Java class defined in `buildSrc`
// ... and it has a cyclic dependency on its own
// output (eek -- but that's what I'm dealing with!)
BuildTool.generateNewCode();
}
task generateDocs(type: GradleBuild) {
buildFile='build.gradle'
tasks = ['generateDocs_Real']
}
task generateDocs_Real << {
BuildTool.outputDocumentation();
}
generateDocs.dependsOn generateNewCode
Then I can invoke gradle generateDocs
to do:
buildSrc
buildSrc
buidSrc
Upvotes: 2
Reputation: 24468
I believe that section 59.4 of the Gradle doc can help you.
Using Gradle 1.8, I tried to "run another Gradle build from a build", where the other Gradle build is buildSrc.
This does not involve codegen, but might be enough to help.
To replicate, I have a simple Java project in buildSrc, with a build.gradle that looks like this:
apply plugin: 'java'
build << {
println "TRACER: hello from buildSrc java build"
}
task compile2() << {
println "TRACER: hello from buildSrc compile2"
}
The 'build' task is called automatically via the buildSrc mechanism. The goal is to call 'compile2' from the root. At the root, the build.gradle looks like this:
task build1() << {
println "TRACER: top-level build1"
}
task build2(type: GradleBuild) {
buildFile = 'buildSrc/build.gradle'
tasks = ['compile2']
}
build2.dependsOn build1
At the root level, the output is as follows:
$ gradle build2
:buildSrc:compileJava etc etc
TRACER: hello from buildSrc java build
TRACER: top-level build1
TRACER: hello from buildSrc compile2
This shows that:
The classpath and codegen is nasty but may be straight-forward.
Upvotes: 1