diff --git a/lib/index.js b/lib/index.js index 4d3c258..91fbe36 100644 --- a/lib/index.js +++ b/lib/index.js @@ -208,15 +208,16 @@ class Walker extends EE { new Walker(this.walkerOpt(entry, opts)).on('done', then).start() } - filterEntry (entry, partial) { + filterEntry (entry, partial, entryBasename) { let included = true // this = /a/b/c // entry = d // parent /a/b sees c/d if (this.parent && this.parent.filterEntry) { - var pt = this.basename + '/' + entry - included = this.parent.filterEntry(pt, partial) + const parentEntry = this.basename + '/' + entry + const parentBasename = entryBasename || entry + included = this.parent.filterEntry(parentEntry, partial, parentBasename) if (!included && partial) { return false } @@ -229,17 +230,28 @@ class Walker extends EE { // so if it's negated, and already included, no need to check // likewise if it's neither negated nor included if (rule.negate !== included) { + const isRelativeRule = entryBasename && rule.globParts.some(part => + part.length <= (part.slice(-1)[0] ? 1 : 2) + ) + // first, match against /foo/bar // then, against foo/bar // then, in the case of partials, match with a / + // then, if also the rule is relative, match against basename const match = rule.match('/' + entry) || rule.match(entry) || - (!!partial && ( + !!partial && ( rule.match('/' + entry + '/') || - rule.match(entry + '/'))) || - (!!partial && rule.negate && ( - rule.match('/' + entry, true) || - rule.match(entry, true))) + rule.match(entry + '/') || + rule.negate && ( + rule.match('/' + entry, true) || + rule.match(entry, true)) || + isRelativeRule && ( + rule.match('/' + entryBasename + '/') || + rule.match(entryBasename + '/') || + rule.negate && ( + rule.match('/' + entryBasename, true) || + rule.match(entryBasename, true)))) if (match) { included = rule.negate diff --git a/test/common.js b/test/common.js index a1a68e9..4d74b81 100644 --- a/test/common.js +++ b/test/common.js @@ -11,6 +11,7 @@ exports.ignores = ignores exports.writeIgnoreFile = writeIgnoreFile exports.writeIgnores = writeIgnores exports.clearIgnores = clearIgnores +exports.createFile = createFile function writeIgnoreFile (file, rules) { file = path.resolve(__dirname, 'fixtures', file) @@ -37,3 +38,13 @@ function ignores (set) { writeIgnores(set) process.on('exit', clearIgnores.bind(null, set)) } + +/** Used to create an extra file next to the fixtures from 00-setup.js. */ +function createFile (dir, file) { + var fixtures = path.resolve(__dirname, 'fixtures') + + dir = path.resolve(fixtures, dir) + fs.mkdirSync(dir, { recursive: true }) + file = path.resolve(dir, file) + fs.writeFileSync(file, path.basename(file)) +} diff --git a/test/nested-ignores.js b/test/nested-ignores.js index f0f4a6d..b937437 100644 --- a/test/nested-ignores.js +++ b/test/nested-ignores.js @@ -7,16 +7,24 @@ const path = resolve(__dirname, 'fixtures') // set the ignores just for this test var c = require('./common.js') c.ignores({ - '.ignore': ['*', 'd', 'h', '!d/c/h/.dch', '!/h/c/d/hcd'], + '.ignore': ['*', 'd', 'h', '!d/c/h/.dch', '!/h/c/d/hcd', '!c/**/ccc'], 'd/.ignore': ['!*', '.ignore'], // unignore everything 'd/d/.ignore': ['*'], // re-ignore everything 'd/c/.ignore': ['*', '!/h/.dch'], // original unignore 'd/h/.ignore': ['*'], // ignore everything again 'h/c/d/.ignore': ['!hcd', '!.hcd', '!/d{ch,dd}'], + 'c/.ignore': ['h/', 'c/c*'], // ignore directories recursively (GH#9) }) +// For GH#9, we need one more level of depth +c.createFile('c/c/d/d', 'ccc') +c.createFile('c/c/d/h', 'ccc') // the only files we expect to see var expected = [ + 'c/c/d/ccc', + 'c/c/d/d/ccc', + 'c/d/c/ccc', + 'c/d/d/ccc', 'd/c/h/.dch', 'h/c/d/.hcd', 'h/c/d/dch',