Execute gradle task on sub projects
Asked Answered
E

3

59

I have a MultiModule gradle project that I am trying to configure.

Root
    projA
    projB
    other
        projC
        projD
        projE
        ...

What I want to be able to do is have a task in the root build.gradle which will execute the buildJar task in each of the projects in the other directory.

I know I can do

configure(subprojects.findAll {it.name != 'tropicalFish'}) {
    task hello << { task -> println "$task.project.name"}
}

But this will also get projA and projB, I want to only run the task on c,d,e... Please let me know the best way to achieve this.

Err answered 22/10, 2014 at 14:7 Comment(0)
B
63

Not entirely sure which of these you're after, but they should cover your bases.

1. Calling the tasks directly

You should just be able to call

gradle :other/projC:hello :other/projD:hello

I tested this with:

# Root/build.gradle
allprojects {
    task hello << { task -> println "$task.project.name" }
}

and

# Root/settings.gradle
include 'projA'
include 'projB'
include 'other/projC'
include 'other/projD'

2. Only creating tasks in the sub projects

Or is it that you only want the task created on the other/* projects?

If the latter, then the following works:

# Root/build.gradle
allprojects {
    if (project.name.startsWith("other/")) {
        task hello << { task -> println "$task.project.name" }
    }
}

and it can then be called with:

$ gradle hello
:other/projC:hello
other/projC
:other/projD:hello
other/projD

3. Creating a task that runs tasks in the subprojects only

This version matches my reading of your question meaning there's already a task on the subprojects (buildJar), and creating a task in root that will only call the subprojects other/*:buildJar

allprojects {
    task buildJar << { task -> println "$task.project.name" }
    if (project.name.startsWith("other/")) {
        task runBuildJar(dependsOn: buildJar) {}
    }
}

This creates a task "buildJar" on every project, and "runBuildJar" on the other/* projects only, so you can call:

$ gradle runBuildJar
:other/projC:buildJar
other/projC
:other/projC:runBuildJar
:other/projD:buildJar
other/projD
:other/projD:runBuildJar

Your question can be read many ways, hope this covers them all :)

Belda answered 22/10, 2014 at 16:32 Comment(3)
Thanks for the answer. None of the options suited my needs: 1. We need to know the list of all subprojects. 2+3. Build script needs to be modified. Finally, I found another way to achieve this and added it as a new answer.Udall
@Marwin: Where is your answer? Would be interested.Elder
@Elder See the answer below mine gradle -p other helloBelda
U
63

All of the ways mentioned by Mark can be used but all of them have some cons. So I am adding one more option:

4. Switching the current project

gradle -p other hello

This switches the "current project" and then runs all tasks named hello under the current project.

Udall answered 27/4, 2016 at 14:8 Comment(1)
Needs to be noted that this literally switches the working directory to 'other'. Therefor, this fails when there's no 'other/build.gradle' file (we use "subprojects {...}" from the parent directory to configure the child projects). That's why I recommend the other answer and the use of "gradle:taskName" instead.Hiltner
T
2

Example 5. Defining common behavior of all projects and subprojects,

allprojects {
    task hello {
        doLast { task ->
            println "I'm $task.project.name"
        }
    }
}
subprojects {
    hello {
        doLast {
            println "- I depend on water"
        }
    }
}

From the Gradle documentation, https://docs.gradle.org/current/userguide/multi_project_builds.html

Tintinnabulum answered 2/12, 2019 at 5:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.