On 7/04/10 12:06 AM, Hans Dockter wrote:
On Mon, Apr 5, 2010 at 5:17 AM, Geronimo M. H. <[email protected]
<mailto:[email protected]>> wrote:
Am Sunday 04 April 2010 23:44:10 schrieb Adam Murdoch:
> On 3/04/10 3:55 AM, Spencer Allain wrote:
> > The "<<" form is confusing enough. Having the first hello world
> > example state that it's equivalent to doFirst will only lead
to later
> > confusion once a user learns about doFirst and doLast.
>
> I think we should look at deprecating the '<<' form after the
Gradle 0.9
> release. And possibly doFirst() and doLast() too, so that a task has
> only 1 action.
I vote against reducing the number of (possible) task-actions and
against the
removal of doFirst() and doLast().
I don't know, whether I understand things right, I stored (in my
mind) the
behaviour of task definitions that
task {
action
}
is run during configuration stage, and could be used to configure
an existing
task (with the same name), whereas the task definition of
task << {
action
}
is a "real" task definition, which runs at execution stage and
will fail, if a
task of the same name already exists.
I very appreciate both - doFirst() and doLast() - to extend an already
existing task. I beleive, that extending existing tasks with an
userdefined
action is easier to understand or implement, than breaking up an
existing
task-dependency graph and adding a completely new task at the
right point.
We don't intend to simply deprecate doFirst or doLast. If we deprecate
them, they will be supported for quite a while. We don't want to break
every Gradle build on the planet.
There are strong use case for doFirst or doLast which couldn't
currently be modeled otherwise. Obviously there is no way do model a
doLast. For example you want to add a doLast action that does some
coverage reporting after test execution. You can't model that with
dependsOn relations. You would need to offer a testCoverage task for
that that dependsOn task. But if you want coverage to happen after the
execution of test, doLast is your only chance.
There are similar special scenarios for do first. A doFirst action can
rely on that each dependsOn task is executed. If you would model
doFirst with dependsOn that would no longer be the case.
Having said all that it is clear that doFirst and doLast points to
something we need and which goes beyond standard dependency base
programming. But doFirst and doLast have their flaws.
- They form a list which is a bit simplistic.
- They are unnamed black boxes (e.g. closure) with no api, thus
unwieldy to customize and manipulate.
When Adam talked about deprecating he meant replacing them with
something better. We are thinking about introducing new kind of tasks
which we call initializers and finalizers to model the above
scenarios. We provided enough syntactic sugar to make them as
convenient to use as actions. But they can depend on each other, can
be shared, etc ...
Task actions might live on too, outside the core.
For example, we might add an ActionTask which has doFirst() and doLast()
methods and maintains a list of actions. It would also be possible, if
we wanted, to add a plugin which adds the doFirst()/doLast() methods to
every task, so you can keep using actions if you like.
The key here is that the core becomes simpler, and you can opt-in to the
task action concept if you like, by applying the plugin to your projects.
--
Adam Murdoch
Gradle Developer
http://www.gradle.org