Skip to content

Commit

Permalink
makeRe globstar should match zero+ path portions
Browse files Browse the repository at this point in the history
This implements the requisite negative lookahead/behind using JavaScript
while building the regexp, so that the regexp returned by makeRe will be
able to match ** patterns against zero or more path portions, rather
than against 1 or more, which was previously a shortcoming of makeRe.

Also, move the pattern regexp tests into snapshots, where they belong.

Fix: isaacs#157
  • Loading branch information
isaacs committed Feb 15, 2022
1 parent 9c7c4bc commit a979c06
Show file tree
Hide file tree
Showing 5 changed files with 503 additions and 117 deletions.
41 changes: 35 additions & 6 deletions minimatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -791,13 +791,42 @@ class Minimatch {
: twoStarNoDot
const flags = options.nocase ? 'i' : ''

let re = set.map(pattern =>
pattern.map(p =>
(p === GLOBSTAR) ? twoStar
: (typeof p === 'string') ? regExpEscape(p)
// coalesce globstars and regexpify non-globstar patterns
// if it's the only item, then we just do one twoStar
// if it's the first, and there are more, prepend (\/|twoStar\/)? to next
// if it's the last, append (\/twoStar|) to previous
// if it's in the middle, append (\/|\/twoStar\/) to previous
// then filter out GLOBSTAR symbols
let re = set.map(pattern => {
pattern = pattern.map(p =>
typeof p === 'string' ? regExpEscape(p)
: p === GLOBSTAR ? GLOBSTAR
: p._src
).join('\\\/')
).join('|')
).reduce((set, p) => {
if (!(set[set.length - 1] === GLOBSTAR && p === GLOBSTAR)) {
set.push(p)
}
return set
}, [])
pattern.forEach((p, i) => {
if (p !== GLOBSTAR || pattern[i-1] === GLOBSTAR) {
return
}
if (i === 0) {
if (pattern.length > 1) {
pattern[i+1] = '(?:\\\/|' + twoStar + '\\\/)?' + pattern[i+1]
} else {
pattern[i] = twoStar
}
} else if (i === pattern.length - 1) {
pattern[i-1] += '(?:\\\/|' + twoStar + ')?'
} else {
pattern[i-1] += '(?:\\\/|\\\/' + twoStar + '\\\/)' + pattern[i+1]
pattern[i+1] = GLOBSTAR
}
})
return pattern.filter(p => p !== GLOBSTAR).join('/')
}).join('|')

// must match entire pattern
// ending in a * or ** will make it less strict.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"main": "minimatch.js",
"scripts": {
"test": "tap",
"snap": "tap",
"preversion": "npm test",
"postversion": "npm publish",
"prepublishOnly": "git push origin --follow-tags"
Expand Down
Loading

0 comments on commit a979c06

Please sign in to comment.