Thanks for the review Adam. Will get back after I'm done with applying the suggestions.

On 21/02/13 06:25, Adam Murdoch wrote:

On 20/02/2013, at 9:09 AM, Marcin Erdmann wrote:

You can checkout my efforts on the 'must run after' ordering over here: https://github.com/erdi/gradle/compare/always-runs-after.

Excellent stuff. Thanks for this. I've added a few comments to the commits.


Following is the list of what I did and some questions I have:
- Added void mustRunAfter(Task... tasks) to Task and implemented it in AbstractTask. Currently it only works with task in contrast to dependsOn which accepts all sorts of things (strings, buildables, etc) as this was enough to use it with build dashboard plugin. The question here is do we want to support more objects via mustRunAfte out of the boxr or should we only add support if a need for it is driven by new feature requirements?

I think I'd prefer to allow must-run-after dependencies to be lazy, like task dependencies. We can just use another TaskDependency instance to collect up the must-run-after tasks.

- DefaultTaskExecutionPlan now uses TaskDependencyGraph (not sure about the name as it seems a bit too generic) to determine the execution plan. Interface of the graph class was driven by how it's used in DefaultTaskExecutionPlan. As suggested by Adam in the first phase I'm building the graph with both dependency and 'must run after' edges and in the second phase I'm toposorting it. - I don't know how to provide a better exception message when there are no edges without incoming edges (https://github.com/erdi/gradle/blob/always-runs-after/subprojects/core/src/main/groovy/org/gradle/execution/taskgraph/DefaultTaskExecutionPlan.java#L99) in the task graph when determining execution plan - there clearly is a cycle then but it's hard to come up with which tasks are in the cycle. Any ideas?

I think we actually don't need to collect the nodes with no incoming edges. We can just start traversing at the tasks that were passed as parameters to addToTaskGraph(). This way, the cycle will be detected later on in the algorithm with some context (ie 2 of the tasks in the cycle).

We can then improve this. CachingDirectedGraphWalker actually has support for collecting up the nodes of a strongly connected component (ie the cycle). So, one option would be, when we hit a cycle, traverse the graph again using this and report which nodes are in the component. We could possibly just use CachingDirectedGraphWalker to do the toposort (this was the plan, just never got around to it).



- I decided to leave addToTaskGraph() contract as is because it is core functionality and any changes to it might introduce regressions in places I couldn't be aware of with my level of knowledge about the codebase. - I didn't directly test getters and setters on TaskDependencyGraphNode. I believe that it's not necessary as it's trivial code and it's indirectly tested via TaskDependencyGraphTest - correct me if I'm wrong.

We don't bother testing simple getters and setters.

- Apart from adding tests around mustRunAfter() in DefaultTaskExecutionPlanTest I have also refactored how the tasks are specified for tests in that class to make it easier to define both dependsOn and mustRunAfter. - buildDashboard tasks must now always run after any Reporting tasks apart from itself

I will of course add documentation and mark mustRunAfter() as incubating when you confirm that you are happy with the implementation.

Marcin

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

http://xircles.codehaus.org/manage_email




--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com


Reply via email to