New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

grunt-contrib-watch

Package Overview
Dependencies
Maintainers
3
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-contrib-watch - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

tasks/lib/taskrun.js

23

docs/watch-examples.md

@@ -36,2 +36,18 @@ # Examples

```js
// Example using watch events
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js']
}
}
});
// Listen for events when files are modified
grunt.event.on('watch', function(action, filepath) {
grunt.log.writeln(filepath + ' has ' + action);
});
```
# FAQs

@@ -47,1 +63,8 @@

Likely because of an enthusiastic pattern trying to watch thousands of files. Such as `'**/*.js'` but forgetting to exclude the `node_modules` folder with `'!node_modules/**/*.js'`. Try grouping your files within a subfolder or be more explicit with your file matching pattern.
## Why spawn as child processes as a default?
The goal of this watch task is as files are changed, run tasks as if they were triggered by the user themself. Each time a user runs `grunt` a process is spawned and tasks are ran in succession. In an effort to keep the experience consistent and continualy produce expected results, this watch task spawns tasks as child processes by default.
Sandboxing task runs also allows this watch task to run more stable over long periods of time. As well as more efficiently with more complex tasks and file structures.
Spawning does cause a performance hit (usually 500ms for most environments). It also cripples tasks that rely on the watch task to share the context with each subsequent run (i.e., reload tasks). If you would like a faster watch task or need to share the context please set the `nospawn` option to `true`. Just be aware that with this option enabled, the watch task is more prone to failure.

21

docs/watch-options.md

@@ -15,4 +15,23 @@ # Settings

## options.nospawn
Type: `Boolean`
Default: false
This instructs the watch task to not spawn task runs in a child process. Setting this option also speeds up the reaction time of the watch (usually 500ms faster for most) and allows subsequent task runs to share the same context (i.e., using a reload task). Not spawning task runs can make the watch more prone to failing so please use as needed.
Example:
```js
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['livereload'],
options: {
nospawn: true
}
}
}
```
## options.interrupt
Type: `boolean`
Type: `Boolean`
Default: false

@@ -19,0 +38,0 @@

6

