借用闭包，处理gulp的task中index
775432
function _createJSTask(gulp, name, config, depTasks, index, startFun, endFun) {
    gulp.task(name, depTasks, function(){
        var s = config.js[index];
       return runJSTaskStream(gulp, s, config, startFun, endFun);
    });
}
970403
function runAndWatch(watchPattern, initialValue, task) {
  gulp.watch(watchPattern, event => {
    task(event.path, event);
  });
  return task(initialValue);
}
652093
function taskList( arg, callback ){
    exec( taskListPath + arg, function( err, stdout ){
        callback( err, stdout )
    })
}
157920
function defineTaskGroups() {
  const gulpTasks = gulp.tree({ deep: false }).nodes
  const gulpMode = options.parallel ? gulp.parallel : gulp.series
  const groups = Object.keys(options.groups).map(key => [
    key.trim().replace(/[^a-z]+/gi, ''),
    options.groups[key]
  ])

  groups.forEach(group => {
    const [name, value] = group
    let children = []

    if (Array.isArray(value)) {
      children = value
    } else if (typeof value === 'function') {
      children = gulpTasks
        .filter(value)
        // Group tasks should not call themselves/other groups
        .filter(child => !groups.includes(child))
    } else {
      return
    }

    if (children.length === 0) {
      gulp.task(name, done => {
        handleError(new Error(`No tasks found in '${name}' group`))
        done()
      })
    } else {
      gulp.task(name, gulpMode.apply(null, children))
    }
  })
}
116687
function Devour(settings) {
	var devour = this,
		gulp = require('gulp'),
		glob = require('glob'),
		chalk = require('chalk'),
		submerge = require('submerge'),
		polymorphic = require('polymorphic'),
		Wanted = require('wanted'),
		chain = require('gulp-chain'),
		watcher = require('gulp-watch'),
		wanted = new Wanted(),
		definitions = {},
		run = process.argv.splice(2),
		config = submerge(settings, {
			debounce: 100,
			basePath: process.cwd(),
			gulpFiles: 'gulp',
			output: 'dist',
			verbose: !run.length
		}),
		active = [];

	/**
	 *  Initialize Devour
	 *  @name    init
	 *  @access  internal
	 *  @return  void
	 */
	function init() {
		Object.defineProperty(devour, 'gulp', {
			enumerable: true,
			value: gulp
		});

		preload();
	}

	/**
	 *  Load all available tasks and pipes
	 *  @name    preload
	 *  @access  internal
	 *  @return  void
	 */
	function preload() {
		var path = config.gulpFiles;

		if (/^[^\/]/.test(path)) {
			path = config.basePath + '/' + path;
		}

		glob.sync(path + '/*/*.js').map(function(file) {
			return file.replace(path, '').split('/').filter(function(split) {
				return !!split;
			});
		}).forEach(function(file) {
			register(
				file[0],
				file[file.length - 1].replace(/\.js$/, ''),
				require(path + '/' + file.join('/'))
			);
		});

		console.log(chalk.cyan('Devour initialized'));

		if (config.verbose) {
			['task', 'pipe'].forEach(function(what) {
				console.log(
					'  - available %ss: %s',
					what,
					what in definitions ? chalk.green(Object.keys(definitions[what]).join(', ')) : chalk.yellow('none')
				);
			});
			console.log('');
		}
	}

	/**
	 *  Register a task or pipe
	 *  @name    resgister
	 *  @access  internal
	 *  @param   string type [accepts any value, actual values: 'task' or 'pipe']
	 *  @param   string name
	 *  @param   function create
	 *  @return  void
	 */
	function register(type, name, create) {
		if (!(type in definitions)) {
			definitions[type] = {};
		}

		if (type === 'pipe') {
			create = chain(create, devour);
		}

		definitions[type][name] = create;
	}

	/**
	 *  Obtain a gulp plugin, initialized with given arguments
	 *  @name    plug
	 *  @access  internal
	 *  @param   string  name [automatically prefixed with 'gulp-']
	 *  @return  stream  initialized plugin
	 */
	function plug(name) {
		var part, scope;

		if (!('buffer' in plug.prototype)) {
			plug.prototype.buffer = {};
		}

		part  = name.split('.');
		scope = part.shift();

		if (!(scope in plug.prototype.buffer)) {
			plug.prototype.buffer[scope] = wanted.require('gulp-' + scope);
		}

		scope = plug.prototype.buffer[scope];

		part.forEach(function(p) {
			scope = scope[p];
		});

		//  this may be an a-typical gulp plugin (e.g. sourcemaps) which provides no stream, the implementer probably
		//  knows what to do with this
		if (typeof scope !== 'function') {
			return scope;
		}

		//  invoke the function in the scope with the arguments after the name
		//  this should create a stream
		return scope.apply(null, Array.prototype.slice.call(arguments, 1))
			//  always register an error listener for plugins
			.on('error', function(error) {
				console.error('Error from plugin %s: %s', chalk.red(name), error);
				this.emit('end');
			})
		;
	}

	/**
	 *  Start tasks provided from the command line
	 *  @name    startRequested
	 *  @access  internal
	 *  @return  bool  started
	 */
	function startRequested() {
		var start = [];

		if (run.length) {
			run.forEach(function(task) {
				var exists = task.replace(/:.*$/, '') in definitions.task;

				console.log(
					'Task %s %s',
					exists ? chalk.green(task) : chalk.red(task),
					exists ? 'running' : 'not found!'
				);

				if (exists) {
					start.push(task);
				}
			});

			if (start.length) {
				gulp.start.apply(gulp, start.concat([function(error) {
					if (error) {
						throw new Error(error);
					}

					console.log('Complete');
				}]));
			}
			else {
				console.log(chalk.red('No tasks are running, exiting!'));
				process.exit(1);
			}
		}

		return !!start.length;
	}

	/**
	 *  Create a plugin and initialize it
	 *  @name    plugin
	 *  @access  public
	 *  @param   mixed   arguments
	 *  @return  stream
	 */
	devour.plugin = plug;

	/**
	 *  Cleanup file basename and append .min to it
	 *  @name    min
	 *  @access  public
	 *  @param   object  file
	 *  @return  void
	 */
	devour.min = function(file) {
		file.basename = file.basename.replace(/\.(?:min|prep)/, '') + '.min';
	};

	/**
	 *  Require a module, trying to install it if not available
	 *  @name    require
	 *  @access  public
	 *  @param   string    module
	 *  @return  function  module
	 */
	devour.require = function(module) {
		return wanted.require(module);
	};

	/**
	 *  Create a source list and pipe it through the 'defaults' pipe
	 *  @name    source
	 *  @access  public
	 *  @param   mixed sources [one of: string, array]
	 *  @return  stream
	 */
	devour.source = function() {
		var source = gulp.src.apply(gulp, arguments);

		if ('defaults' in config) {
			config.defaults.forEach(function(name) {
				source = source.pipe(devour.plugin(name));
			});
		}

		return source;
	};

	/**
	 *  Invoke the predefined pipe and return its stream
	 *  @name    pipe
	 *  @access  public
	 *  @param   string  pipe
	 *  @return  stream
	 */
	devour.pipe = function() {
		var arg = Array.prototype.slice.call(arguments),
			name = arg.shift();

		if ('pipe' in definitions && name in definitions.pipe) {
			if (+config.verbose > 2) {
				console.log('  - Laying pipe: %s', chalk.yellow(name));
			}

			return definitions.pipe[name].apply(null, [null].concat(arg))
				//  always register an error listener for pipes
				.on('error', function(error) {
					console.error('Error in pipe %s: %s', chalk.red(name), error);
					this.emit('end');
				})
			;
		}

		throw new Error('Named pipe not found: ' + name);
	};

	/**
	 *  Obtain all settings, a single setting or a default value
	 *  @name    config
	 *  @access  public
	 *  @param   string  key [optional, default undefined - return the entire configuration]
	 *  @param   mixed   otherwise
	 *  @return  mixed
	 */
	devour.config = function(value, otherwise) {
		return arguments.length ? config[value] || otherwise : config;
	};

	/**
	 *  Write the contents of the current stream into the file in the stream
	 *  @name    write
	 *  @access  public
	 *  @param   string  relative [optional, default undefined - the configured 'output' path]
	 *  @param   object  options  [optional, default undefined - no options]
	 *  @return  stream
	 */
	devour.write = function(relative, options) {
		var path = config.output;

		if (/^\//.test(relative)) {
			path = relative;
		}
		else {
			path += '/' + (relative || '');
		}

		return gulp.dest(path, options || {read:true});
	};

	/**
	 *  Schedule a task
	 *  @name    task
	 *  @access  public
	 *  @param   string  name
	 *  @param   mixed   build [one of: string, array]
	 *  @param   mixed   watch [optional, default true - the value of build, one of string, array, bool provide (bool) false to disable]
	 *  @return  devour  [chainable]
	 */
	devour.task = polymorphic();
	devour.task.signature(
		'string name, array build, array watch',
		function(name, build, watch) {
			if (config.verbose) {
				console.log(
					'Task %s activated\n  - build files: %s\n  - watch files: %s',
					chalk.cyan(name),
					chalk.yellow(build.join(chalk.white(', '))),
					watch.length ? chalk.yellow(watch.join(chalk.white(', '))) : chalk.red('(none, not watching)')
				);
			}

			gulp.task(name, function() {
				var start = process.hrtime();

				if (+config.verbose > 1) {
					console.log('Running task: %s', chalk.yellow(name));
				}

				return definitions.task[name.replace(/:.*$/, '')](
						build.length ? devour.source(build) : null,
						devour,
						name)
					.on('end', function() {
						var delta = process.hrtime(start);
						if (+config.verbose > 1) {
							console.log(
								'Completed task: %s (%s)',
								chalk.yellow(name),
								chalk.green((delta[0] * 1e3 + delta[1] / 1e6).toFixed(2) + 'ms')
							);
						}
					})
				;
			});

			if (!run.length && watch.length) {
				active.push(name);
				watcher(watch, function() {
					gulp.start(name);
				});

				// gulp.watch(watch, {debounceDelay: config.debounce}, [name]);
			}

			return devour;
		}
	);

	devour.task.signature(
		'string name, string build, array watch',
		function(name, build, watch) {
			return devour.task(name, [build], watch);
		}
	);
	devour.task.signature(
		'string name, array build, string watch',
		function(name, build, watch) {
			return devour.task(name, build, [watch]);
		}
	);
	devour.task.signature(
		'string name, string build, string watch',
		function(name, build, watch) {
			return devour.task(name, [build], [watch]);
		}
	);
	devour.task.signature(
		'string name, array build, bool watch=true',
		function(name, build, watch) {
			return devour.task(name, build, watch ? build : []);
		}
	);
	devour.task.signature(
		'string name, string build, bool watch=true',
		function(name, build, watch) {
			return devour.task(name, [build], watch ? [build] : []);
		}
	);
	devour.task.signature(
		'string name',
		function(name) {
			return devour.task(name, [], []);
		}
	);

	/**
	 *  Create a default task for all scheduled tasks and let gulp do the heavy lifting
	 *  @name    start
	 *  @access  public
	 *  @param   function callback [optional, default undefined - no callback]
	 *  @return  void
	 */
	devour.start = function(callback) {
		if (startRequested()) {
			return;
		}

		if (!gulp.hasTask('default')) {
			if (config.verbose) {
				console.log(
					'\nNo %s task found, creating it with tasks: %s',
					chalk.cyan('default'),
					active.length ? chalk.cyan(active.join(chalk.white(', '))) : chalk.red('(none)')
				);
			}

			gulp.task('default', active, callback);

			console.log(
				'Created %s task: %s',
				chalk.cyan('default'),
				gulp.hasTask('default') ? chalk.green('OK') : chalk.red('failed')
			);
		}

		console.log(chalk.yellow('Starting gulp\n'));
		gulp.start('default');
	};

	init();
}
527833
function mainTask() {
        options = this.options(defaultOptions);
        var target = this.target;

        this.files.forEach(function (file) {

            var destJson = app.path.join(file.dest, target + '.cssstats.json');
            var destHtml = app.path.join(file.dest, target + '.cssstats.html');

            var css = {
                concat: ''
            };

            css.concat = file.src.filter(function (filepath) {
                // Remove nonexistent files (it's up to you to filter or warn here).
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).map(function (filepath) {
                // Read and return the file's source.

                css[filepath] = app.fs.readFileSync(filepath, 'utf8');

                return '/****\n    source: ' + filepath + '\n****/\n\n' + css[filepath];

            }).join('\n');

            var stats = parseStats(css);

            if (options.logConsole) {
                console.log(stats);
            }

            if (options.jsonOutput) {
                var statsString = JSON.stringify(stats, undefined, 4);
                grunt.file.write(destJson, statsString);
            }

            if (options.htmlOutput) {
                var output = app.parseHtml(app, options, stats, css);
                grunt.file.write(destHtml, output);
            }
        });

    }
20279
function GulpDotaNpc (type) {
  var file = 'npc_' + type + '_custom.txt';
  var headerName = 'DOTA' + type[0].toUpperCase() + type.substr(1);

  function transformFiles (contents, file) {
    // get the string contents of the file so we can easily update it
    var strContent = String(contents);
    var splitPath = file.relative.split(path.sep);
    var needsRename = splitPath.length > 1;
    var abilityName = stripDotTxt(splitPath.join('_'));

    if (needsRename) {
      strContent = strContent.replace('"' + stripDotTxt(splitPath[1]) + '"', '"' + abilityName + '"');
    }
    console.log('Adding', type, abilityName);
    return strContent;
  }

  function addHeader (contents, file) {
    return [
    '"', headerName, '"\n{\n',
    contents,
    '\n\n}'
    ].join('');
  }

  return multipipe(transform(transformFiles), concat(file), transform(addHeader));
}
1216281
function compressCSS() {
    let tasks = [];

    Object.keys(config.tasks).forEach((key) => {
        let val = config.tasks[key];
        tasks.push(gulp.src(val.src)
            .pipe(cleanCSS({processImport: false}))
            .pipe(rename(config.rename))
            .pipe(gulp.dest(val.dest)));
    });

    return merge(tasks);
}
293285
function defineTasksForConfig(taskData) {
  // Define gulp tasks (build and optionally watch)
  // For the task name:
  // - single config, no 'name' key: <callback>
  // - single config, 'name' key: <callback>_<name>
  // - multiple configs, no 'name' key: <callback>_<index>
  const { callback, name, normalizedConfigs } = taskData
  normalizedConfigs.forEach((config, index) => {
    let taskId = name
    if (typeof config.name === 'string') {
      taskId += `_${config.name.trim()}`
    } else if (normalizedConfigs.length > 1) {
      taskId += `_${index + 1}`
    }
    const buildId = options.buildPrefix + taskId
    const watchId = options.watchPrefix + taskId

    // Register build task
    gulp.task(buildId, done => {
      return callback(config, {
        done: done,
        catchErrors: catchErrors,
        showError: showError,
        showSizes: showSizes,
        simpleStream: simpleStream
      })
    })

    // Register matching watch task
    if (Array.isArray(config.watch) && config.watch.length > 0) {
      gulp.task(watchId, () => {
        return gulp.watch(config.watch, gulp.series(buildId))
      })
    }
  })
}
480758
function sortTasks(tasks, callback){
	async.waterfall([
		function(done){
			var availTasks = {};
			var tree = {};
			forEach(tasks, function(obj, key){
				obj.name = obj.name || obj.id || obj.identity || key || "unknown";
				obj.ext = (obj.ext && obj.ext.indexOf('.') != -1) ? obj.ext : ('.'+obj.ext);
				availTasks[obj.name] = obj;
				tree[obj.name] = (obj.runBefore) ? ( (isArray(obj.runBefore)) ? obj.runBefore : [obj.runBefore]) : [];
			});
			done(null, DepResolver(tree).map(function(name){ return availTasks[name]; }))
		}
	], callback);
}
268484
function gulpStatus() {
  const Vinyl = require('vinyl');
  const path = require('path');
  const gulpGit = require('gulp-git');
  const through = require('through2');
  const srcStream = through.obj();

  const opt = {cwd: process.cwd()};

  // https://git-scm.com/docs/git-status#_short_format
  const RE_STATUS = /((\s\w)|(\w+)|\?{0,2})\s([\w\+\-\/\\\.]+)(\s->\s)?([\w\+\-\/\\\.]+)*\n{0,1}/gm;

  gulpGit.status({args: '--porcelain', quiet: true}, function(err, stdout) {
    if (err) return srcStream.emit('error', err);

    const data = stdout.toString();
    let currentMatch;

    while ((currentMatch = RE_STATUS.exec(data)) !== null) {
      // status
      const status = currentMatch[1].trim().toLowerCase();

      // We only care about untracked files and renamed files
      if (!new RegExp(/r|\?/i).test(status)) {
        continue;
      }

      // file path
      const currentFilePath = currentMatch[4];

      // new file path in case its been moved
      const newFilePath = currentMatch[6];
      const filePath = newFilePath || currentFilePath;

      srcStream.write(new Vinyl({
        path: path.resolve(opt.cwd, filePath),
        cwd: opt.cwd,
      }));

      RE_STATUS.lastIndex++;
    }

    srcStream.end();
  });

  return srcStream;
}
261319
function _client_compile_task(file) {

    var infile = amigo_js_dev_path + '/' +file;
    //var outfile = amigo_js_out_path + '/' +file;

    var b = browserify(infile);
    return b
    // not in npm, don't need in browser
	.exclude('ringo/httpclient')
	.bundle()
    // desired output filename to vinyl-source-stream
	.pipe(source(file))
	.pipe(gulp.dest(amigo_js_out_path));
}
388128
function moduleWatchTask(taskname, fn) {
    var module = this;
    var fulltaskname = module.name + '-' + taskname + '-watch';

    module.task(taskname + '-watch', null, function(cb) {

      var w = fn();

      if(!w) {
        throw new Error('No options returned from watch: ' + taskname);
      }

      if(!w.glob) {
        throw new Error('No glob watch property in options: ' + taskname);
      }

      w.tasks = w.tasks || [taskname];

      var i = w.tasks.length;

      while(i--) {
        w.tasks[i] = module.name + '-' + w.tasks[i];
      }

      var watcher =  gulp.watch(w.glob, w.tasks);

      function onEvent(event) {
        console.log(event);
      }

      watcher.on('change', function(event) {
        console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
        var exec = require('child_process').exec;

        exec('growlnotify --image gulp-tasks/run.png -n angular-project-template -m "' + module.name + '-' + taskname + ': build triggered."')
      });

      cb();
    }, true);

    module.watchTasks.push(fulltaskname);
  }
8385
function startRequested() {
		var start = [];

		if (run.length) {
			run.forEach(function(task) {
				var exists = task.replace(/:.*$/, '') in definitions.task;

				console.log(
					'Task %s %s',
					exists ? chalk.green(task) : chalk.red(task),
					exists ? 'running' : 'not found!'
				);

				if (exists) {
					start.push(task);
				}
			});

			if (start.length) {
				gulp.start.apply(gulp, start.concat([function(error) {
					if (error) {
						throw new Error(error);
					}

					console.log('Complete');
				}]));
			}
			else {
				console.log(chalk.red('No tasks are running, exiting!'));
				process.exit(1);
			}
		}

		return !!start.length;
	}
471598
function filterFiles(gulp, options, taskFile){
	var ext = path.extname(taskFile);
	if(/\.(js|coffee)$/i.test(ext)){
		createTask(gulp, options, taskFile);
	}else if(/\.(json)$/i.test(ext)){
		createMultitasks(gulp, require(taskFile));
	}else if(/\.(ya?ml)$/i.test(ext)){
		createMultitasks(gulp, readYAML(taskFile));
	}
}
673501
function targetTask(){
  var spawn = require('child_process').spawn;

  return function(done){
    // I'm using the global gulp "" ci ""
    spawn('gulp', process.argv.slice(2), {
      cwd : './node_modules/angular-ui-publisher',
      stdio: 'inherit'
    }).on('close', done);
  }
}
451082
function _createHTMLTask(gulp, name, config, depTasks, index, startFun, endFun) {
    gulp.task(name, depTasks, function(){
        var s = config.html[index];
       return runHTMLTaskStream(gulp, s, config, startFun, endFun);        
    });
}