minimatch.js 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. ;(function (require, exports, module, platform) {
  2. if (module) module.exports = minimatch
  3. else exports.minimatch = minimatch
  4. if (!require) {
  5. require = function (id) {
  6. switch (id) {
  7. case "sigmund": return function sigmund (obj) {
  8. return JSON.stringify(obj)
  9. }
  10. case "path": return { basename: function (f) {
  11. f = f.split(/[\/\\]/)
  12. var e = f.pop()
  13. if (!e) e = f.pop()
  14. return e
  15. }}
  16. case "lru-cache": return function LRUCache () {
  17. // not quite an LRU, but still space-limited.
  18. var cache = {}
  19. var cnt = 0
  20. this.set = function (k, v) {
  21. cnt ++
  22. if (cnt >= 100) cache = {}
  23. cache[k] = v
  24. }
  25. this.get = function (k) { return cache[k] }
  26. }
  27. }
  28. }
  29. }
  30. minimatch.Minimatch = Minimatch
  31. var LRU = require("lru-cache")
  32. , cache = minimatch.cache = new LRU({max: 100})
  33. , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
  34. , sigmund = require("sigmund")
  35. var path = require("path")
  36. // any single thing other than /
  37. // don't need to escape / when using new RegExp()
  38. , qmark = "[^/]"
  39. // * => any number of characters
  40. , star = qmark + "*?"
  41. // ** when dots are allowed. Anything goes, except .. and .
  42. // not (^ or / followed by one or two dots followed by $ or /),
  43. // followed by anything, any number of times.
  44. , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
  45. // not a ^ or / followed by a dot,
  46. // followed by anything, any number of times.
  47. , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
  48. // characters that need to be escaped in RegExp.
  49. , reSpecials = charSet("().*{}+?[]^$\\!")
  50. // "abc" -> { a:true, b:true, c:true }
  51. function charSet (s) {
  52. return s.split("").reduce(function (set, c) {
  53. set[c] = true
  54. return set
  55. }, {})
  56. }
  57. // normalizes slashes.
  58. var slashSplit = /\/+/
  59. minimatch.monkeyPatch = monkeyPatch
  60. function monkeyPatch () {
  61. var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
  62. var orig = desc.value
  63. desc.value = function (p) {
  64. if (p instanceof Minimatch) return p.match(this)
  65. return orig.call(this, p)
  66. }
  67. Object.defineProperty(String.prototype, desc)
  68. }
  69. minimatch.filter = filter
  70. function filter (pattern, options) {
  71. options = options || {}
  72. return function (p, i, list) {
  73. return minimatch(p, pattern, options)
  74. }
  75. }
  76. function ext (a, b) {
  77. a = a || {}
  78. b = b || {}
  79. var t = {}
  80. Object.keys(b).forEach(function (k) {
  81. t[k] = b[k]
  82. })
  83. Object.keys(a).forEach(function (k) {
  84. t[k] = a[k]
  85. })
  86. return t
  87. }
  88. minimatch.defaults = function (def) {
  89. if (!def || !Object.keys(def).length) return minimatch
  90. var orig = minimatch
  91. var m = function minimatch (p, pattern, options) {
  92. return orig.minimatch(p, pattern, ext(def, options))
  93. }
  94. m.Minimatch = function Minimatch (pattern, options) {
  95. return new orig.Minimatch(pattern, ext(def, options))
  96. }
  97. return m
  98. }
  99. Minimatch.defaults = function (def) {
  100. if (!def || !Object.keys(def).length) return Minimatch
  101. return minimatch.defaults(def).Minimatch
  102. }
  103. function minimatch (p, pattern, options) {
  104. if (typeof pattern !== "string") {
  105. throw new TypeError("glob pattern string required")
  106. }
  107. if (!options) options = {}
  108. // shortcut: comments match nothing.
  109. if (!options.nocomment && pattern.charAt(0) === "#") {
  110. return false
  111. }
  112. // "" only matches ""
  113. if (pattern.trim() === "") return p === ""
  114. return new Minimatch(pattern, options).match(p)
  115. }
  116. function Minimatch (pattern, options) {
  117. if (!(this instanceof Minimatch)) {
  118. return new Minimatch(pattern, options, cache)
  119. }
  120. if (typeof pattern !== "string") {
  121. throw new TypeError("glob pattern string required")
  122. }
  123. if (!options) options = {}
  124. pattern = pattern.trim()
  125. // windows: need to use /, not \
  126. // On other platforms, \ is a valid (albeit bad) filename char.
  127. if (platform === "win32") {
  128. pattern = pattern.split("\\").join("/")
  129. }
  130. // lru storage.
  131. // these things aren't particularly big, but walking down the string
  132. // and turning it into a regexp can get pretty costly.
  133. var cacheKey = pattern + "\n" + sigmund(options)
  134. var cached = minimatch.cache.get(cacheKey)
  135. if (cached) return cached
  136. minimatch.cache.set(cacheKey, this)
  137. this.options = options
  138. this.set = []
  139. this.pattern = pattern
  140. this.regexp = null
  141. this.negate = false
  142. this.comment = false
  143. this.empty = false
  144. // make the set of regexps etc.
  145. this.make()
  146. }
  147. Minimatch.prototype.make = make
  148. function make () {
  149. // don't do it more than once.
  150. if (this._made) return
  151. var pattern = this.pattern
  152. var options = this.options
  153. // empty patterns and comments match nothing.
  154. if (!options.nocomment && pattern.charAt(0) === "#") {
  155. this.comment = true
  156. return
  157. }
  158. if (!pattern) {
  159. this.empty = true
  160. return
  161. }
  162. // step 1: figure out negation, etc.
  163. this.parseNegate()
  164. // step 2: expand braces
  165. var set = this.globSet = this.braceExpand()
  166. if (options.debug) console.error(this.pattern, set)
  167. // step 3: now we have a set, so turn each one into a series of path-portion
  168. // matching patterns.
  169. // These will be regexps, except in the case of "**", which is
  170. // set to the GLOBSTAR object for globstar behavior,
  171. // and will not contain any / characters
  172. set = this.globParts = set.map(function (s) {
  173. return s.split(slashSplit)
  174. })
  175. if (options.debug) console.error(this.pattern, set)
  176. // glob --> regexps
  177. set = set.map(function (s, si, set) {
  178. return s.map(this.parse, this)
  179. }, this)
  180. if (options.debug) console.error(this.pattern, set)
  181. // filter out everything that didn't compile properly.
  182. set = set.filter(function (s) {
  183. return -1 === s.indexOf(false)
  184. })
  185. if (options.debug) console.error(this.pattern, set)
  186. this.set = set
  187. }
  188. Minimatch.prototype.parseNegate = parseNegate
  189. function parseNegate () {
  190. var pattern = this.pattern
  191. , negate = false
  192. , options = this.options
  193. , negateOffset = 0
  194. if (options.nonegate) return
  195. for ( var i = 0, l = pattern.length
  196. ; i < l && pattern.charAt(i) === "!"
  197. ; i ++) {
  198. negate = !negate
  199. negateOffset ++
  200. }
  201. if (negateOffset) this.pattern = pattern.substr(negateOffset)
  202. this.negate = negate
  203. }
  204. // Brace expansion:
  205. // a{b,c}d -> abd acd
  206. // a{b,}c -> abc ac
  207. // a{0..3}d -> a0d a1d a2d a3d
  208. // a{b,c{d,e}f}g -> abg acdfg acefg
  209. // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
  210. //
  211. // Invalid sets are not expanded.
  212. // a{2..}b -> a{2..}b
  213. // a{b}c -> a{b}c
  214. minimatch.braceExpand = function (pattern, options) {
  215. return new Minimatch(pattern, options).braceExpand()
  216. }
  217. Minimatch.prototype.braceExpand = braceExpand
  218. function braceExpand (pattern, options) {
  219. options = options || this.options
  220. pattern = typeof pattern === "undefined"
  221. ? this.pattern : pattern
  222. if (typeof pattern === "undefined") {
  223. throw new Error("undefined pattern")
  224. }
  225. if (options.nobrace ||
  226. !pattern.match(/\{.*\}/)) {
  227. // shortcut. no need to expand.
  228. return [pattern]
  229. }
  230. var escaping = false
  231. // examples and comments refer to this crazy pattern:
  232. // a{b,c{d,e},{f,g}h}x{y,z}
  233. // expected:
  234. // abxy
  235. // abxz
  236. // acdxy
  237. // acdxz
  238. // acexy
  239. // acexz
  240. // afhxy
  241. // afhxz
  242. // aghxy
  243. // aghxz
  244. // everything before the first \{ is just a prefix.
  245. // So, we pluck that off, and work with the rest,
  246. // and then prepend it to everything we find.
  247. if (pattern.charAt(0) !== "{") {
  248. // console.error(pattern)
  249. var prefix = null
  250. for (var i = 0, l = pattern.length; i < l; i ++) {
  251. var c = pattern.charAt(i)
  252. // console.error(i, c)
  253. if (c === "\\") {
  254. escaping = !escaping
  255. } else if (c === "{" && !escaping) {
  256. prefix = pattern.substr(0, i)
  257. break
  258. }
  259. }
  260. // actually no sets, all { were escaped.
  261. if (prefix === null) {
  262. // console.error("no sets")
  263. return [pattern]
  264. }
  265. var tail = braceExpand(pattern.substr(i), options)
  266. return tail.map(function (t) {
  267. return prefix + t
  268. })
  269. }
  270. // now we have something like:
  271. // {b,c{d,e},{f,g}h}x{y,z}
  272. // walk through the set, expanding each part, until
  273. // the set ends. then, we'll expand the suffix.
  274. // If the set only has a single member, then'll put the {} back
  275. // first, handle numeric sets, since they're easier
  276. var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
  277. if (numset) {
  278. // console.error("numset", numset[1], numset[2])
  279. var suf = braceExpand(pattern.substr(numset[0].length), options)
  280. , start = +numset[1]
  281. , end = +numset[2]
  282. , inc = start > end ? -1 : 1
  283. , set = []
  284. for (var i = start; i != (end + inc); i += inc) {
  285. // append all the suffixes
  286. for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
  287. set.push(i + suf[ii])
  288. }
  289. }
  290. return set
  291. }
  292. // ok, walk through the set
  293. // We hope, somewhat optimistically, that there
  294. // will be a } at the end.
  295. // If the closing brace isn't found, then the pattern is
  296. // interpreted as braceExpand("\\" + pattern) so that
  297. // the leading \{ will be interpreted literally.
  298. var i = 1 // skip the \{
  299. , depth = 1
  300. , set = []
  301. , member = ""
  302. , sawEnd = false
  303. , escaping = false
  304. function addMember () {
  305. set.push(member)
  306. member = ""
  307. }
  308. // console.error("Entering for")
  309. FOR: for (i = 1, l = pattern.length; i < l; i ++) {
  310. var c = pattern.charAt(i)
  311. // console.error("", i, c)
  312. if (escaping) {
  313. escaping = false
  314. member += "\\" + c
  315. } else {
  316. switch (c) {
  317. case "\\":
  318. escaping = true
  319. continue
  320. case "{":
  321. depth ++
  322. member += "{"
  323. continue
  324. case "}":
  325. depth --
  326. // if this closes the actual set, then we're done
  327. if (depth === 0) {
  328. addMember()
  329. // pluck off the close-brace
  330. i ++
  331. break FOR
  332. } else {
  333. member += c
  334. continue
  335. }
  336. case ",":
  337. if (depth === 1) {
  338. addMember()
  339. } else {
  340. member += c
  341. }
  342. continue
  343. default:
  344. member += c
  345. continue
  346. } // switch
  347. } // else
  348. } // for
  349. // now we've either finished the set, and the suffix is
  350. // pattern.substr(i), or we have *not* closed the set,
  351. // and need to escape the leading brace
  352. if (depth !== 0) {
  353. // console.error("didn't close", pattern)
  354. return braceExpand("\\" + pattern, options)
  355. }
  356. // x{y,z} -> ["xy", "xz"]
  357. // console.error("set", set)
  358. // console.error("suffix", pattern.substr(i))
  359. var suf = braceExpand(pattern.substr(i), options)
  360. // ["b", "c{d,e}","{f,g}h"] ->
  361. // [["b"], ["cd", "ce"], ["fh", "gh"]]
  362. var addBraces = set.length === 1
  363. // console.error("set pre-expanded", set)
  364. set = set.map(function (p) {
  365. return braceExpand(p, options)
  366. })
  367. // console.error("set expanded", set)
  368. // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
  369. // ["b", "cd", "ce", "fh", "gh"]
  370. set = set.reduce(function (l, r) {
  371. return l.concat(r)
  372. })
  373. if (addBraces) {
  374. set = set.map(function (s) {
  375. return "{" + s + "}"
  376. })
  377. }
  378. // now attach the suffixes.
  379. var ret = []
  380. for (var i = 0, l = set.length; i < l; i ++) {
  381. for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
  382. ret.push(set[i] + suf[ii])
  383. }
  384. }
  385. return ret
  386. }
  387. // parse a component of the expanded set.
  388. // At this point, no pattern may contain "/" in it
  389. // so we're going to return a 2d array, where each entry is the full
  390. // pattern, split on '/', and then turned into a regular expression.
  391. // A regexp is made at the end which joins each array with an
  392. // escaped /, and another full one which joins each regexp with |.
  393. //
  394. // Following the lead of Bash 4.1, note that "**" only has special meaning
  395. // when it is the *only* thing in a path portion. Otherwise, any series
  396. // of * is equivalent to a single *. Globstar behavior is enabled by
  397. // default, and can be disabled by setting options.noglobstar.
  398. Minimatch.prototype.parse = parse
  399. var SUBPARSE = {}
  400. function parse (pattern, isSub) {
  401. var options = this.options
  402. // shortcuts
  403. if (!options.noglobstar && pattern === "**") return GLOBSTAR
  404. if (pattern === "") return ""
  405. var re = ""
  406. , hasMagic = !!options.nocase
  407. , escaping = false
  408. // ? => one single character
  409. , patternListStack = []
  410. , plType
  411. , stateChar
  412. , inClass = false
  413. , reClassStart = -1
  414. , classStart = -1
  415. // . and .. never match anything that doesn't start with .,
  416. // even when options.dot is set.
  417. , patternStart = pattern.charAt(0) === "." ? "" // anything
  418. // not (start or / followed by . or .. followed by / or end)
  419. : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
  420. : "(?!\\.)"
  421. function clearStateChar () {
  422. if (stateChar) {
  423. // we had some state-tracking character
  424. // that wasn't consumed by this pass.
  425. switch (stateChar) {
  426. case "*":
  427. re += star
  428. hasMagic = true
  429. break
  430. case "?":
  431. re += qmark
  432. hasMagic = true
  433. break
  434. default:
  435. re += "\\"+stateChar
  436. break
  437. }
  438. stateChar = false
  439. }
  440. }
  441. for ( var i = 0, len = pattern.length, c
  442. ; (i < len) && (c = pattern.charAt(i))
  443. ; i ++ ) {
  444. if (options.debug) {
  445. console.error("%s\t%s %s %j", pattern, i, re, c)
  446. }
  447. // skip over any that are escaped.
  448. if (escaping && reSpecials[c]) {
  449. re += "\\" + c
  450. escaping = false
  451. continue
  452. }
  453. SWITCH: switch (c) {
  454. case "/":
  455. // completely not allowed, even escaped.
  456. // Should already be path-split by now.
  457. return false
  458. case "\\":
  459. clearStateChar()
  460. escaping = true
  461. continue
  462. // the various stateChar values
  463. // for the "extglob" stuff.
  464. case "?":
  465. case "*":
  466. case "+":
  467. case "@":
  468. case "!":
  469. if (options.debug) {
  470. console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
  471. }
  472. // all of those are literals inside a class, except that
  473. // the glob [!a] means [^a] in regexp
  474. if (inClass) {
  475. if (c === "!" && i === classStart + 1) c = "^"
  476. re += c
  477. continue
  478. }
  479. // if we already have a stateChar, then it means
  480. // that there was something like ** or +? in there.
  481. // Handle the stateChar, then proceed with this one.
  482. clearStateChar()
  483. stateChar = c
  484. // if extglob is disabled, then +(asdf|foo) isn't a thing.
  485. // just clear the statechar *now*, rather than even diving into
  486. // the patternList stuff.
  487. if (options.noext) clearStateChar()
  488. continue
  489. case "(":
  490. if (inClass) {
  491. re += "("
  492. continue
  493. }
  494. if (!stateChar) {
  495. re += "\\("
  496. continue
  497. }
  498. plType = stateChar
  499. patternListStack.push({ type: plType
  500. , start: i - 1
  501. , reStart: re.length })
  502. // negation is (?:(?!js)[^/]*)
  503. re += stateChar === "!" ? "(?:(?!" : "(?:"
  504. stateChar = false
  505. continue
  506. case ")":
  507. if (inClass || !patternListStack.length) {
  508. re += "\\)"
  509. continue
  510. }
  511. hasMagic = true
  512. re += ")"
  513. plType = patternListStack.pop().type
  514. // negation is (?:(?!js)[^/]*)
  515. // The others are (?:<pattern>)<type>
  516. switch (plType) {
  517. case "!":
  518. re += "[^/]*?)"
  519. break
  520. case "?":
  521. case "+":
  522. case "*": re += plType
  523. case "@": break // the default anyway
  524. }
  525. continue
  526. case "|":
  527. if (inClass || !patternListStack.length || escaping) {
  528. re += "\\|"
  529. escaping = false
  530. continue
  531. }
  532. re += "|"
  533. continue
  534. // these are mostly the same in regexp and glob
  535. case "[":
  536. // swallow any state-tracking char before the [
  537. clearStateChar()
  538. if (inClass) {
  539. re += "\\" + c
  540. continue
  541. }
  542. inClass = true
  543. classStart = i
  544. reClassStart = re.length
  545. re += c
  546. continue
  547. case "]":
  548. // a right bracket shall lose its special
  549. // meaning and represent itself in
  550. // a bracket expression if it occurs
  551. // first in the list. -- POSIX.2 2.8.3.2
  552. if (i === classStart + 1 || !inClass) {
  553. re += "\\" + c
  554. escaping = false
  555. continue
  556. }
  557. // finish up the class.
  558. hasMagic = true
  559. inClass = false
  560. re += c
  561. continue
  562. default:
  563. // swallow any state char that wasn't consumed
  564. clearStateChar()
  565. if (escaping) {
  566. // no need
  567. escaping = false
  568. } else if (reSpecials[c]
  569. && !(c === "^" && inClass)) {
  570. re += "\\"
  571. }
  572. re += c
  573. } // switch
  574. } // for
  575. // handle the case where we left a class open.
  576. // "[abc" is valid, equivalent to "\[abc"
  577. if (inClass) {
  578. // split where the last [ was, and escape it
  579. // this is a huge pita. We now have to re-walk
  580. // the contents of the would-be class to re-translate
  581. // any characters that were passed through as-is
  582. var cs = pattern.substr(classStart + 1)
  583. , sp = this.parse(cs, SUBPARSE)
  584. re = re.substr(0, reClassStart) + "\\[" + sp[0]
  585. hasMagic = hasMagic || sp[1]
  586. }
  587. // handle the case where we had a +( thing at the *end*
  588. // of the pattern.
  589. // each pattern list stack adds 3 chars, and we need to go through
  590. // and escape any | chars that were passed through as-is for the regexp.
  591. // Go through and escape them, taking care not to double-escape any
  592. // | chars that were already escaped.
  593. var pl
  594. while (pl = patternListStack.pop()) {
  595. var tail = re.slice(pl.reStart + 3)
  596. // maybe some even number of \, then maybe 1 \, followed by a |
  597. tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
  598. if (!$2) {
  599. // the | isn't already escaped, so escape it.
  600. $2 = "\\"
  601. }
  602. // need to escape all those slashes *again*, without escaping the
  603. // one that we need for escaping the | character. As it works out,
  604. // escaping an even number of slashes can be done by simply repeating
  605. // it exactly after itself. That's why this trick works.
  606. //
  607. // I am sorry that you have to see this.
  608. return $1 + $1 + $2 + "|"
  609. })
  610. // console.error("tail=%j\n %s", tail, tail)
  611. var t = pl.type === "*" ? star
  612. : pl.type === "?" ? qmark
  613. : "\\" + pl.type
  614. hasMagic = true
  615. re = re.slice(0, pl.reStart)
  616. + t + "\\("
  617. + tail
  618. }
  619. // handle trailing things that only matter at the very end.
  620. clearStateChar()
  621. if (escaping) {
  622. // trailing \\
  623. re += "\\\\"
  624. }
  625. // only need to apply the nodot start if the re starts with
  626. // something that could conceivably capture a dot
  627. var addPatternStart = false
  628. switch (re.charAt(0)) {
  629. case ".":
  630. case "[":
  631. case "(": addPatternStart = true
  632. }
  633. // if the re is not "" at this point, then we need to make sure
  634. // it doesn't match against an empty path part.
  635. // Otherwise a/* will match a/, which it should not.
  636. if (re !== "" && hasMagic) re = "(?=.)" + re
  637. if (addPatternStart) re = patternStart + re
  638. // parsing just a piece of a larger pattern.
  639. if (isSub === SUBPARSE) {
  640. return [ re, hasMagic ]
  641. }
  642. // skip the regexp for non-magical patterns
  643. // unescape anything in it, though, so that it'll be
  644. // an exact match against a file etc.
  645. if (!hasMagic) {
  646. return globUnescape(pattern)
  647. }
  648. var flags = options.nocase ? "i" : ""
  649. , regExp = new RegExp("^" + re + "$", flags)
  650. regExp._glob = pattern
  651. regExp._src = re
  652. return regExp
  653. }
  654. minimatch.makeRe = function (pattern, options) {
  655. return new Minimatch(pattern, options || {}).makeRe()
  656. }
  657. Minimatch.prototype.makeRe = makeRe
  658. function makeRe () {
  659. if (this.regexp || this.regexp === false) return this.regexp
  660. // at this point, this.set is a 2d array of partial
  661. // pattern strings, or "**".
  662. //
  663. // It's better to use .match(). This function shouldn't
  664. // be used, really, but it's pretty convenient sometimes,
  665. // when you just want to work with a regex.
  666. var set = this.set
  667. if (!set.length) return this.regexp = false
  668. var options = this.options
  669. var twoStar = options.noglobstar ? star
  670. : options.dot ? twoStarDot
  671. : twoStarNoDot
  672. , flags = options.nocase ? "i" : ""
  673. var re = set.map(function (pattern) {
  674. return pattern.map(function (p) {
  675. return (p === GLOBSTAR) ? twoStar
  676. : (typeof p === "string") ? regExpEscape(p)
  677. : p._src
  678. }).join("\\\/")
  679. }).join("|")
  680. // must match entire pattern
  681. // ending in a * or ** will make it less strict.
  682. re = "^(?:" + re + ")$"
  683. // can match anything, as long as it's not this.
  684. if (this.negate) re = "^(?!" + re + ").*$"
  685. try {
  686. return this.regexp = new RegExp(re, flags)
  687. } catch (ex) {
  688. return this.regexp = false
  689. }
  690. }
  691. minimatch.match = function (list, pattern, options) {
  692. var mm = new Minimatch(pattern, options)
  693. list = list.filter(function (f) {
  694. return mm.match(f)
  695. })
  696. if (options.nonull && !list.length) {
  697. list.push(pattern)
  698. }
  699. return list
  700. }
  701. Minimatch.prototype.match = match
  702. function match (f, partial) {
  703. // console.error("match", f, this.pattern)
  704. // short-circuit in the case of busted things.
  705. // comments, etc.
  706. if (this.comment) return false
  707. if (this.empty) return f === ""
  708. if (f === "/" && partial) return true
  709. var options = this.options
  710. // windows: need to use /, not \
  711. // On other platforms, \ is a valid (albeit bad) filename char.
  712. if (platform === "win32") {
  713. f = f.split("\\").join("/")
  714. }
  715. // treat the test path as a set of pathparts.
  716. f = f.split(slashSplit)
  717. if (options.debug) {
  718. console.error(this.pattern, "split", f)
  719. }
  720. // just ONE of the pattern sets in this.set needs to match
  721. // in order for it to be valid. If negating, then just one
  722. // match means that we have failed.
  723. // Either way, return on the first hit.
  724. var set = this.set
  725. // console.error(this.pattern, "set", set)
  726. for (var i = 0, l = set.length; i < l; i ++) {
  727. var pattern = set[i]
  728. var hit = this.matchOne(f, pattern, partial)
  729. if (hit) {
  730. if (options.flipNegate) return true
  731. return !this.negate
  732. }
  733. }
  734. // didn't get any hits. this is success if it's a negative
  735. // pattern, failure otherwise.
  736. if (options.flipNegate) return false
  737. return this.negate
  738. }
  739. // set partial to true to test if, for example,
  740. // "/a/b" matches the start of "/*/b/*/d"
  741. // Partial means, if you run out of file before you run
  742. // out of pattern, then that's fine, as long as all
  743. // the parts match.
  744. Minimatch.prototype.matchOne = function (file, pattern, partial) {
  745. var options = this.options
  746. if (options.debug) {
  747. console.error("matchOne",
  748. { "this": this
  749. , file: file
  750. , pattern: pattern })
  751. }
  752. if (options.matchBase && pattern.length === 1) {
  753. file = path.basename(file.join("/")).split("/")
  754. }
  755. if (options.debug) {
  756. console.error("matchOne", file.length, pattern.length)
  757. }
  758. for ( var fi = 0
  759. , pi = 0
  760. , fl = file.length
  761. , pl = pattern.length
  762. ; (fi < fl) && (pi < pl)
  763. ; fi ++, pi ++ ) {
  764. if (options.debug) {
  765. console.error("matchOne loop")
  766. }
  767. var p = pattern[pi]
  768. , f = file[fi]
  769. if (options.debug) {
  770. console.error(pattern, p, f)
  771. }
  772. // should be impossible.
  773. // some invalid regexp stuff in the set.
  774. if (p === false) return false
  775. if (p === GLOBSTAR) {
  776. if (options.debug)
  777. console.error('GLOBSTAR', [pattern, p, f])
  778. // "**"
  779. // a/**/b/**/c would match the following:
  780. // a/b/x/y/z/c
  781. // a/x/y/z/b/c
  782. // a/b/x/b/x/c
  783. // a/b/c
  784. // To do this, take the rest of the pattern after
  785. // the **, and see if it would match the file remainder.
  786. // If so, return success.
  787. // If not, the ** "swallows" a segment, and try again.
  788. // This is recursively awful.
  789. //
  790. // a/**/b/**/c matching a/b/x/y/z/c
  791. // - a matches a
  792. // - doublestar
  793. // - matchOne(b/x/y/z/c, b/**/c)
  794. // - b matches b
  795. // - doublestar
  796. // - matchOne(x/y/z/c, c) -> no
  797. // - matchOne(y/z/c, c) -> no
  798. // - matchOne(z/c, c) -> no
  799. // - matchOne(c, c) yes, hit
  800. var fr = fi
  801. , pr = pi + 1
  802. if (pr === pl) {
  803. if (options.debug)
  804. console.error('** at the end')
  805. // a ** at the end will just swallow the rest.
  806. // We have found a match.
  807. // however, it will not swallow /.x, unless
  808. // options.dot is set.
  809. // . and .. are *never* matched by **, for explosively
  810. // exponential reasons.
  811. for ( ; fi < fl; fi ++) {
  812. if (file[fi] === "." || file[fi] === ".." ||
  813. (!options.dot && file[fi].charAt(0) === ".")) return false
  814. }
  815. return true
  816. }
  817. // ok, let's see if we can swallow whatever we can.
  818. WHILE: while (fr < fl) {
  819. var swallowee = file[fr]
  820. if (options.debug) {
  821. console.error('\nglobstar while',
  822. file, fr, pattern, pr, swallowee)
  823. }
  824. // XXX remove this slice. Just pass the start index.
  825. if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
  826. if (options.debug)
  827. console.error('globstar found match!', fr, fl, swallowee)
  828. // found a match.
  829. return true
  830. } else {
  831. // can't swallow "." or ".." ever.
  832. // can only swallow ".foo" when explicitly asked.
  833. if (swallowee === "." || swallowee === ".." ||
  834. (!options.dot && swallowee.charAt(0) === ".")) {
  835. if (options.debug)
  836. console.error("dot detected!", file, fr, pattern, pr)
  837. break WHILE
  838. }
  839. // ** swallows a segment, and continue.
  840. if (options.debug)
  841. console.error('globstar swallow a segment, and continue')
  842. fr ++
  843. }
  844. }
  845. // no match was found.
  846. // However, in partial mode, we can't say this is necessarily over.
  847. // If there's more *pattern* left, then
  848. if (partial) {
  849. // ran out of file
  850. // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
  851. if (fr === fl) return true
  852. }
  853. return false
  854. }
  855. // something other than **
  856. // non-magic patterns just have to match exactly
  857. // patterns with magic have been turned into regexps.
  858. var hit
  859. if (typeof p === "string") {
  860. if (options.nocase) {
  861. hit = f.toLowerCase() === p.toLowerCase()
  862. } else {
  863. hit = f === p
  864. }
  865. if (options.debug) {
  866. console.error("string match", p, f, hit)
  867. }
  868. } else {
  869. hit = f.match(p)
  870. if (options.debug) {
  871. console.error("pattern match", p, f, hit)
  872. }
  873. }
  874. if (!hit) return false
  875. }
  876. // Note: ending in / means that we'll get a final ""
  877. // at the end of the pattern. This can only match a
  878. // corresponding "" at the end of the file.
  879. // If the file ends in /, then it can only match a
  880. // a pattern that ends in /, unless the pattern just
  881. // doesn't have any more for it. But, a/b/ should *not*
  882. // match "a/b/*", even though "" matches against the
  883. // [^/]*? pattern, except in partial mode, where it might
  884. // simply not be reached yet.
  885. // However, a/b/ should still satisfy a/*
  886. // now either we fell off the end of the pattern, or we're done.
  887. if (fi === fl && pi === pl) {
  888. // ran out of pattern and filename at the same time.
  889. // an exact hit!
  890. return true
  891. } else if (fi === fl) {
  892. // ran out of file, but still had pattern left.
  893. // this is ok if we're doing the match as part of
  894. // a glob fs traversal.
  895. return partial
  896. } else if (pi === pl) {
  897. // ran out of pattern, still have file left.
  898. // this is only acceptable if we're on the very last
  899. // empty segment of a file with a trailing slash.
  900. // a/* should match a/b/
  901. var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
  902. return emptyFileEnd
  903. }
  904. // should be unreachable.
  905. throw new Error("wtf?")
  906. }
  907. // replace stuff like \* with *
  908. function globUnescape (s) {
  909. return s.replace(/\\(.)/g, "$1")
  910. }
  911. function regExpEscape (s) {
  912. return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
  913. }
  914. })( typeof require === "function" ? require : null,
  915. this,
  916. typeof module === "object" ? module : null,
  917. typeof process === "object" ? process.platform : "win32"
  918. )