There is clearly some confusion concerning task creation and addition to 
tasks.  Both task abc, task abc {}, and task abc << {} create a task, and both 
will complain if one already exists (let's ignore overwrite: true for the 
moment).

Consider the below definitions

task bob << { println '7' }
bob.doLast() { println '8' }
bob { println '1' }
bob { configure { println '2' } }
bob { doLast { println '9' } }
bob.doFirst { println '6' }
bob { println '3' ; doLast { println '10' } ; doFirst { println '5' } }
bob.configure { println '4' }

Running "gradle -q bob" gives you 1 .. 10 listed in order.  Running without the 
-q flag actually is helpful in showing where configuration occurs, and where 
execution occurs, as ":bob" will show up after "4" and before "5" in the output.

task abc << { action }  
            really is just shorthand for:
task abc { doLast { action } }

I actually need doFirst and doLast (and yes, it works with or without the 
parens, so doLast or doLast() is preference at this point), so I must vote to 
retain the ability to prepend and append at the execution phase.  I thought I'd 
require that ability during the configuration phase too, but so far that hasn't 
been true - at least yet :-)

All things not in any named closure or the configuration closure happen in the 
order they are defined during the configuration phase.

Then all doFirst closures happen in the reverse order they are defined during 
the execution phase.

Finally, all doLast closures happen in the order they are defined during the 
execution phase.

I believe that most of the confusion occurs because the "default" desired 
behavior is to have tasks that do something at execution time, but the 
non-short form happens at configuration time only.

It probably would be quite disruptive to the parsing I suspect (and existing 
scripts), but maybe the default behavior should be an implicit doLast, and to 
have things that absolutely need to happen at configuration time can use the 
configure closure.

Then the short form would simply be the "normal" form, and the "<<" is much 
less relevant, as it's usually only more advanced operations that might require 
much at configuration time:
task myTask { implicitDoLastRunAtExecTime }
task myTask { configure { runAtConfigTime } ; implicitDoLastRunAtExecTime }

-Spencer

--- On Sun, 4/4/10, Geronimo M. H. <[email protected]> wrote:
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.




      

Reply via email to