Advanced composite build

Hello everyone,

we have two projects project1 and project2. I uploaded an example to Github.

project2 has project1 as binary dependency:

// project2 build.gradle
dependencies {
    implementation('com.example:project-1:1.0.0')
}

Now we want to include project1 as composite build in project2 which works just fine:

// project2 settings.gradle
boolean substituteDependency = hasProperty('substituteDependency')

includeBuild('../project1') {
    if (substituteDependency) {
        dependencySubstitution {
            substitute module('com.example:project-1') with project(':')
        }
    }
}

Now we have some additional files in project1 which are placed in the distribution zip of project1 (represented by the project1/src/main/dist/ExampleFile.txt file). These files are needed in project2 for a specific task and therefore published together with the actual sources:

// project1 build.gradle
publishing {
    publications {
        project1(MavenPublication) {
            artifactId = 'project-1'
            from components.java
            artifact(project.distZip) {
                classifier "resources"
            }
            artifact sourcesJar
            artifact javadocJar
        }
    }
}
// project2 build.gradle
configurations {
    additionalResources
}
dependencies {
    additionalResources(group: 'com.example', name: 'project-1', version: '1.0.0', classifier: 'resources', ext: 'zip')
}
task exampleTask {
    inputs.files configurations.additionalResources.singleFile

    doLast {

        def tree = zipTree(configurations.additionalResources.singleFile)
        ...
    }
}

When using this setup together with the configuration as composite build we get the following error:

A problem occurred evaluating root project 'project2'.
> Could not resolve all files for configuration ':additionalResources'.
   > Could not find project-1-resources.zip (project :project1).

Is there a possibility of substituting these additional resources with the outputs of project1.distZip task? Or is there a different/better way to publish the additional resources in the first place?

Thanks for any advice.

1 Like

After this problem came up again, I had a close look at the features introduced with newer gradle versions (like feature variants and capabilities) and with help of the gradle team I managed to get my use case working. I updated the example project, but just in case - the main changes are as following:

// project1 build.gradle
java {
    registerFeature('myFeature') { // add feature variant from main source set (in addition to the "default" feature)
        usingSourceSet(sourceSets.main)
    }
}

configurations.myFeatureApiElements.outgoing {
    artifacts.clear() // remove jar
    artifact distZip // add output of distZip task
}
configurations.myFeatureRuntimeElements.outgoing {
    artifacts.clear() // remove jar
    artifact distZip // add output of distZip task
}
// project2 build.gradle
dependencies {
    additionalResources(group: 'com.example', name: 'project-1', version: '1.0.0') {
        capabilities { // use declared feature variant instead of "classifier"-extension
            requireCapability('com.example:project1-my-feature')
        }
    }
}
1 Like