1 | [Grunt homepage](https://github.com/cowboy/grunt) | [Documentation table of contents](toc.md)
|
2 |
|
3 | # Types of Tasks
|
4 |
|
5 | EXPLAIN BETTER
|
6 |
|
7 | Tasks are grunt's bread and butter. The stuff you do most often, like `concat` or `test`. Every time grunt is run, you specify one more more tasks, which tells grunt what you'd like it to do.
|
8 |
|
9 | _Note: if you don't specify a task, but a task named "default" has been defined, that task will run (unsurprisingly) by default._
|
10 |
|
11 | Tasks can be created in a few ways.
|
12 |
|
13 | ## Alias tasks
|
14 |
|
15 | ```javascript
|
16 | task.registerTask(taskName, [description, ] taskList);
|
17 | ```
|
18 |
|
19 | _Note that for alias tasks, the description is optional. If omitted, a useful description will be added for you automatically._
|
20 |
|
21 | In the following example, a `theworks` task is defined that, when invoked by `grunt theworks`, will execute the `lint`, `qunit`, `concat` and `min` tasks in-order. Running `grunt theworks` behaves exactly as if `grunt lint qunit concat min` was run on the command line.
|
22 |
|
23 | ```javascript
|
24 | task.registerTask('theworks', 'lint qunit concat min');
|
25 | ```
|
26 |
|
27 | In this example, a default task is defined that, when invoked by `grunt` or `grunt default`, will execute the `lint`, `qunit`, `concat` and `min` tasks in-order. It behaves exactly as if `grunt lint qunit concat min` was run on the command line.
|
28 |
|
29 | ```javascript
|
30 | task.registerTask('default', 'lint qunit concat min');
|
31 | ```
|
32 |
|
33 | _In case it's not obvious, defining a `default` task is helpful because it runs by default, whenever you run `grunt` without explicitly specifying tasks._
|
34 |
|
35 | ## Multi tasks
|
36 | A multi task is a task that implicitly iterates over all of its targets if no target is specified. For example, in the following, while `grunt lint:test` or `grunt lint:lib` will lint only those specific sets of files, `grunt lint` will automatically run the `test`, `lib` and `grunt` targets for you. It's super convenient.
|
37 |
|
38 | _Note: multi tasks will ignore any config sub-properties beginning with `_` (underscore)._
|
39 |
|
40 | ```javascript
|
41 | /*global config:true, task:true*/
|
42 | config.init({
|
43 | lint: {
|
44 | test: ['test/*.js'],
|
45 | lib: ['lib/*.js'],
|
46 | grunt: ['grunt.js']
|
47 | }
|
48 | });
|
49 | ```
|
50 |
|
51 | While it's probably most useful for you to check out the JavaScript source of the [built-in tasks](https://github.com/cowboy/grunt/tree/master/tasks), this example shows how you might define your own multi task:
|
52 |
|
53 | ```javascript
|
54 | /*global config:true, task:true*/
|
55 | config.init({
|
56 | logstuff: {
|
57 | foo: [1, 2, 3],
|
58 | bar: 'hello world',
|
59 | baz: false
|
60 | }
|
61 | });
|
62 |
|
63 | task.registerMultiTask('logstuff', 'This task logs stuff.', function(target) {
|
64 | // target === the name of the target
|
65 | // this.data === the target's value in the config object
|
66 | // this.name === the task name
|
67 | // this.args === an array of args specified after the target on the command-line
|
68 | // this.flags === a map of flags specified after the target on the command-line
|
69 | // this.file === file-specific .src and .dest properties
|
70 |
|
71 | // Log some stuff.
|
72 | log.writeln(target + ': ' + this.data);
|
73 |
|
74 | // If data was falsy, abort!!
|
75 | if (!this.data) { return false; }
|
76 | log.writeln('Logging stuff succeeded.');
|
77 | });
|
78 | ```
|
79 |
|
80 | Sample grunt output from running `logstuff` targets individually:
|
81 |
|
82 | ```
|
83 | $ grunt logstuff:foo
|
84 | Running "logstuff:foo" (logstuff) task
|
85 | foo: 1,2,3
|
86 | Logging stuff succeeded.
|
87 |
|
88 | Done, without errors.
|
89 |
|
90 | $ grunt logstuff:bar
|
91 | Running "logstuff:bar" (logstuff) task
|
92 | bar: hello world
|
93 | Logging stuff succeeded.
|
94 |
|
95 | Done, without errors.
|
96 |
|
97 | $ grunt logstuff:baz
|
98 | Running "logstuff:baz" (logstuff) task
|
99 | baz: false
|
100 | <WARN> Task "logstuff:baz" failed. Use --force to continue. </WARN>
|
101 |
|
102 | Aborted due to warnings.
|
103 | ```
|
104 |
|
105 | Sample grunt output from running `logstuff` task:
|
106 |
|
107 | ```
|
108 | $ grunt logstuff
|
109 | Running "logstuff:foo" (logstuff) task
|
110 | foo: 1,2,3
|
111 | Logging stuff succeeded.
|
112 |
|
113 | Running "logstuff:bar" (logstuff) task
|
114 | bar: hello world
|
115 | Logging stuff succeeded.
|
116 |
|
117 | Running "logstuff:baz" (logstuff) task
|
118 | baz: false
|
119 | <WARN> Task "logstuff:baz" failed. Use --force to continue. </WARN>
|
120 |
|
121 | Aborted due to warnings.
|
122 | ```
|
123 |
|
124 | ## Custom tasks
|
125 | You can go crazy with tasks. If your tasks don't follow the "multi task" structure, use a custom task.
|
126 |
|
127 | ```javascript
|
128 | task.registerTask('default', 'My "default" task description.', function() {
|
129 | log.writeln('Currently running the "default" task.');
|
130 | });
|
131 | ```
|
132 |
|
133 | Inside a task, you can run other tasks.
|
134 |
|
135 | ```javascript
|
136 | task.registerTask('foo', 'My "foo" task.', function() {
|
137 | // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
|
138 | task.run('bar baz');
|
139 | // Or:
|
140 | task.run(['bar', 'baz']);
|
141 | });
|
142 | ```
|
143 |
|
144 | Tasks can be asynchronous.
|
145 |
|
146 | ```javascript
|
147 | task.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
|
148 | // Force task into async mode and grab a handle to the "done" function.
|
149 | var done = this.async();
|
150 | // Run some sync stuff.
|
151 | log.writeln('Processing task...');
|
152 | // And some async stuff.
|
153 | setTimeout(function() {
|
154 | log.writeln('All done!');
|
155 | done();
|
156 | }, 1000);
|
157 | });
|
158 | ```
|
159 |
|
160 | Tasks can access their own name and arguments.
|
161 |
|
162 | ```javascript
|
163 | task.registerTask('foo', 'My "foo" task.', function(a, b) {
|
164 | log.writeln(this.name, a, b);
|
165 | });
|
166 |
|
167 | // Usage:
|
168 | // grunt foo foo:bar
|
169 | // logs: "foo", undefined, undefined
|
170 | // logs: "foo", "bar", undefined
|
171 | // grunt foo:bar:baz
|
172 | // logs: "foo", "bar", "baz"
|
173 | ```
|
174 |
|
175 | Tasks can fail if any errors were logged.
|
176 |
|
177 | ```javascript
|
178 | task.registerTask('foo', 'My "foo" task.', function() {
|
179 | if (failureOfSomeKind) {
|
180 | log.error('This is an error message.');
|
181 | }
|
182 |
|
183 | // Fail task if errors were logged.
|
184 | if (task.hadErrors()) { return false; }
|
185 |
|
186 | log.writeln('This is the success message');
|
187 | });
|
188 | ```
|
189 |
|
190 | When tasks fail, all subsequent tasks will be aborted unless `--force` was specified.
|
191 |
|
192 | ```javascript
|
193 | task.registerTask('foo', 'My "foo" task.', function() {
|
194 | // Fail synchronously.
|
195 | return false;
|
196 | });
|
197 |
|
198 | task.registerTask('bar', 'My "bar" task.', function() {
|
199 | var done = this.async();
|
200 | setTimeout(function() {
|
201 | // Fail asynchronously.
|
202 | done(false);
|
203 | }, 1000);
|
204 | });
|
205 | ```
|
206 |
|
207 | Tasks can be dependent on the successful execution of other tasks. Note that `task.requires` won't actually RUN the other task(s). It'll just check to see that it has run and not failed.
|
208 |
|
209 | ```javascript
|
210 | task.registerTask('foo', 'My "foo" task.', function() {
|
211 | return false;
|
212 | });
|
213 |
|
214 | task.registerTask('bar', 'My "bar" task.', function() {
|
215 | // Fail task if "foo" task failed or never ran.
|
216 | task.requires('foo');
|
217 | // This code executes if the "foo" task ran successfully.
|
218 | log.writeln('Hello, world.');
|
219 | });
|
220 |
|
221 | // Usage:
|
222 | // grunt foo bar
|
223 | // doesn't log, because foo failed.
|
224 | // grunt bar
|
225 | // doesn't log, because foo never ran.
|
226 | ```
|
227 |
|
228 | Tasks can fail if required configuration properties don't exist.
|
229 |
|
230 | ```javascript
|
231 | task.registerTask('foo', 'My "foo" task.', function() {
|
232 | // Fail task if "meta.name" config prop is missing.
|
233 | config.requires('meta.name');
|
234 | // Also fails if "meta.name" config prop is missing.
|
235 | config.requires(['meta', 'name']);
|
236 | // Log... conditionally.
|
237 | log.writeln('This will only log if meta.name is defined in the config.');
|
238 | });
|
239 | ```
|
240 |
|
241 | Tasks can access configuration properties.
|
242 |
|
243 | ```javascript
|
244 | task.registerTask('foo', 'My "foo" task.', function() {
|
245 | // Log the property value. Returns null if the property is undefined.
|
246 | log.writeln('The meta.name property is: ' + config('meta.name'));
|
247 | // Also logs the property value. Returns null if the property is undefined.
|
248 | log.writeln('The meta.name property is: ' + config(['meta', 'name']));
|
249 | });
|
250 | ```
|
251 |
|
252 | Take a look at the [built-in tasks](https://github.com/cowboy/grunt/tree/master/tasks) for more examples.
|