On 17/02/13 22:30, Adam Murdoch wrote:
On 12/02/2013, at 6:31 AM, Marcin Erdmann wrote:
On 29/01/13 07:44, Adam Murdoch wrote:
Implementation-wise, I would think about busting up building the
task graph into 2 steps:
1. Build the task graph proper, with a node for each task in the
graph and edges to represent the various types of dependencies.
2. Once the graph is built, calculate the execution plan:
- Take each node that has no incoming edges, sort them and then
traverse each in turn.
- To traverse a node
- Take each soft dependency, sort them and traverse each in turn.
- Take each hard dependency, sort them and traverse each in turn.
I think I have already found an issue with the solution I proposed in
my previous email.
Currently it is valid to add a new task to the execution graph from
within gradle.taskGraph.whenReady{} which means that we should
probably indeed build a graph and determine executionPlan every
single time TaskExecutionPlan.addToTaskGraph() is called not to break
that contract. Looks like I'll need to work on building the graph in
the end.
TaskExecutionPlan is internal and there's no public API for adding
tasks to the graph. Once gradle.taskGraph.whenReady {} has been
called, addToTaskGraph() is never called. You don't need to support
adding more tasks after firing the event, if it makes things easier to
implement.
After having a look at it last week I think it's actually easier not to
change the API of TaskExecutionPlan to have to call a new method when
you want to determine executionPlan. It will save me changing all the
callers of addToTaskGraph if the executionPlan is still determined as a
part of addToTaskGraph implementation. And since I have already
implemented building the graph I will leave it as is.