diff --git a/CHANGELOG b/CHANGELOG index e38e2dd0..92d59e1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v0.4.4: + date: 2014-04-12 + changes: + - Only signal completion of tasks async if grunt.task.start is invoked with `{asyncDone:true}`. v0.4.3: date: 2014-03-07 changes: diff --git a/lib/grunt.js b/lib/grunt.js index 297c6c53..0ea8909d 100644 --- a/lib/grunt.js +++ b/lib/grunt.js @@ -156,5 +156,7 @@ grunt.tasks = function(tasks, options, done) { // Execute all tasks, in order. Passing each task individually in a forEach // allows the error callback to execute multiple times. tasks.forEach(function(name) { task.run(name); }); - task.start(); + // Run tasks async internally to reduce call-stack, per: + // https://github.com/gruntjs/grunt/pull/1026 + task.start({asyncDone:true}); }; diff --git a/lib/util/task.js b/lib/util/task.js index 17e5f7b8..4944b200 100644 --- a/lib/util/task.js +++ b/lib/util/task.js @@ -188,7 +188,7 @@ }; // Run a task function, handling this.async / return value. - Task.prototype.runTaskFn = function(context, fn, done) { + Task.prototype.runTaskFn = function(context, fn, done, asyncDone) { // Async flag. var async = false; @@ -215,9 +215,15 @@ if (!success && this._options.error) { this._options.error.call({name: context.name, nameArgs: context.nameArgs}, err); } - process.nextTick(function () { + // only call done async if explicitly requested to + // see: https://github.com/gruntjs/grunt/pull/1026 + if (asyncDone) { + process.nextTick(function () { + done(err, success); + }); + } else { done(err, success); - }); + } }.bind(this); // When called, sets the async flag and returns a function that can @@ -248,7 +254,10 @@ }; // Begin task queue processing. Ie. run all tasks. - Task.prototype.start = function() { + Task.prototype.start = function(opts) { + if (!opts) { + opts = {}; + } // Abort if already running. if (this._running) { return false; } // Actually process the next task. @@ -285,7 +294,7 @@ // Actually run the task function (handling this.async, etc) this.runTaskFn(context, function() { return thing.task.fn.apply(this, this.args); - }, nextTask); + }, nextTask, !!opts.asyncDone); }.bind(this);