123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /*
- * grunt-contrib-watch
- * http://gruntjs.com/
- *
- * Copyright (c) 2018 "Cowboy" Ben Alman, contributors
- * Licensed under the MIT license.
- */
- 'use strict';
- var path = require('path');
- var Gaze = require('gaze').Gaze;
- var _ = require('lodash');
- var waiting = 'Waiting...';
- var changedFiles = Object.create(null);
- var watchers = [];
- module.exports = function(grunt) {
- var taskrun = require('./lib/taskrunner')(grunt);
- // Default date format logged
- var dateFormat = function(time) {
- grunt.log.writeln(String(
- 'Completed in ' +
- time.toFixed(3) +
- 's at ' +
- (new Date()).toString()
- ).cyan + ' - ' + waiting);
- };
- // When task runner has started
- taskrun.on('start', function() {
- Object.keys(changedFiles).forEach(function(filepath) {
- // Log which file has changed, and how.
- grunt.log.ok('File "' + filepath + '" ' + changedFiles[filepath] + '.');
- });
- // Reset changedFiles
- changedFiles = Object.create(null);
- });
- // When task runner has ended
- taskrun.on('end', function(time) {
- if (time > 0) {
- dateFormat(time);
- }
- });
- // When a task run has been interrupted
- taskrun.on('interrupt', function() {
- grunt.log.writeln('').write('Scheduled tasks have been interrupted...'.yellow);
- });
- // When taskrun is reloaded
- taskrun.on('reload', function() {
- taskrun.clearRequireCache(Object.keys(changedFiles));
- grunt.log.writeln('').writeln('Reloading watch config...'.cyan);
- });
- grunt.registerTask('watch', 'Run predefined tasks whenever watched files change.', function(target) {
- var self = this;
- var name = self.name || 'watch';
- // Close any previously opened watchers
- watchers.forEach(function(watcher) {
- watcher.close();
- });
- watchers = [];
- // Never gonna give you up, never gonna let you down
- if (grunt.config([name, 'options', 'forever']) !== false) {
- taskrun.forever();
- }
- // If a custom dateFormat function
- var df = grunt.config([name, 'options', 'dateFormat']);
- if (typeof df === 'function') {
- dateFormat = df;
- }
- if (taskrun.running === false) {
- grunt.log.writeln(waiting);
- }
- // Initialize taskrun
- var targets = taskrun.init(name, {target: target});
- targets.forEach(function(target) {
- if (typeof target.files === 'string') {
- target.files = [target.files];
- }
- // Process into raw patterns
- var patterns = _.chain(target.files).flatten().map(function(pattern) {
- return grunt.config.process(pattern);
- }).value();
- // Validate the event option
- if (typeof target.options.event === 'string') {
- target.options.event = [target.options.event];
- }
- var eventCwd = process.cwd();
- if (target.options.cwd && target.options.cwd.event) {
- eventCwd = target.options.cwd.event;
- }
- // Set cwd if options.cwd.file is set
- if (typeof target.options.cwd !== 'string' && target.options.cwd.files) {
- target.options.cwd = target.options.cwd.files;
- }
- // Create watcher per target
- watchers.push(new Gaze(patterns, target.options, function(err) {
- if (err) {
- if (typeof err === 'string') {
- err = new Error(err);
- }
- grunt.log.writeln('ERROR'.red);
- grunt.fatal(err);
- return taskrun.done();
- }
- // Log all watched files with --verbose set
- if (grunt.option('verbose')) {
- var watched = this.watched();
- Object.keys(watched).forEach(function(watchedDir) {
- watched[watchedDir].forEach(function(watchedFile) {
- grunt.log.writeln('Watching ' + path.relative(process.cwd(), watchedFile) + ' for changes.');
- });
- });
- }
- // On changed/added/deleted
- this.on('all', function(status, filepath) {
- // Skip events not specified
- if (!_.includes(target.options.event, 'all') &&
- !_.includes(target.options.event, status)) {
- return;
- }
- filepath = path.relative(eventCwd, filepath);
- // Skip empty filepaths
- if (filepath === '') {
- return;
- }
- // If Gruntfile.js changed, reload self task
- if (target.options.reload || /gruntfile\.(js|coffee)/i.test(filepath)) {
- taskrun.reload = true;
- }
- // Emit watch events if anyone is listening
- if (grunt.event.listeners('watch').length > 0) {
- grunt.event.emit('watch', status, filepath, target.name);
- }
- // Group changed files only for display
- changedFiles[filepath] = status;
- // Add changed files to the target
- if (taskrun.targets[target.name]) {
- if (!taskrun.targets[target.name].changedFiles) {
- taskrun.targets[target.name].changedFiles = Object.create(null);
- }
- taskrun.targets[target.name].changedFiles[filepath] = status;
- }
- // Queue the target
- if (taskrun.queue.indexOf(target.name) === -1) {
- taskrun.queue.push(target.name);
- }
- // Run the tasks
- taskrun.run();
- });
- // On watcher error
- this.on('error', function(err) {
- if (typeof err === 'string') {
- err = new Error(err);
- }
- grunt.log.error(err.message);
- });
- }));
- });
- });
- };
|