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

Reply via email to