5 * Copyright (c) 2016 "Cowboy" Ben Alman, contributors
6 * Licensed under the MIT license.
11 module.exports = function(grunt) {
13 // Create a TaskRun on a target
14 function TaskRun(target) {
15 this.name = target.name || 0;
16 this.files = target.files || [];
17 this._getConfig = target._getConfig;
18 this.options = target.options;
19 this.startedAt = false;
21 this.changedFiles = Object.create(null);
22 this.spawnTaskFailure = false;
23 this.livereloadOnError = true;
24 if (typeof this.options.livereloadOnError !== 'undefined') {
25 this.livereloadOnError = this.options.livereloadOnError;
29 var getErrorCount = function() {
30 if (typeof grunt.fail.forever_warncount !== 'undefined') {
31 return grunt.fail.forever_warncount + grunt.fail.forever_errorcount;
33 return grunt.fail.warncount + grunt.fail.errorcount;
38 TaskRun.prototype.run = function(done) {
41 // Dont run if already running
42 if (self.startedAt !== false) {
46 // Start this task run
47 self.startedAt = Date.now();
49 // reset before each run
50 self.spawnTaskFailure = false;
51 self.errorsAndWarningsCount = getErrorCount();
53 // pull the tasks here in case they were changed by a watch event listener
54 self.tasks = self._getConfig('tasks') || [];
55 if (typeof self.tasks === 'string') {
56 self.tasks = [self.tasks];
59 // If no tasks just call done to trigger potential livereload
60 if (self.tasks.length < 1) {
64 if (self.options.spawn === false || self.options.nospawn === true) {
65 grunt.task.run(self.tasks);
68 self.spawned = grunt.util.spawn({
69 // Spawn with the grunt bin
71 // Run from current working dir and inherit stdio from process
73 cwd: self.options.cwd.spawn,
76 // Run grunt this process uses, append the task to be run and any cli options
77 args: self.tasks.concat(self.options.cliArgs || [])
78 }, function(err, res, code) {
79 self.spawnTaskFailure = (code !== 0);
80 if (self.options.interrupt !== true || (code !== 130 && code !== 1)) {
89 // When the task run has completed
90 TaskRun.prototype.complete = function() {
91 var time = Date.now() - this.startedAt;
92 this.startedAt = false;
94 this.spawned.kill('SIGINT');
98 var taskFailed = this.spawnTaskFailure || (getErrorCount() > this.errorsAndWarningsCount);
99 this.errorsAndWarningsCount = getErrorCount();
101 // Trigger livereload if necessary
102 if (this.livereload && (this.livereloadOnError || !taskFailed)) {
103 this.livereload.trigger(Object.keys(this.changedFiles));
104 this.changedFiles = Object.create(null);