Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute Gradle task after subprojects are configured

Tags:

gradle

I have a multi-project Gradle build where subprojects are assigned version numbers independent of the root project. I'd like to inject this version number into a few resource files in each subproject. Normally, I'd do this by configuring the processResources task for each subproject in the root build. However, the problem is that Gradle appears to be executing the processResources task before loading the subprojects' build files and is injecting "unspecified" as the version.

Currently, my project looks like this:

/settings.gradle

include 'childA' // ... and many others

/build.gradle

subprojects {
    apply plugin: 'java'
    apply plugin: 'com.example.exampleplugin'
}

subprojects {
    // This has to be configured before processResources
    customPlugin {
        baseDir = "../common"
    }

    processResources {
        // PROBLEM: version is "unspecified" here
        inputs.property "version", project.version

        // Inject the version:
        from(sourceSets.main.resources.srcDirs) {
            include 'res1.txt', 'res2.txt', 'res3.txt'
            expand 'version':project.version
        }
        // ...
    }
}

/childA/build.gradle

version = "0.5.424"

I looked into adding evaluationDependsOnChildren() at the beginning of root's build.gradle, but that causes an error because childA/build.gradle runs before customPlugin { ... }. I've tried using dependsOn, mustRunAfter, and other techniques, but none seem have the desired effect. (Perhaps I don't fully understand the lifecycle, but it seems like the root project is configured and executed before the subprojects. Shouldn't it configure root, then configure subprojects, and then execute?)

How can I get inject the version of each subproject into the appropriate resource files without a lot of copy/paste or boilerplate?

like image 775
user3427070 Avatar asked May 15 '26 16:05

user3427070


2 Answers

You could try using this method, with a hook:

gradle.projectsEvaluated({
   // your code
})
like image 142
Victor Avatar answered May 19 '26 03:05

Victor


I got this figured out for myself. I'm using a init.gradle file to apply something to the rootProject, but I need data from a subproject.

First option was to evaluate each subproject before I modified it:

rootProject {
    project.subprojects { sub ->
        sub.evaluate()
        //Put your code here

But I wasn't sure what side effects forcing the sub project to evaluate would have so I did the following:

allprojects {
    afterEvaluate { project ->
         //Put your code here
like image 24
BoredAndroidDeveloper Avatar answered May 19 '26 04:05

BoredAndroidDeveloper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!