Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define task order without dependency in Gradle?

Tags:

gradle

Question

Can I somehow make sure that a task will be executed before/after another task, when both of them are to be executed? I don't want to add a dependency between them that's always there.

Background

I have two tasks, one that starts a server and one that runs tests against it. The task that starts that server runs it in a new process, so I can run gradle startServer runServerTests. Since it takes some time to start the server, it must be possible to start a server with one gradle process and then run the tests several times with another gradle process.

Now I'm trying to create a single task that does all that our CI environment does, which includes starting a server and running the server tests. I obviously want to make sure that the server is started before running the tests, but so far I'm out of luck.

Attempts

My first attempt is below, but that does not work since the order of the defined dependencies is not guaranteed:

task doItAll(dependsOn: [startServer, runServerTests]) { ... }

My second attempt, calling the tasks in actions does not work and is not supported:

task doItAll() << {
  tasks.startServer.execute()
  tasks.runServerTests.execute()
}

Solutions are on the roadmap (GRADLE-294, Initializer/Finalizer), but that doesn't help me now.

like image 211
David Pärsson Avatar asked Mar 06 '13 15:03

David Pärsson


3 Answers

It probably won't help you much at the moment, but but I have submitted a pull request in this area recently and it was hinted that it should make it into 1.6 (they are currently releasing 1.5 and the PR didn't make it into that release) - see the discussion here . Your best bet is to wait for the pull request to be merged into master after 1.5 release and then grab the first available nightly build from here.

EDIT

Gradle 1.6 has been released some time ago and now you can simply use mustRunAfter to achieve that. See the section on task ordering in Gradle manual for details.

like image 200
erdi Avatar answered Sep 22 '22 14:09

erdi


The gradle Task enhancements finalizedBy and mustRunAfter go some way to solving these issues. However, like the OP I had a need to change the dependencies and finalization based on the tasks requested, not statically defined.

I wanted gradle integrationTest to execute startup, runTests and finalized by shutdown. I also wanted startup, runTests and shutdown to be able to be run independently - without any dependencies or finalization.

You could statically create wrapper tasks that could express this, however it didn't scale well as the number and complexity of startup and shutdown tasks increased - and relied on anyone adding more tasks to add and maintain the required wrappers.

More elegant I found was to implement integrationTests as a task rule.

tasks.addRule('integrationTest: Full execution of integration tests with setup, startup,  shutdown and clean up') { String taskName ->
    if (taskName.equals('integrationTest')) {
        task(dependsOn: [runTests], taskName)

        // Add ordering and finalization for integration test runs        
        runTests.dependsOn startup
        startup.finalizedBy shutdown

        ... // and many other setup and shutdown tasks you want in the task DAG when running an integration test
    }
}
like image 43
sprynter Avatar answered Sep 20 '22 14:09

sprynter


http://issues.gradle.org/browse/GRADLE-294 was resolved 1st May (Gradle 1.6) and now gives you a way to describe that task B should run before A, if both are present when using a mustRunAfter() relationship between tasks.

I therefore think your question is fully answered.

like image 38
user2427436 Avatar answered Sep 22 '22 14:09

user2427436