Rade Milovic
Rade Milovic

Reputation: 1015

How to make Gradle run tasks in certain order?

Let's say that I have created separate tasks for running integration and acceptance tests in my gradle build script. When I run the build task I want to run testing tasks before in this order: unit tests(test task), integration tests (intergationTest task) and acceptance tests (acceptanceTest task). Is this possible and how?

Upvotes: 4

Views: 23415

Answers (6)

Frederic Leitenberger
Frederic Leitenberger

Reputation: 2019

UPDATE: While using this "solution" for a short while i found out, that it does not work 100% as intended. I don't know why though. Any help to make it work would be appreciated. Maybe it does not work properly when there is more than one task in the Set?! While testing i did add some dummy-Tasks which only printed a text inbetween each of the other tasks and all seemed to be ok.


After some attempts with other solutions i came up with this solution:
It uses the mustRunAfter command to chain Sets of Tasks into the required order.

I'm working with Sets instead of individual Tasks, because i got circular dependency issues otherwise, since some tasks already depended on each other.

Also important to note: the isNotEmpty() check was essential, as it would otherwise break the enforced ordering if an ampty set was passed to the method.

tasks.register("cleanAndGenerate") {
    var lastTasks: Set<Task> = setOf()

    fun findTasks(taskName: String): Set<Task> {
        return if (taskName.startsWith(":")) { // task in specific sub-project
            setOf(tasks.findByPath(taskName)!!)
        } else { // tasks in all (sub-)projects
            getTasksByName(taskName, true)
        }
    }

    fun dependsOnSequential(taskName: String) {
        val tasks = findTasks(taskName)
        tasks.forEach { task -> task.mustRunAfter(lastTasks) }
        dependsOn(tasks)
        if (tasks.isNotEmpty()) {
            lastTasks = tasks
        }
    }

    dependsOnSequential(":project1:clean") // task in specific sub-project
    dependsOnSequential(":project2:clean")
    dependsOnSequential("task1") // tasks in all (sub-)projects
    dependsOnSequential("task2")
    // add more as needed
}

Upvotes: 0

Prafulla Girgaonkar
Prafulla Girgaonkar

Reputation: 29

The first answer in the list turned out to be great for me. I used

X.shouldRunAfter Y

Upvotes: 0

Topera
Topera

Reputation: 12389

I created this helper method based on a solution that I found on Gradle forum.

Task.metaClass.runFirst = { Task... others ->
    delegate.dependsOn(others)
    delegate.mustRunAfter(others[0])
    for (def i=0; i < others.size() - 1; i++) {
        def before = others[i]
        def after = others[i+1]
        after.mustRunAfter(before)
    }
}

Then you can create tasks X, A, B and C and use like this:

X.runFirst A, B, C

Upvotes: 1

sancho21
sancho21

Reputation: 3643

This is what I did on my projects.

check.dependsOn integTest
integTest.mustRunAfter test
tasks.withType(Pmd) {
  mustRunAfter integTest // Pointing to a task
}
tasks.withType(FindBugs) {
  mustRunAfter tasks.withType(Pmd) // Pointing to a group of tasks under Pmd
}
tasks.withType(Checkstyle) {
  mustRunAfter tasks.withType(FindBugs)
}

It helped me to order tasks by group.

Upvotes: 1

Lance
Lance

Reputation: 752

Here's how you can do it without creating artificial dependencies:

https://caffeineinduced.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/

TLDR; version:

//--- build aliases : define a synonym here if you want a shortcut to run multiple targets

def buildAliases = [
   'all' : ['clean', 'assemble', 'runProvisioner', 'stopTomcat', 'installTomcat', 'deployToTomcat', 'startTomcat'],
   'rebuild' : ['clean', 'assemble']
]
def expandedTaskList = []

gradle.startParameter.taskNames.each {
    expandedTaskList << (buildAliases[it] ? buildAliases[it] : it)
}

gradle.startParameter.taskNames = expandedTaskList.flatten()

println "\n\n\texpanded task list: ${gradle.startParameter.taskNames }\n\n"

Upvotes: 2

Radim
Radim

Reputation: 4808

You are looking for "should run after" described in Gradle documentation - http://www.gradle.org/docs/current/userguide/more_about_tasks.html

Upvotes: 4

Related Questions