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.
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.
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.
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.
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
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With