diff --git a/index.js b/index.js index 4006e080..54c03574 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ var globParent = require('glob-parent'); var isGlob = require('is-glob'); var isAbsolute = require('path-is-absolute'); var inherits = require('inherits'); +var braces = require('braces'); var NodeFsHandler = require('./lib/nodefs-handler'); var FsEventsHandler = require('./lib/fsevents-handler'); @@ -423,21 +424,31 @@ FSWatcher.prototype._getWatchHelpers = function(path, depth) { var getDirParts = function(path) { if (!hasGlob) return false; - var parts = sysPath.relative(watchPath, path).split(/[\/\\]/); + var parts = []; + var expandedPath = braces.expand(path); + expandedPath.forEach(function(path) { + parts.push(sysPath.relative(watchPath, path).split(/[\/\\]/)); + }); return parts; }; var dirParts = getDirParts(path); - if (dirParts && dirParts.length > 1) dirParts.pop(); + if (dirParts) { + dirParts.forEach(function(parts) { + if (parts.length > 1) parts.pop(); + }); + } var unmatchedGlob; var filterDir = function(entry) { if (hasGlob) { var entryParts = getDirParts(checkGlobSymlink(entry)); var globstar = false; - unmatchedGlob = !dirParts.every(function(part, i) { - if (part === '**') globstar = true; - return globstar || !entryParts[i] || anymatch(part, entryParts[i]); + unmatchedGlob = !dirParts.some(function(parts) { + return parts.every(function(part, i) { + if (part === '**') globstar = true; + return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i]); + }); }); } return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat); diff --git a/package.json b/package.json index 78a422d9..da392b70 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ "mocha": "^3.0.0", "rimraf": "^2.4.3", "sinon": "^1.10.3", - "sinon-chai": "^2.6.0" + "sinon-chai": "^2.6.0", + "upath": "1.0.0" }, "optionalDependencies": { "fsevents": "^1.0.0" @@ -45,6 +46,7 @@ "dependencies": { "anymatch": "^1.3.0", "async-each": "^1.0.0", + "braces": "2.2.2", "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", diff --git a/test.js b/test.js index 7fdcb21b..6ed41f98 100644 --- a/test.js +++ b/test.js @@ -8,6 +8,7 @@ var sinon = require('sinon'); var rimraf = require('rimraf'); var fs = require('graceful-fs'); var sysPath = require('path'); +var upath = require("upath"); var cp = require('child_process'); chai.use(require('sinon-chai')); var os = process.platform; @@ -767,6 +768,33 @@ function runTests(baseopts) { }); }); }); + it('should correctly handle glob with braces', function(done) { + var spy = sinon.spy(); + var watchPath = upath.normalizeSafe(getFixturePath('{subdir/*,subdir1/subsub1}/subsubsub/*.txt')); + var deepFileA = getFixturePath('subdir/subsub/subsubsub/a.txt'); + var deepFileB = getFixturePath('subdir1/subsub1/subsubsub/a.txt'); + fs.mkdirSync(getFixturePath('subdir'), 0x1ed); + fs.mkdirSync(getFixturePath('subdir/subsub'), 0x1ed); + fs.mkdirSync(getFixturePath('subdir/subsub/subsubsub'), 0x1ed); + fs.mkdirSync(getFixturePath('subdir1'), 0x1ed); + fs.mkdirSync(getFixturePath('subdir1/subsub1'), 0x1ed); + fs.mkdirSync(getFixturePath('subdir1/subsub1/subsubsub'), 0x1ed); + fs.writeFileSync(deepFileA, Date.now()); + fs.writeFileSync(deepFileB, Date.now()); + watcher = chokidar.watch(watchPath, options) + .on('all', spy) + .on('ready', function() { + spy.should.have.been.calledWith('add', deepFileA); + spy.should.have.been.calledWith('add', deepFileB); + fs.appendFileSync(deepFileA, Date.now()); + fs.appendFileSync(deepFileB, Date.now()); + waitFor([[spy, 4]], function() { + spy.should.have.been.calledWith('change', deepFileA); + spy.should.have.been.calledWith('change', deepFileB); + done(); + }); + }); + }); }); describe('watch symlinks', function() { if (os === 'win32') return; @@ -1118,7 +1146,7 @@ function runTests(baseopts) { describe('ignored', function() { it('should check ignore after stating', function(done) { options.ignored = function(path, stats) { - if (path === testDir || !stats) return false; + if (upath.normalizeSafe(path) === upath.normalizeSafe(testDir) || !stats) return false; return stats.isDirectory(); }; var spy = sinon.spy();