On May 6, 2009, at 11:38 PM, Adam Murdoch wrote:
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')
The use case I have in mind is artifact oriented.
Also, when you run with -a, should we still build those artifacts
which have not already been built?
I think that would be nice (although I'm wondering a little bit if
this could lead to overly smartness).
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?
When we change our lifecycle to make the jar not depend on test any
longer, uploading to the internal repository might not trigger a test.
You might want to have a special partial build that runs the tests. Or
you want to have an additional clean because you want a very reliable
partial build. I'm not saying that this is the only way to achieve
this. But those are the use cases within the current way of doing
things.
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.
I agree. I also like the conceptual purity of our set based DAG.
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?
I think there is a type of relationship that can't be modeled with
dependsOn. If b is clean and a is compile: b is not a prerequisite of
a. But if both are executed, then b should be executed before 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?
Gradle will be the first build system for Vulcans ;). You are right.
It does not make sense.
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.
I agree.
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.
One problem is that the tasks you apply to the current project is most
of the time a different set than the task set you need to build the
project dependencies. So there is at least the theoretical possibility
that a user wants to manipulate only the set of tasks for building the
project dependencies. I'm not sure about the practical relevance for
that but it does not look extremely exotic. You might argue, whether
this should really be solved on the command line. I'm not sure.
What you are proposing is similar to what we did in an early version
of Gradle. What we did was to always establish an additional
project1.dependsOn project2 for a artifact project dependency (e.g.
compile project('project2')). We might reintroduce this, together with
the !notation. I need to further think about this. This feature would
not be mutually exclusive to the one above. But it might be good enough.
The project dependencies issue will lose some its relevance once
Gradle becomes smart in regard to change detection.
We are still left with the more fundamental issue, if there is
something missing in our model where an ordered dependsOn set is a bad
solution for. I have to think about that.
- Hans
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
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email