Comparing version 0.3.3 to 0.3.4
215
lib/gaze.js
@@ -5,3 +5,3 @@ /* | ||
* | ||
* Copyright (c) 2012 Kyle Robinson Young | ||
* Copyright (c) 2013 Kyle Robinson Young | ||
* Licensed under the MIT license. | ||
@@ -13,3 +13,4 @@ */ | ||
// libs | ||
var events = require('events'); | ||
var util = require('util'); | ||
var EE = require('events').EventEmitter; | ||
var fs = require('fs'); | ||
@@ -19,3 +20,2 @@ var path = require('path'); | ||
var minimatch = require('minimatch'); | ||
var Gaze; | ||
@@ -25,83 +25,78 @@ // globals | ||
// Main entry point. Start watching and call done when setup | ||
module.exports = function gaze(files, opts, done) { | ||
return new Gaze(files, opts, done); | ||
}; | ||
// `Gaze` EventEmitter object to return in the callback | ||
function Gaze(patterns, opts, done) { | ||
var _this = this; | ||
EE.call(_this); | ||
// Node v0.6 compat | ||
fs.existsSync = fs.existsSync || path.existsSync; | ||
path.sep = path.sep || path.normalize('/'); | ||
// CoffeeScript's __extends utility | ||
var __extends = function(child, parent) { | ||
for (var key in parent) { | ||
if ({}.hasOwnProperty.call(parent, key)) { | ||
child[key] = parent[key]; | ||
} | ||
// If second arg is the callback | ||
if (typeof opts === 'function') { | ||
done = opts; | ||
opts = {}; | ||
} | ||
function Ctor() { | ||
this.constructor = child; | ||
} | ||
Ctor.prototype = parent.prototype; | ||
child.prototype = new Ctor(); | ||
child.__super__ = parent.prototype; | ||
return child; | ||
}; | ||
// lodash helpers | ||
// Default options | ||
opts = opts || {}; | ||
opts.mark = true; | ||
opts.interval = opts.interval || 100; | ||
opts.debounceDelay = opts.debounceDelay || 500; | ||
opts.cwd = opts.cwd || process.cwd(); | ||
this.options = opts; | ||
var ArrayPrototype = Array.prototype; | ||
var toString = Object.prototype.toString; | ||
var has = Object.prototype.hasOwnProperty; | ||
// Default done callback | ||
done = done || function() {}; | ||
function defaults(obj, source) { | ||
for (var prop in source) { | ||
if (obj[prop] == null) { | ||
obj[prop] = source[prop]; | ||
} | ||
} | ||
// Remember our watched dir:files | ||
this._watched = Object.create(null); | ||
return obj; | ||
} | ||
// Store watchers | ||
this._watchers = Object.create(null); | ||
function unique() { | ||
var array = ArrayPrototype.concat.apply(ArrayPrototype, arguments); | ||
var result = []; | ||
// Store patterns | ||
this._patterns = []; | ||
for (var i = 0; i < array.length; i++) { | ||
if (result.indexOf(array[i]) === -1) { | ||
result.push(array[i]); | ||
} | ||
// Cached events for debouncing | ||
this._cached = Object.create(null); | ||
// Set maxListeners | ||
if (this.options.maxListeners) { | ||
this.setMaxListeners(this.options.maxListeners); | ||
Gaze.super_.prototype.setMaxListeners(this.options.maxListeners); | ||
delete this.options.maxListeners; | ||
} | ||
return result; | ||
} | ||
// Initialize the watch on files | ||
if (patterns) { | ||
this.add(patterns, done); | ||
} | ||
function union() { | ||
return unique.apply(null, arguments); | ||
return this; | ||
} | ||
util.inherits(Gaze, EE); | ||
function isString(obj) { | ||
return toString.call(obj) === '[object String]'; | ||
} | ||
// Main entry point. Start watching and call done when setup | ||
module.exports = function gaze(patterns, opts, done) { | ||
return new Gaze(patterns, opts, done); | ||
}; | ||
module.exports.Gaze = Gaze; | ||
function isEmpty(obj) { | ||
if (obj == null) { return true; } | ||
// Node v0.6 compat | ||
fs.existsSync = fs.existsSync || path.existsSync; | ||
path.sep = path.sep || path.normalize('/'); | ||
if (Array.isArray(obj) || isString(obj)) { return obj.length === 0; } | ||
/** | ||
* Lo-Dash 1.0.1 <http://lodash.com/> | ||
* Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> | ||
* Based on Underscore.js 1.4.4 <http://underscorejs.org/> | ||
* Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. | ||
* Available under MIT license <http://lodash.com/license> | ||
*/ | ||
function unique() { var array = Array.prototype.concat.apply(Array.prototype, arguments); var result = []; for (var i = 0; i < array.length; i++) { if (result.indexOf(array[i]) === -1) { result.push(array[i]); } } return result; } | ||
for (var key in obj) { | ||
if (has.call(obj, key)) { return false; } | ||
} | ||
return true; | ||
} | ||
// async helper | ||
/** | ||
* Copyright (c) 2010 Caolan McMahon | ||
* Available under MIT license <https://raw.github.com/caolan/async/master/LICENSE> | ||
*/ | ||
function forEachSeries(arr, iterator, callback) { | ||
if (!arr.length) { return callback(); } | ||
var completed = 0; | ||
var iterate = function() { | ||
@@ -114,3 +109,2 @@ iterator(arr[completed], function (err) { | ||
completed += 1; | ||
if (completed === arr.length) { | ||
@@ -124,3 +118,2 @@ callback(null); | ||
}; | ||
iterate(); | ||
@@ -160,50 +153,2 @@ } | ||
// `Gaze` EventEmitter object to return in the callback | ||
Gaze = module.exports.Gaze = __extends(function(files, opts, done) { | ||
var _this = this; | ||
// If second arg is the callback | ||
if (typeof opts === 'function') { | ||
done = opts; | ||
opts = {}; | ||
} | ||
// Default options | ||
this.options = defaults(opts || {}, { | ||
// Tell glob to mark directories | ||
mark: true, | ||
// Interval to pass to fs.watchFile | ||
interval: 100, | ||
// Delay for events called in succession for the same file/event | ||
debounceDelay: 500 | ||
}); | ||
// Default done callback | ||
done = done || function() {}; | ||
// Remember our watched dir:files | ||
this._watched = Object.create(null); | ||
// Store watchers | ||
this._watchers = Object.create(null); | ||
// Store patterns | ||
this._patterns = []; | ||
// Cached events for debouncing | ||
this._cached = Object.create(null); | ||
// Set maxListeners | ||
if (this.options.maxListeners) { | ||
this.setMaxListeners(this.options.maxListeners); | ||
Gaze.__super__.setMaxListeners(this.options.maxListeners); | ||
delete this.options.maxListeners; | ||
} | ||
// Initialize the watch on files | ||
this.add(files, done); | ||
return this; | ||
}, events.EventEmitter); | ||
// Override the emit function to emit `all` events | ||
@@ -221,3 +166,3 @@ // and debounce on duplicate events per file | ||
if (e.slice(-2) !== 'ed') { | ||
Gaze.__super__.emit.apply(_this, args); | ||
Gaze.super_.prototype.emit.apply(_this, args); | ||
return this; | ||
@@ -248,4 +193,4 @@ } | ||
// Emit the event and `all` event | ||
Gaze.__super__.emit.apply(_this, args); | ||
Gaze.__super__.emit.apply(_this, ['all', e].concat([].slice.call(args, 1))); | ||
Gaze.super_.prototype.emit.apply(_this, args); | ||
Gaze.super_.prototype.emit.apply(_this, ['all', e].concat([].slice.call(args, 1))); | ||
} | ||
@@ -286,3 +231,3 @@ | ||
} | ||
this._patterns = union(this._patterns, files); | ||
this._patterns = unique.apply(null, [this._patterns, files]); | ||
@@ -321,5 +266,5 @@ var include = [], exclude = []; | ||
var index = _this._watched[dir].indexOf(file); | ||
if (index) { | ||
if (index !== -1) { | ||
fs.unwatchFile(file); | ||
delete _this._watched[dir][index]; | ||
_this._watched[dir].splice(index, 1); | ||
return false; | ||
@@ -373,26 +318,6 @@ } | ||
var _this = this; | ||
var dir, parent; | ||
var cwd = _this.options.cwd || process.cwd(); | ||
files.forEach(function(file) { | ||
var filepath = path.resolve(cwd, file); | ||
// if mark false, use stat to figure the isDir | ||
// the '/' mark comes from node-glob but we convert it to path.sep | ||
if (_this.options.mark === false) { | ||
if (fs.statSync(filepath).isDirectory()) { | ||
file += '/'; | ||
} | ||
} | ||
if (file.slice(-1) === '/') { | ||
// is dir, init key and sub folder | ||
filepath = _markDir(filepath); | ||
_objectPush(_this._watched, filepath); | ||
parent = path.dirname(filepath) + path.sep; | ||
_objectPush(_this._watched, parent, filepath); | ||
} else { | ||
// is file, add to dir | ||
dir = path.dirname(filepath) + path.sep; | ||
_objectPush(_this._watched, dir, filepath); | ||
} | ||
var filepath = path.resolve(_this.options.cwd, file); | ||
if (file.slice(-1) === '/') { filepath += path.sep; } | ||
_objectPush(_this._watched, path.dirname(filepath) + path.sep, filepath); | ||
}); | ||
@@ -477,3 +402,3 @@ return this; | ||
current = current.map(function(curPath) { | ||
if (fs.existsSync(curPath) && fs.statSync(path.join(dir, curPath)).isDirectory()) { | ||
if (fs.existsSync(path.join(dir, curPath)) && fs.statSync(path.join(dir, curPath)).isDirectory()) { | ||
return curPath + path.sep; | ||
@@ -480,0 +405,0 @@ } else { |
{ | ||
"name": "gaze", | ||
"description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", | ||
"version": "0.3.3", | ||
"version": "0.3.4", | ||
"homepage": "https://github.com/shama/gaze", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -154,2 +154,3 @@ # gaze [![Build Status](https://secure.travis-ci.org/shama/gaze.png?branch=master)](http://travis-ci.org/shama/gaze) | ||
## Release History | ||
* 0.3.4 - Code clean up. Fix path must be strings errors (@groner). Fix incorrect added events (@groner). | ||
* 0.3.3 - Fix for multiple patterns with negate. | ||
@@ -171,3 +172,3 @@ * 0.3.2 - Emit `end` before removeAllListeners. | ||
## License | ||
Copyright (c) 2012 Kyle Robinson Young | ||
Copyright (c) 2013 Kyle Robinson Young | ||
Licensed under the MIT license. |
@@ -19,2 +19,3 @@ 'use strict'; | ||
'nested/added.js', | ||
'nested/.tmp', | ||
'nested/sub/added.js' | ||
@@ -89,2 +90,19 @@ ].forEach(function(d) { | ||
}, | ||
dontAddMatchedDirectoriesThatArentReallyAdded: function(test) { | ||
// This is a regression test for a bug I ran into where a matching directory would be reported | ||
// added when a non-matching file was created along side it. This only happens if the | ||
// directory name doesn't occur in $PWD. | ||
test.expect(1); | ||
gaze('**/*', function(err, watcher) { | ||
setTimeout(function() { | ||
test.ok(true, 'Ended without adding a file.'); | ||
watcher.close(); | ||
}, 1000); | ||
this.on('added', function(filepath) { | ||
test.notEqual(path.relative(process.cwd(), filepath), path.join('nested', 'sub2')); | ||
}); | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'nested', '.tmp'), 'Wake up!'); | ||
watcher.on('end', test.done); | ||
}); | ||
}, | ||
deleted: function(test) { | ||
@@ -105,14 +123,2 @@ test.expect(1); | ||
}, | ||
nomark: function(test) { | ||
test.expect(1); | ||
gaze('**/*', {mark:false}, function(err, watcher) { | ||
watcher.on('changed', function(filepath) { | ||
var expected = path.relative(process.cwd(), filepath); | ||
test.equal(path.join('sub', 'one.js'), expected); | ||
watcher.close(); | ||
}); | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); | ||
watcher.on('end', test.done); | ||
}); | ||
}, | ||
dontEmitTwice: function(test) { | ||
@@ -119,0 +125,0 @@ test.expect(2); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27
173
39493
984