1

I have a multi-module gradle project and it seems that I need some common task, or a root task, that can be run on each child project with different parameters. My project structure is:

-+ parent
 |  /gradle
 |  build.gradle.kts
 |  settings.gradle.kts
 |  gradlew
 |  gradlew.bat
 +- child1
 |    /build
 |    build.gradle.kts
 +- child2
 |    /build
 |    build.gradle.kts
 +- child3
 |    /build
 |    build.gradle.kts
 +- child4
 |    /build
 |    build.gradle.kts

I need to run jacoco test coverage tasks only at child2, child3, and child4 projects with individual minimum value.

So I can't define a task in the subprojects section of root build.gradle.kts, because it will be applied to all subprojects.

Also as an alternative, it seems that I can define a task in the root build.gradle.kts and call it dependsOn(":parent:myTask") but in this case I can't use parameterization...

I'm not very familiar with this, so could anyone explain the right way it should be done, or maybe point to a good example of similar functionality?

Monish Khatri
  • 820
  • 1
  • 7
  • 24
darth jemico
  • 605
  • 2
  • 9
  • 18
  • The trick is to create a convention plugin. There's [an example](https://docs.gradle.org/current/samples/sample_convention_plugins.html) in the Gradle docs, and see [this answer](https://stackoverflow.com/questions/71883613/configure-kotlin-extension-for-gradle-subprojects/71892685#71892685) on a similar question. – aSemy Apr 13 '23 at 19:24

1 Answers1

0

I'm sure there's many ways to go about this, but how about something like this... The task can live in the root build.gradle, and you can parse the project name and define your value specifically (you could also skip sub-projects you don't want to do it in). For example...

tasks.register("jill") {
    doLast {
        println("Jill was here")
    }
}

allprojects {
    gradle.projectsEvaluated {
        var value = 0
        if (project.name == "child1") value = 45
        if (project.name == "child2") value = 73
        if (project.name == "child3") value = 61
        if (project.name == "child4") value = 38
        tasks.register("jones") {
            doLast {
                println("PROJECT [$value]: ${project.name}")
            }
        }
        tasks.findByPath(":jill").finalizedBy(project.tasks.findByName("jones"))
    }
}

Explaining the solution a moment... Looping through all projects, set value based on project name. Then, register a task in each sub-project which will do some stuff (mine prints project name and computed value).

Then, since you mentioned it, it connects all of these new tasks (jones) to a task in the root project (jill).

Finally, you can simply run ./gradlew jill. It runs the main tasks, and finalizes it by all of the created tasks in the child projects, each with self-awareness of their own values.

> Task :jill
Jill was here

> Task :child4:jones
PROJECT [38]: child4

> Task :child3:jones
PROJECT [61]: child3

> Task :child2:jones
PROJECT [73]: child2


> Task :child1:jones
PROJECT [45]: child1
User51
  • 887
  • 8
  • 17