package.json
{
"name": "grunt-contrib-watch",
"description": "Run predefined tasks whenever watched file patterns are added, changed or deleted.",
"version": "0.2.0",
"version": "0.3.0",
"homepage": "https://github.com/gruntjs/grunt-contrib-watch",

@@ -35,5 +35,5 @@ "author": {

"grunt": "~0.4.0",
"grunt-contrib-jshint": "~0.1.1",
"grunt-contrib-jshint": "~0.2.0",
"grunt-contrib-nodeunit": "~0.1.2",
"grunt-contrib-internal": "~0.4.0"
"grunt-contrib-internal": "~0.4.3"
},

@@ -40,0 +40,0 @@ "peerDependencies": {

@@ -16,3 +16,3 @@ # grunt-contrib-watch [![Build Status](https://secure.travis-ci.org/gruntjs/grunt-contrib-watch.png?branch=master)](http://travis-ci.org/gruntjs/grunt-contrib-watch)

One the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

@@ -44,4 +44,23 @@ ```js

#### options.nospawn
Type: `Boolean`
Default: false
This instructs the watch task to not spawn task runs in a child process. Setting this option also speeds up the reaction time of the watch (usually 500ms faster for most) and allows subsequent task runs to share the same context (i.e., using a reload task). Not spawning task runs can make the watch more prone to failing so please use as needed.
Example:
```js
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['livereload'],
options: {
nospawn: true
}
}
}
```
#### options.interrupt
Type: `boolean`
Type: `Boolean`
Default: false

@@ -124,2 +143,18 @@

```js
// Example using watch events
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js']
}
}
});
// Listen for events when files are modified
grunt.event.on('watch', function(action, filepath) {
grunt.log.writeln(filepath + ' has ' + action);
});
```
### FAQs

@@ -136,5 +171,13 @@

#### Why spawn as child processes as a default?
The goal of this watch task is as files are changed, run tasks as if they were triggered by the user themself. Each time a user runs `grunt` a process is spawned and tasks are ran in succession. In an effort to keep the experience consistent and continualy produce expected results, this watch task spawns tasks as child processes by default.
Sandboxing task runs also allows this watch task to run more stable over long periods of time. As well as more efficiently with more complex tasks and file structures.
Spawning does cause a performance hit (usually 500ms for most environments). It also cripples tasks that rely on the watch task to share the context with each subsequent run (i.e., reload tasks). If you would like a faster watch task or need to share the context please set the `nospawn` option to `true`. Just be aware that with this option enabled, the watch task is more prone to failure.
## Release History
* 2013-02-26   v0.3.0   nospawn option added to run tasks without spawning as child processes. Watch emits 'watch' events upon files being triggered with grunt.event. Completion time in seconds and date/time shown after tasks ran. Negate file patterns fixed. Tasks debounced individually to handle simultaneous triggering for multiple targets. Errors handled better and viewable with --stack cli option. Code complexity reduced making the watch task code easier to read.
* 2013-02-14   v0.2.0   First official release for Grunt 0.4.0.

@@ -154,2 +197,2 @@ * 2013-01-17   v0.2.0rc7   Updating grunt/gruntplugin dependencies to rc6. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.

*This file was generated on Mon Feb 18 2013 09:00:52.*
*This file was generated on Wed Feb 27 2013 14:08:02.*

@@ -13,8 +13,9 @@ /*

var path = require('path');
var fs = require('fs');
var Gaze = require('gaze').Gaze;
var taskrun = require('./lib/taskrun')(grunt);
// Default options for the watch task
var defaults = {
interrupt: false
interrupt: false,
nospawn: false
};

@@ -44,66 +45,16 @@

// Message to display when waiting for changes
var waiting = 'Waiting...';
// This task's name + optional args, in string format.
taskrun.nameArgs = this.nameArgs;
// File changes to be logged.
var changedFiles = Object.create(null);
// Keep track of spawns per tasks
var spawned = Object.create(null);
// List of changed / deleted file paths.
grunt.file.watchFiles = {changed: [], deleted: [], added: []};
// Get process.argv options without grunt.cli.tasks to pass to child processes
var cliArgs = grunt.util._.without.apply(null, [[].slice.call(process.argv, 2)].concat(grunt.cli.tasks));
taskrun.cliArgs = grunt.util._.without.apply(null, [[].slice.call(process.argv, 2)].concat(grunt.cli.tasks));
// Call to close this task
var done = this.async();
grunt.log.write(waiting);
if (taskrun.startedAt !== false) {
taskrun.completed();
} else {
grunt.log.write(taskrun.waiting);
}
// Run the tasks for the changed files
var runTasks = grunt.util._.debounce(function runTasks(i, tasks, options) {
// If interrupted, reset the spawned for a target
if (options.interrupt && typeof spawned[i] === 'object') {
grunt.log.writeln('').write('Previously spawned task has been interrupted...'.yellow);
spawned[i].kill('SIGINT');
delete spawned[i];
}
// Only spawn one at a time unless interrupt is specified
if (!spawned[i]) {
grunt.log.ok();
var fileArray = Object.keys(changedFiles);
fileArray.forEach(function(filepath) {
// Log which file has changed, and how.
grunt.log.ok('File "' + filepath + '" ' + changedFiles[filepath] + '.');
});
// Reset changedFiles
changedFiles = Object.create(null);
// Spawn the tasks as a child process
var start = Date.now();
spawned[i] = grunt.util.spawn({
// Spawn with the grunt bin
grunt: true,
// Run from current working dir and inherit stdio from process
opts: {cwd: process.cwd(), stdio: 'inherit'},
// Run grunt this process uses, append the task to be run and any cli options
args: grunt.util._.union(tasks, cliArgs)
}, function(err, res, code) {
// Spawn is done
delete spawned[i];
var msg = String(
'Completed in ' +
Number((Date.now() - start) / 1000).toFixed(2) +
's at ' +
(new Date()).toString()
).cyan;
grunt.log.writeln('').write(msg + ' - ' + waiting);
});
}
}, 250);
targets.forEach(function(target, i) {

@@ -123,17 +74,34 @@ if (typeof target.files === 'string') {

// Create watcher per target
var gaze = new Gaze(patterns, options, function(err) {
new Gaze(patterns, options, function(err) {
if (err) {
grunt.log.error(err.message);
if (typeof err === 'string') { err = new Error(err); }
grunt.log.writeln('ERROR'.red);
grunt.fatal(err);
return done();
}
// Debounce each task run
var runTasks = grunt.util._.debounce(taskrun[options.nospawn ? 'nospawn' : 'spawn'], 250);
// On changed/added/deleted
this.on('all', function(status, filepath) {
filepath = path.relative(process.cwd(), filepath);
changedFiles[filepath] = status;
runTasks(i, target.tasks, options);
// Emit watch events if anyone is listening
if (grunt.event.listeners('watch').length > 0) {
grunt.event.emit('watch', status, filepath);
}
// Run tasks if any have been specified
if (target.tasks) {
taskrun.changedFiles[filepath] = status;
runTasks(i, target.tasks, options, done);
}
});
// On watcher error
this.on('error', function(err) { grunt.log.error(err); });
this.on('error', function(err) {
if (typeof err === 'string') { err = new Error(err); }
grunt.log.error(err.message);
});
});

@@ -140,0 +108,0 @@ });

@@ -37,3 +37,3 @@ var grunt = require('grunt');

// Add the tasks to run
spawnOptions.push(task);
spawnOptions = spawnOptions.concat(task);

@@ -40,0 +40,0 @@ // Return an interface for testing this task

@@ -56,3 +56,3 @@ 'use strict';

},
multiTargetsTriggerBoth: function(test) {
multiTargetsSequentialFilesChangeTriggerBoth: function(test) {
test.expect(2);

@@ -72,2 +72,16 @@ var cwd = path.resolve(fixtures, 'multiTargets');

},
multiTargetsSimultaneousFilesChangeTriggerBoth: function(test) {
test.expect(2);
var cwd = path.resolve(fixtures, 'multiTargets');
var assertWatch = helper.assertTask('watch', {cwd:cwd});
assertWatch([function() {
grunt.file.write(path.join(cwd, 'lib', 'one.js'), 'var test = true;');
grunt.file.write(path.join(cwd, 'lib', 'two.js'), 'var test = true;');
}], function(result) {
helper.verboseLog(result);
test.ok(result.indexOf('one has changed') !== -1, 'Task echo:one should of emit.');
test.ok(result.indexOf('two has changed') !== -1, 'Task echo:two should of emit.');
test.done();
});
},
spawnOneAtATime: function(test) {

@@ -99,3 +113,3 @@ test.expect(1);

helper.verboseLog(result);
test.ok(result.indexOf('has been interrupted') !== -1, 'Task should have been interrupted.');
test.ok(result.indexOf('have been interrupted') !== -1, 'Task should have been interrupted.');
test.done();

@@ -102,0 +116,0 @@ });

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc