taskrun.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * grunt-contrib-watch
  3. * http://gruntjs.com/
  4. *
  5. * Copyright (c) 2014 "Cowboy" Ben Alman, contributors
  6. * Licensed under the MIT license.
  7. */
  8. 'use strict';
  9. var path = require('path');
  10. var EE = require('events').EventEmitter;
  11. var util = require('util');
  12. module.exports = function(grunt) {
  13. var livereload = require('./livereload')(grunt);
  14. // Create a TaskRun on a target
  15. function TaskRun(target) {
  16. this.name = target.name || 0;
  17. this.files = target.files || [];
  18. this._getConfig = target._getConfig;
  19. this.options = target.options;
  20. this.startedAt = false;
  21. this.spawned = null;
  22. this.changedFiles = Object.create(null);
  23. this.spawnTaskFailure = false;
  24. this.livereloadOnError = true;
  25. if (typeof this.options.livereloadOnError !== 'undefined') {
  26. this.livereloadOnError = this.options.livereloadOnError;
  27. }
  28. }
  29. var getErrorCount = function(){
  30. if (typeof grunt.fail.forever_warncount !== 'undefined') {
  31. return grunt.fail.forever_warncount + grunt.fail.forever_errorcount;
  32. } else {
  33. return grunt.fail.warncount + grunt.fail.errorcount;
  34. }
  35. };
  36. // Run it
  37. TaskRun.prototype.run = function(done) {
  38. var self = this;
  39. // Dont run if already running
  40. if (self.startedAt !== false) { return; }
  41. // Start this task run
  42. self.startedAt = Date.now();
  43. // reset before each run
  44. self.spawnTaskFailure = false;
  45. self.errorsAndWarningsCount = getErrorCount();
  46. // pull the tasks here in case they were changed by a watch event listener
  47. self.tasks = self._getConfig('tasks') || [];
  48. if (typeof self.tasks === 'string') {
  49. self.tasks = [self.tasks];
  50. }
  51. // If no tasks just call done to trigger potential livereload
  52. if (self.tasks.length < 1) { return done(); }
  53. if (self.options.spawn === false || self.options.nospawn === true) {
  54. grunt.task.run(self.tasks);
  55. done();
  56. } else {
  57. self.spawned = grunt.util.spawn({
  58. // Spawn with the grunt bin
  59. grunt: true,
  60. // Run from current working dir and inherit stdio from process
  61. opts: {
  62. cwd: self.options.cwd.spawn,
  63. stdio: 'inherit',
  64. },
  65. // Run grunt this process uses, append the task to be run and any cli options
  66. args: self.tasks.concat(self.options.cliArgs || []),
  67. }, function(err, res, code) {
  68. self.spawnTaskFailure = (code !== 0);
  69. if (self.options.interrupt !== true || (code !== 130 && code !== 1)) {
  70. // Spawn is done
  71. self.spawned = null;
  72. done();
  73. }
  74. });
  75. }
  76. };
  77. // When the task run has completed
  78. TaskRun.prototype.complete = function() {
  79. var time = Date.now() - this.startedAt;
  80. this.startedAt = false;
  81. if (this.spawned) {
  82. this.spawned.kill('SIGINT');
  83. this.spawned = null;
  84. }
  85. var taskFailed = this.spawnTaskFailure || (getErrorCount() > this.errorsAndWarningsCount);
  86. this.errorsAndWarningsCount = getErrorCount();
  87. // Trigger livereload if necessary
  88. if (this.livereload && (this.livereloadOnError || !taskFailed)) {
  89. this.livereload.trigger(Object.keys(this.changedFiles));
  90. this.changedFiles = Object.create(null);
  91. }
  92. return time;
  93. };
  94. return TaskRun;
  95. };