Hans Dockter wrote:
I have just committed a fix for Gradle-220 (Provide control to the user if and how project dependencies should be rebuild).

With -a or --no-rebuild you can now disable that project dependencies are build at all. Of course this works only if the project dependencies have been build before and are accessible in the ./gradle/internal-repository cache.


Should -a ignore all dependencies on tasks in different projects, regardless of how they were added? Currently, it only ignores dependencies added using a project dependency in a configuration. That is, should it also ignore the dependency declared in:

task myTask(dependsOn: ':anotherProject:someTask')

Also, when you run with -a, should we still build those artifacts which have not already been built?

With gradle -Ajavadoc -Atest you can specify additional tasks that should be run when building project dependencies.

I don't understand why you would want to do this from the command-line. Do you have some use cases?

For 0.7 we plan to make our command line smarter and more expressive. Jon Cox and Steve Appling have made very interesting proposals. So this syntax is likely to change with 0.7. It is pretty basic anyhow and does not allow for fine-grained control. But it solves the most urgent pain.

I have run into one rather fundamental issue. Task dependencies are not ordered. They are not a LinkedHashSet or a List.


I feel pretty strongly that ordering of task dependencies is the wrong way to go.

I have 2 main objections. Firstly, it really muddies the semantics of the dependency graph. By ordering the edges, it stops being a DAG, and becomes something else. It becomes unclear what it is and what it means.

Consider:

task a
task b
task c(dependsOn: b,a)

Why should task c have anything to say about the relationship between tasks a and b, and how they should be ordered? If b really needs to happen before a, then why is this not declared on b or a?

It becomes worse if you add a few indirections:

task a
task b
task c(dependsOn: b,a)
task d(dependsOn: a,c)
task e(dependsOn: c,d)

which of the above incompatible orderings do we choose? do we fail the build? what if a,b and c are in a plugin outside our control? How does a human understand what will happen here?

My second objection is that task ordering is, in practice, almost always lossy. That is, there's something missing from the model to express the actual reason why a particular task needs to be completed before another one can start. Ordered dependencies are a poor approximation of this.

We should, instead, identify what it is that's missing from the model, and add it in.

With Gradle-220 I have the following use case: Let's say you want that project-dependencies are build with a clean:

Project A (has a compile dependency on Project B)
gradle -Aclean compile

The problem is that clean is not necessarily executed as the first task when building B. Which of course leads to a failing build. For other tasks (e.g. javadoc) this is not an issue, as it has no side-effects.

I'm wondering what to do here. This also relates to:


I think you should flip the problem around. The -a option works well, I think, because the build describes completely how to build the project, and -a simply takes some stuff out. The problem with -A is that it is trying to add stuff in. It's much more difficult to add things in, which is why we have a DSL and build scripts.

So, a solution to the problem is to change the clean task to always clean the projects which the project depends on. Then, you can simply use -a if you don't want the other projects to be cleaned. And -A and task ordering is not required.

So,

gradle clean libs

will rebuild the current project and all the projects it depends on.

gradle -a clean libs

will rebuild only the current project.

And for anything more exotic, we can add in the ! notation.


Adam


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to