angular-cn/tools/build/watch.js

125 lines
3.3 KiB
JavaScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var chokidar = require('chokidar');
var runSequence = require('run-sequence');
var path = require('path');
function watch(globs, opts, tasks) {
if (typeof opts !== 'object' || Array.isArray(opts)) {
tasks = opts;
opts = {};
}
var triggerCount = 0;
var useRunSequence = typeof tasks !== 'function';
var runTasks;
if (useRunSequence) {
if (!Array.isArray(tasks)) tasks = [tasks];
tasks = tasks.slice();
tasks.push(tasksDone);
runTasks = function runTaskSequence() { runSequence.apply(null, tasks); };
} else {
var sync = tasks.length === 0;
runTasks = function runCallback() {
try {
tasks(tasksDone);
if (sync) tasksDone();
} catch (e) {
return tasksDone(e);
}
};
}
var events = opts.events = opts.events || ['add', 'change', 'unlink'];
// Don't let chokidar call us while initializing because on large trees it might take too long for
// all the add events to be emitted which causes the initial callback to be triggered more than
// once. Instead, we call handleEvent directly.
var ignoreInitial = opts.ignoreInitial;
opts.ignoreInitial = true;
var delay = opts.delay;
if (delay === undefined) delay = 100;
var watcher =
chokidar.watch(globs, opts).on('all', handleEvent).on('error', function(err) { throw err; });
var log = function watchLogger(triggerCount) {
// Don't report change for initial event
if (!ignoreInitial && !--triggerCount) return;
process.stdout.write([
'',
'==================================================',
' WATCH TRIGGERED BY FILE CHANGE #' + triggerCount,
' On: ' + prettyTime(),
'==================================================\n',
].join('\n'));
function prettyTime() {
var now = new Date();
return now.toLocaleDateString() + ' at ' + now.toLocaleTimeString();
}
};
if (opts.log !== undefined && !opts.log) {
log = function noopLog(triggerCount) {};
}
var close = watcher.close.bind(watcher);
watcher.close = function() {
if (timeoutId !== null) clearTimeout(timeoutId);
close();
};
var eventsRecorded = 0; // Number of events recorded
var timeoutId = null; // If non-null, event capture window is open
if (!ignoreInitial) {
// synthetic event to kick off the first task run
timeoutId = setTimeout(invokeCallback, delay);
}
return watcher;
function handleEvent(event, filepath) {
// Ignore unwatched events
if (events.indexOf(event) < 0) return;
// Increment number of events captured in this window
++eventsRecorded;
if (timeoutId === null) {
timeoutId = setTimeout(invokeCallback, delay);
}
}
function invokeCallback() {
eventsRecorded = 0;
log(++triggerCount);
runTasks();
}
function tasksDone(err) {
if (eventsRecorded) {
// eventsRecorded has increased during the run, run again on the next turn
timeoutId = setTimeout(invokeCallback, 0);
} else {
timeoutId = null;
}
if (!useRunSequence && err) {
// tslint:disable-next-line:no-console
console.log('Watch task error:', err.toString());
}
}
}
module.exports = watch;