On Sep 1, 2008, at 12:44 PM, Adam Murdoch wrote:
Hans Dockter wrote:
On Aug 30, 2008, at 7:10 AM, Adam Murdoch wrote:
So, I think we should, for the short term:
- Implement each report as a Task. We should also add a Report
interface to provide some generic config and meta-info.
- Split a JunitReport task out of the Test task
- Add a way to declare that a task must be included in the
execution graph if a given other task (or matching set of tasks)
is included in the execution graph.
Here is how I understand this requirement:
With the current dependsOn declaration we can only define
prerequisites of a task. Something I have always liked were the
postGoal's of Maven 1. We could offer a method to a task like
'postRequisite' which takes tasks as an argument. This tasks need
to be executed after the source task has been executed.
Pretty much. It's a kind of like a finally handler for the source
task, which is itself a task. We could call these tasks finally
handler tasks, and the method doFinally(). Regardless of its name,
I think it should work like dependsOn() - you can use a task path
or Task object or collections of these things (and TaskActions? and
Closures?).
Another option is that you flip this around and attach the
dependency to the postrequisite task, using, say, a dependsOn()
with a condition, such that the dependency is included only when
the condition is met. In this case, the condition would be whether
the source task is scheduled to be executed.
I'd like to make the dependencies between tasks into real objects
with an interface (TaskDependency, say) which anyone can implement
to describe different types of dependencies. We would have some
standard implementations: prerequisite tasks, finally tasks, error
handler tasks, project dependencies, all tasks which generate
reports, all tasks which match a closure, all tasks in the same
project, all tasks with a given name in all subprojects ... you get
the idea. Not sure how this interface would look yet.
Introducing a task dependency is I think a very good idea.
The question is how to fit this into a directed acyclic graph. My
rough idea is to create dependsOn relations from the postRequisite
tasks to the source task. If the build is started with: 'gradle
sourceTask' we need to translate this into an execution of the
postRequisite tasks. If a task has postRequisite its name is
rather an alias for the postRequisite tasks.
I think all of the above stuff boils down to 3 primitive
dependencies between tasks:
1) taskA should execute if taskB successfully executes
2) taskA should execute if taskB executes and fails
3) taskA should execute if taskB executes at all, regardless of
success or failure
Building the DAG would involve converting from TaskDependency
objects to the above primitives (somehow).
May be I'm missing something. But I think the domain is more
complicated then that (leaving aside conditional tasks). Let's look
at test, testCompile and testReport. How would the relationship
between test and testCompile be modeled with the above? If I execute
testCompile, I don't want test to be executed.
gradle testCompile // should execute only testCompile
gradle test // should execute testCompile before and testReport after
gradle testReport // should execute test before. In this case this is
equivalent to 'gradle test'. But it is a possible operation.
One way to solve this would be to have only one primitive dependency
in a DAG, which is dependsOn (as it is now).
test dependsOn testCompile
testReport dependsOn test
Additionally we have to modify our execution logic. Instead of
executing a task, we execute its finally tasks. They have a dependsOn
relation to its source task. This means the source task is executed
first and afterwards the finally tasks. Only if there are no finally
task, the task is executed directly.
- Hans
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email