From 6d651617bd0965a4f41beed095622fda0a4b3405 Mon Sep 17 00:00:00 2001 From: Kyle Robinson Young Date: Tue, 8 Apr 2014 21:57:09 -0700 Subject: [PATCH] Convert relative() to async. Ref GH-76. --- README.md | 10 +++++--- benchmarks/relative.js | 9 ++++--- lib/gaze.js | 38 ++++++++++++++++++++-------- lib/gaze04.js | 22 ++++++++++++---- lib/helper.js | 18 +++++++------ test/add_test.js | 25 ++++++++++++------ test/api_test.js | 28 +++++++++++++-------- test/helper_test.js | 14 ++++++----- test/matching_test.js | 57 +++++++++++++++++++++++------------------- test/watch_test.js | 17 +++++++------ 10 files changed, 149 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 29d9d05..54769ff 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,9 @@ gaze('**/*.js', function(err, watcher) { }); // Get watched files with relative paths - console.log(this.relative()); + this.relative(function(err, files) { + console.log(files); + }); }); // Also accepts an array of patterns @@ -140,10 +142,12 @@ var gaze = new Gaze(pattern, options, callback); * `add(patterns, callback)` Adds file(s) patterns to be watched. * `remove(filepath)` removes a file or directory from being watched. Does not recurse directories. -* `watched()` Returns the currently watched files. -* `relative([dir, unixify])` Returns the currently watched files with relative paths. +* `watched([callback])` Returns the currently watched files. + * `callback` {function} Calls with `function(err, files)`. +* `relative([dir, unixify, callback])` Returns the currently watched files with relative paths. * `dir` {string} Only return relative files for this directory. * `unixify` {boolean} Return paths with `/` instead of `\\` if on Windows. + * `callback` {function} Calls with `function(err, files)`. ## FAQs diff --git a/benchmarks/relative.js b/benchmarks/relative.js index 711c4cd..af4f040 100644 --- a/benchmarks/relative.js +++ b/benchmarks/relative.js @@ -9,10 +9,11 @@ b.table.setHeading('files', 'ms').setAlign(0, 2).setAlign(1, 2); b.run(function(num, done) { gaze('**/*', {cwd: b.tmpDir, maxListeners:0}, function(err, watcher) { b.start(); - var files = this.relative('.'); - b.log(num, b.end()); - watcher.on('end', done); - watcher.close(); + this.relative('.', function(err, files) { + b.log(num, b.end()); + watcher.on('end', done); + watcher.close(); + }); }); }, function() { process.exit(); diff --git a/lib/gaze.js b/lib/gaze.js index b439275..4aaea7b 100644 --- a/lib/gaze.js +++ b/lib/gaze.js @@ -100,6 +100,7 @@ module.exports.Gaze = Gaze; Gaze.prototype.emit = function() { var self = this; var args = arguments; + //console.log('GAZE EMIT', arguments) var e = args[0]; var filepath = args[1]; @@ -182,6 +183,7 @@ Gaze.prototype.close = function(_reset) { // Add file patterns to be watched Gaze.prototype.add = function(files, done) { var self = this; + //console.log('ADD', files); if (typeof files === 'string') { files = [files]; } this._patterns = helper.unique.apply(null, [this._patterns, files]); files = globule.find(this._patterns, this.options); @@ -294,19 +296,33 @@ Gaze.prototype.remove = function(file) { }; // Return watched files -Gaze.prototype.watched = function() { - return helper.flatToTree(platform.getWatchedPaths(), this.options.cwd, false); +Gaze.prototype.watched = function(done) { + done = nextback(done || function() {}); + helper.flatToTree(platform.getWatchedPaths(), this.options.cwd, false, done); + return this; }; // Returns `watched` files with relative paths to cwd -Gaze.prototype.relative = function(dir, unixify) { - var relative = helper.flatToTree(platform.getWatchedPaths(), this.options.cwd, true, unixify); - if (dir) { - if (unixify) { - dir = helper.unixifyPathSep(dir); - } - // Better guess what to return for backwards compatibility - return relative[dir] || relative[dir + (unixify ? '/' : path.sep)] || []; +Gaze.prototype.relative = function(dir, unixify, done) { + if (typeof dir === 'function') { + done = dir; + dir = null; + unixify = false; } - return relative; + if (typeof unixify === 'function') { + done = unixify; + unixify = false; + } + done = nextback(done || function() {}); + helper.flatToTree(platform.getWatchedPaths(), this.options.cwd, true, unixify, function(err, relative) { + if (dir) { + if (unixify) { + dir = helper.unixifyPathSep(dir); + } + // Better guess what to return for backwards compatibility + return done(null, relative[dir] || relative[dir + (unixify ? '/' : path.sep)] || []); + } + return done(null, relative); + }); + return this; }; diff --git a/lib/gaze04.js b/lib/gaze04.js index cf04a08..1de85d3 100644 --- a/lib/gaze04.js +++ b/lib/gaze04.js @@ -213,12 +213,22 @@ Gaze.prototype.remove = function(file) { }; // Return watched files -Gaze.prototype.watched = function() { - return this._watched; +Gaze.prototype.watched = function(done) { + done(null, this._watched); + return this; }; // Returns `watched` files with relative paths to process.cwd() -Gaze.prototype.relative = function(dir, unixify) { +Gaze.prototype.relative = function(dir, unixify, done) { + if (typeof dir === 'function') { + done = dir; + dir = null; + unixify = false; + } + if (typeof unixify === 'function') { + done = unixify; + unixify = false; + } var self = this; var relative = Object.create(null); var relDir, relFile, unixRelDir; @@ -238,13 +248,15 @@ Gaze.prototype.relative = function(dir, unixify) { if (unixify) { relFile = helper.unixifyPathSep(relFile); } - return relFile; + done(null, relFile); + return self; }); }); if (dir && unixify) { dir = helper.unixifyPathSep(dir); } - return dir ? relative[dir] || [] : relative; + done(null, dir ? relative[dir] || [] : relative); + return self; }; // Adds files and dirs to watched diff --git a/lib/helper.js b/lib/helper.js index 113f3d9..ea1acf6 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -41,16 +41,16 @@ helper.unixifyPathSep = function unixifyPathSep(filepath) { }; // Converts a flat list of paths to the old style tree -helper.flatToTree = function flatToTree(files, cwd, relative, unixify) { +helper.flatToTree = function flatToTree(files, cwd, relative, unixify, done) { cwd = helper.markDir(cwd); var tree = Object.create(null); - for (var i = 0; i < files.length; i++) { - var filepath = files[i]; + + helper.forEachSeries(files, function(filepath, next) { var parent = path.dirname(filepath) + path.sep; // If parent outside cwd, ignore if (path.relative(cwd, parent) === '..') { - continue; + return next(); } // If we want relative paths @@ -60,7 +60,7 @@ helper.flatToTree = function flatToTree(files, cwd, relative, unixify) { } else { parent = path.relative(cwd, parent) + path.sep; } - filepath = path.relative(path.join(cwd, parent), files[i]) + (helper.isDir(files[i]) ? path.sep : ''); + filepath = path.relative(path.join(cwd, parent), filepath) + (helper.isDir(filepath) ? path.sep : ''); } // If we want to transform paths to unix seps @@ -71,14 +71,16 @@ helper.flatToTree = function flatToTree(files, cwd, relative, unixify) { } } - if (!parent) continue; + if (!parent) { return next(); } if (!Array.isArray(tree[parent])) { tree[parent] = []; } tree[parent].push(filepath); - } - return tree; + next(); + }, function() { + done(null, tree); + }); }; /** diff --git a/test/add_test.js b/test/add_test.js index cdaa653..b957364 100644 --- a/test/add_test.js +++ b/test/add_test.js @@ -16,15 +16,24 @@ exports.add = { addLater: function(test) { test.expect(3); new Gaze('sub/one.js', function(err, watcher) { - test.deepEqual(watcher.relative('sub'), ['one.js']); - watcher.add('sub/*.js', function() { - test.deepEqual(watcher.relative('sub'), ['one.js', 'two.js']); - watcher.on('changed', function(filepath) { - test.equal('two.js', path.basename(filepath)); - watcher.on('end', test.done); - watcher.close(); + watcher.on('changed', function(filepath) { + test.equal('two.js', path.basename(filepath)); + watcher.on('end', test.done); + watcher.close(); + }); + + function addLater() { + watcher.add('sub/*.js', function() { + watcher.relative('sub', function(err, result) { + test.deepEqual(result, ['one.js', 'two.js']); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'two.js'), 'var two = true;'); + }); }); - fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'two.js'), 'var two = true;'); + } + + watcher.relative('sub', function(err, result) { + test.deepEqual(result, ['one.js']); + addLater(); }); }); }, diff --git a/test/api_test.js b/test/api_test.js index 37666e8..9593468 100644 --- a/test/api_test.js +++ b/test/api_test.js @@ -13,28 +13,34 @@ exports.api = { newGaze: function(test) { test.expect(2); new gaze.Gaze('**/*', {}, function() { - var result = helper.sortobj(this.relative(null, true)); - test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); - test.deepEqual(result['sub/'], ['one.js', 'two.js']); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + var result = helper.sortobj(result); + test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, func: function(test) { test.expect(1); var g = gaze('**/*', function(err, watcher) { - test.deepEqual(watcher.relative('sub', true), ['one.js', 'two.js']); - g.on('end', test.done); - g.close(); + watcher.relative('sub', true, function(err, result) { + test.deepEqual(result, ['one.js', 'two.js']); + g.on('end', test.done); + g.close(); + }.bind(this)); }); }, ready: function(test) { test.expect(1); var g = new gaze.Gaze('**/*'); g.on('ready', function(watcher) { - test.deepEqual(watcher.relative('sub', true), ['one.js', 'two.js']); - this.on('end', test.done); - this.close(); + watcher.relative('sub', true, function(err, result) { + test.deepEqual(result, ['one.js', 'two.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, nomatch: function(test) { diff --git a/test/helper_test.js b/test/helper_test.js index c324bc0..bf453d3 100644 --- a/test/helper_test.js +++ b/test/helper_test.js @@ -27,9 +27,10 @@ exports.helper = { '/Users/dude/www/sub/': ['/Users/dude/www/sub/one.js', '/Users/dude/www/sub/nested/'], '/Users/dude/www/sub/nested/': ['/Users/dude/www/sub/nested/one.js'], }; - var actual = helper.flatToTree(files, cwd, false, true); - test.deepEqual(actual, expected); - test.done(); + helper.flatToTree(files, cwd, false, true, function(err, actual) { + test.deepEqual(actual, expected); + test.done(); + }); }, flatToTreeRelative: function(test) { test.expect(1); @@ -48,8 +49,9 @@ exports.helper = { 'sub/': ['one.js', 'nested/'], 'sub/nested/': ['one.js'], }; - var actual = helper.flatToTree(files, cwd, true, true); - test.deepEqual(actual, expected); - test.done(); + helper.flatToTree(files, cwd, true, true, function(err, actual) { + test.deepEqual(actual, expected); + test.done(); + }); }, }; diff --git a/test/matching_test.js b/test/matching_test.js index 9fcb037..0ef906d 100644 --- a/test/matching_test.js +++ b/test/matching_test.js @@ -29,47 +29,53 @@ exports.matching = { globAll: function(test) { test.expect(2); gaze('**/*', function() { - var result = this.relative(null, true); - test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); - test.deepEqual(result['sub/'], ['one.js', 'two.js']); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, relativeDir: function(test) { test.expect(1); gaze('**/*', function() { - test.deepEqual(this.relative('sub', true), ['one.js', 'two.js']); - this.on('end', test.done); - this.close(); + this.relative('sub', true, function(err, result) { + test.deepEqual(result, ['one.js', 'two.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, globArray: function(test) { test.expect(2); gaze(['*.js', 'sub/*.js'], function() { - var result = this.relative(null, true); - test.deepEqual(sortobj(result['.']), sortobj(['one.js', 'sub/'])); - test.deepEqual(sortobj(result['sub/']), sortobj(['one.js', 'two.js'])); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + test.deepEqual(sortobj(result['.']), sortobj(['one.js', 'sub/'])); + test.deepEqual(sortobj(result['sub/']), sortobj(['one.js', 'two.js'])); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, globArrayDot: function(test) { test.expect(1); gaze(['./sub/*.js'], function() { - var result = this.relative(null, true); - test.deepEqual(result['sub/'], ['one.js', 'two.js']); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, oddName: function(test) { test.expect(1); gaze(['Project (LO)/*.js'], function() { - var result = this.relative(null, true); - test.deepEqual(result['Project (LO)/'], ['one.js']); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + test.deepEqual(result['Project (LO)/'], ['one.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, addedLater: function(test) { @@ -82,11 +88,10 @@ exports.matching = { gaze('**/*.js', function(err, watcher) { watcher.on('all', function(status, filepath) { var expect = expected.shift(); - var result = watcher.relative(expect[0], true); - test.deepEqual(sortobj(result), sortobj(expect.slice(1))); - if (expected.length < 1) { - watcher.close(); - } + watcher.relative(expect[0], true, function(err, result) { + test.deepEqual(sortobj(result), sortobj(expect.slice(1))); + if (expected.length < 1) { watcher.close(); } + }.bind(this)); }); grunt.file.write(path.join(fixtures, 'newfolder', 'added.js'), 'var added = true;'); setTimeout(function() { diff --git a/test/watch_test.js b/test/watch_test.js index a636d87..151402b 100644 --- a/test/watch_test.js +++ b/test/watch_test.js @@ -36,11 +36,12 @@ exports.watch = { gaze('**/*', function() { this.remove(path.resolve(__dirname, 'fixtures', 'sub', 'two.js')); this.remove(path.resolve(__dirname, 'fixtures')); - var result = this.relative(null, true); - test.deepEqual(result['sub/'], ['one.js']); - test.notDeepEqual(result['.'], ['one.js']); - this.on('end', test.done); - this.close(); + this.relative(null, true, function(err, result) { + test.deepEqual(result['sub/'], ['one.js']); + test.notDeepEqual(result['.'], ['one.js']); + this.on('end', test.done); + this.close(); + }.bind(this)); }); }, changed: function(test) { @@ -178,8 +179,10 @@ exports.watch = { cwd: cwd }, function(err, watcher) { watcher.on('changed', function(filepath) { - test.deepEqual(this.relative(), {'.':['two.js']}); - watcher.close(); + this.relative(function(err, result) { + test.deepEqual(result, {'.':['two.js']}); + watcher.close(); + }); }); fs.writeFileSync(path.resolve(cwd, 'two.js'), 'var two = true;'); watcher.on('end', test.done);