On 22/03/2013, at 12:32 PM, Marcin Erdmann <marcin.erdm...@proxerd.pl> wrote:
> I'm about to start working on finalising tasks. Following are my initial > thoughts about how I currently see the implementation: > > - the relationship between tasks is specified on the finalised task, like > Adam suggested: > > tasks.withType(Reporting) { > finalisedBy(buildDashboardTask) > } > > plus all the other flavours of it just like for dependsOn and mustRunAfter > > - the relationship has to be stored on both the finalised task (to be able to > add the finialising task to the graph when the finalised task is being added) > and on the finalising task (to be able to use that info when verifying that > at least one of the tasks it finalises has been executed and the finalising > task is not otherwise required to be executed). > - a new TaskExecutionState or a flag on TaskInfo has to be added to > differentiate between a state where a task is a finaliser and is otherwise > not required to be executed, so that it can be skipped when the finalised > task(s) did not run for whatever reason as described in the design spec: > https://github.com/gradle/gradle/blob/master/design-docs/reporting.md#implementation-approach-2 > - a new TaskExecuter that would skip execution of a finalising task if none > of the finalised tasks run and the finalising task is otherwise not required > to be executed - that information can only be obtained from TaskInfo so it > would now need to be passed to TaskExecuter.execute() I think it might be better to keep this knowledge in TaskInfo. More on this below. > - I have no idea on how to achieve skipping dependencies of a finalising task > when the finalising task should be skipped - it gets really tricky as those > dependencies might be made mandatory by making the finalising task mandatory > after being added to the graph… Add them all as finalisers of the target task when you're traversing the graph down from a finaliser task - that is, a dependency of a finaliser of task A is itself a finaliser of A. > - Modify DefaultTaskExecutionPlan to go into "finaliser task mode only" after > a task failure not handled by failureHandler; if in that mode then > getNextReadyAndMatching() would use a Spec that only allows finaliser tasks, > and (I don't know how to achieve that) finaliser task dependencies I would split the `ready` state into several: `should run` and `must run` and `should not run`. The entry tasks and any task with an incoming hard dependency will be in `should run`. A finaliser task starts off as `should not run` and is switched to `must run` once any of the tasks that it finalises is executed. Before the first failure, the execution plan runs tasks in `should run` and `must run` state. Following a failure, it runs only tasks in `must run` state and continues until there are no such tasks left. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: http://www.gradlesummit.com