Is it possible to execute multiple tasks atomically regarding other tasks?


(Attila Kelemen) #1

I will give you an example to explain my problem:

When releasing, I want to commit each project’s api doc to a git repository but each of them to a different branch. So commiting one goes like this:

  1. Checkout branch named like the project. 2. Removed the “api” directory from the repository. 3. Recreate an empty “api” directory and copy the generated javadocs into this “api” folder. 4. Stage and commit the changes.

It would have been nice to do these in 4 different tasks but I could not do this safely because Gradle might decide that it first executes the “checkout” tasks of each project then proceeds which is of course not what I want. If this atomicity is not possible, what is the best way to solve this problem?

ps.: Minor issue in the forum: I came here from http://forums.gradle.org/gradle and my “one sentence question” was put into the “Post” field rather than the “Title”.


#2

Is there any reason you need to can’t use a different directory name for each checkout? Then it wouldn’t matter what order the tasks run.


(Attila Kelemen) #3

I do it this way because Github allows to download the current state of a branch as a single zip file. So if I want to download only one of the docs, I can do so. Besides, it is already this way, I do not really want to change, so that links to them remain valid.

Also, separate directories wouldn’t solve problems automatically because I still need to stage and commit and I prefer to do this consistently. That is, either commit them in one go or separate commit for each directory added.


(Attila Kelemen) #4

What I think of is something like a task which is an aggregation of multiple tasks. Though in this case an additional option is needed: a property for a task which means that no other task is to be run concurrently with it.

An aggregation of tasks would be benefical anyway, so that I could easily create tasks like “rebuild” (defined as the aggregation of “clean” and “build”).


#5

If you really need atomicity for your execution, then perhaps Gradle tasks are not the right way to model these actions. Gradle structures tasks in a dependency graph, and only guarantees that the dependent tasks will be executed before the depending ones. No other ordering guarantees are made.

In your case, you could easily extract each piece of functionality into a separate method, without needing them to be separate tasks.


(Attila Kelemen) #6

The above mentioned four tasks are simple enough to implement in one task. I just wanted to reuse the Copy and Delete tasks of Gradle so that I don’t need to add Apache Commons IO to the dependencies of the script.

I just realized that even though I have implemented it in one task, atomicity would still be required because if Gradle were to execute tasks concurrently and two such tasks were to execute concurrently then one of them is bound to fail.

I mean atomicity this way: Given a valid serial execution order of the tasks and an atomic task named AtomicTask, Gradle would assume that AtomicTask depends on each task executed before (in the previously mentioned execution order) and each task depends on AtomicTask executed after AtomicTask. So this would naturally enforce the atomicity, I would like.