Given this example of a minimal gradle java multiproject (using gradle 6.3 and explicitly using compile instead of api/implementation):
- build.gradle
allprojects {
apply plugin: 'java'
}
- settings.gradle
rootProject.name = 'gradle-fruits'
include ':apple'
include ':banana'
- apple/src/main/java/test/fruit/stonefruits/Apple.java
package test.fruit.stonefruits;
public class Apple {
public static String NAME = "Apple";
}
- banana/build.gradle
dependencies {
compile project(':apple')
}
- banana/src/main/java/test/fruit/herbs/Banana.java
package test.fruit.herbs;
import test.fruit.stonefruits.Apple;
public class Banana {
public static void main(String args[]) {
System.out.println(Apple.NAME);
}
}
We would like to use gradle to generate text files for each project from the compile dependencies and project specific input files (template.in). Such that:
-
apple/template/template.in
Stonefruits
-
banana/template/template.in
Herbs
results in:
-
apple/template/template-apple
Stonefruits
-
banana/template/template-banana
Stonefruits
Herbs
- template/template-gradle-fruits
Stonefruits
Herbs
where
:apple :compileTemplate reads apple/template/template.in and
writes apple/template/template-apple
:banana :compileTemplate reads banana/template/template.in
apple/template/template-apple and concatenates the files into
banana/template/template-banana
:gradle-fruits:compileTemplate reads template/template.in
apple/template/template-apple banana/template/template-banana and
concatenates the files into template/template-gradle-fruits
The task compileTemplate below is supposed to generate a
template/template-${project.name} as an artifact that may be used as
further input for dependant compileTemplate tasks, where the dependency
info comes from the compile configuration:
- build.gradle
void concat(File target, Iterable<File> files) {
target.bytes = []
files.each { f ->
target.append(f.getBytes())
}
}
allprojects {
apply plugin: 'java'
task compileTemplate {
File templ_in = file "template/template.in"
File templ_out = file "template/template-${project.name}"
inputs.files templ_in
outputs.file templ_out
doLast {
List<File> deps = configurations.template.incoming.dependencies.collectMany { d ->
d.artifacts.url
}
List<File> all = [ templ_in ] + deps
println "deps: ${configurations.template.incoming.dependencies.collect { d-> d.name }}"
println "dep artifacts: $deps"
println "all artifacts: $all"
concat(templ_out, all)
}
}
task cleanTemplate {
File templ_out = file "template/template-${project.name}"
doLast {
delete templ_out
}
}
configurations {
template {
canBeConsumed = true
canBeResolved = true
extendsFrom compile
}
}
artifacts {
template(subprojects.compileTemplate.templ_out) {
builtBy(compileTemplate)
}
}
tasks.clean.dependsOn(cleanTemplate)
}
task template {
dependsOn allprojects.compileTemplate
}
however this results in:
$ gradle template
FAILURE: Build failed with an exception.
* Where:
Build file 'build.gradle' line: 46
* What went wrong:
A problem occurred evaluating root project 'gradle-fruits'.
> Could not get unknown property 'templ_out' for task ':compileTemplate of type org.gradle.api.DefaultTask.
Is this the way to do this with gradle and is there any solution for this error?
Thanks for any help.