gruntjs/grunt

Add pre-execution and post-execution "hooks"

jakub-g opened this issue · 10 comments

Hello,

I have an idea of adding some way to define hooks that will be executed before Grunt starts and after it finishes.

Now I can achieve this by creating a task, say gruntBeforeStart and gruntAfterEnd and then use grunt.registerTask('fooHooked', 'gruntBeforeStart foo gruntAfterEnd') but you can see it's not very handy and doesn't scale.

I can think of adding a "magic" tasks -- empty by default -- which will be always executed, regardless of the way Grunt is invoked. The main rationale is to invoke Grunt with any set of tasks I like from the command line, and have the hooks take place as well -- without the need to list them explicitly.

Usage example: timer to execute the whole build time, number of files processed, whatever.

Looking forward to your comments.

It will be really useful to have hooks. I am trying to run some code using data I collected in a multitask after the multitask finishes. Right now there is no easy way

We've talked about adding setup/teardown methods for multi tasks, this is most likely something we'll address in 0.5.

Are those going to work like say, jasmine specs beforeEach and afterEach() ?

@cowboy setup/teardown for multi tasks are also a neat idea. However I still think that "global" hooks before/after all of the targets of a multitask and/or the whole Grunt execution will be useful.

Edge use case : let's say I run some task with targets out of order: baz foo:t1 bar foo:t2 foo:t3 and I want to display some collective stats from all targets of foo (i.e. t1 and t2, t3) at the end (only once, not after each target). It will be good if it worked out of the box also when you run Grunt and pass the tasks & targets from the command line like I wrote.

I agree and to add to that it would be cool to be able to pass data to the next task

@jakub-g in your example, who defines the gruntAfterEnd behavior for the foo task? You, in the Gruntfile, or the task author in the task itself?

@chchrist what data would you pass? Would you pass it to the next multi task target, or the next completely separate task? What's your use case?

@cowboy To the next completely separate task. That way if for example did in a previous task grunt.file.recurse and I need the same file list in the next task, I don't need to iterate again. To be more specific. I have developed a task that finds if your app has missing jasmine spec files in order to prevent code to be untested. Then I wanted to get that list, create the missing specs based on a template and populate my Specrunner.html. It is realy hard now to do that with a multitask.

In 0.5 we're going to be emitting events to facilitate this sort of thing. If you want to see the direction we're headed, check out:
http://github.com/tkellen/node-task

If you need to persist data across tasks, check out our recommendation (under Storing task files) here:
https://github.com/gruntjs/grunt/wiki/Creating-plugins

try https://github.com/kingback/grunt-task-hooker

require('grunt-task-hooker')(grunt);

grunt.hookTask('build', 'before build', ['clean:dist']);
grunt.hookTask('build', 'before build', ['clean:dist'], true);