minimatch 3.0.0 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -9
  2. package/minimatch.js +102 -62
  3. package/package.json +7 -6
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A minimal matching utility.
4
4
 
5
- [![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
5
+ [![Build Status](https://travis-ci.org/isaacs/minimatch.svg?branch=master)](http://travis-ci.org/isaacs/minimatch)
6
6
 
7
7
 
8
8
  This is the matching library used internally by npm.
@@ -37,7 +37,7 @@ See:
37
37
 
38
38
  ## Minimatch Class
39
39
 
40
- Create a minimatch object by instanting the `minimatch.Minimatch` class.
40
+ Create a minimatch object by instantiating the `minimatch.Minimatch` class.
41
41
 
42
42
  ```javascript
43
43
  var Minimatch = require("minimatch").Minimatch
@@ -82,13 +82,6 @@ var mm = new Minimatch(pattern, options)
82
82
 
83
83
  All other methods are internal, and will be called as necessary.
84
84
 
85
- ## Functions
86
-
87
- The top-level exported function has a `cache` property, which is an LRU
88
- cache set to store 100 items. So, calling these methods repeatedly
89
- with the same pattern and options will use the same Minimatch object,
90
- saving the cost of parsing it multiple times.
91
-
92
85
  ### minimatch(path, pattern, options)
93
86
 
94
87
  Main export. Tests a path against the pattern using the options.
package/minimatch.js CHANGED
@@ -1,32 +1,40 @@
1
1
  module.exports = minimatch
2
2
  minimatch.Minimatch = Minimatch
3
3
 
4
- var path = { sep: '/' }
5
- try {
6
- path = require('path')
7
- } catch (er) {}
4
+ const path = (() => { try { return require('path') } catch (e) {}})() || {
5
+ sep: '/'
6
+ }
7
+ minimatch.sep = path.sep
8
+
9
+ const GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
10
+ const expand = require('brace-expansion')
8
11
 
9
- var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
10
- var expand = require('brace-expansion')
12
+ const plTypes = {
13
+ '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
14
+ '?': { open: '(?:', close: ')?' },
15
+ '+': { open: '(?:', close: ')+' },
16
+ '*': { open: '(?:', close: ')*' },
17
+ '@': { open: '(?:', close: ')' }
18
+ }
11
19
 
12
20
  // any single thing other than /
13
21
  // don't need to escape / when using new RegExp()
14
- var qmark = '[^/]'
22
+ const qmark = '[^/]'
15
23
 
16
24
  // * => any number of characters
17
- var star = qmark + '*?'
25
+ const star = qmark + '*?'
18
26
 
19
27
  // ** when dots are allowed. Anything goes, except .. and .
20
28
  // not (^ or / followed by one or two dots followed by $ or /),
21
29
  // followed by anything, any number of times.
22
- var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
30
+ const twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
23
31
 
24
32
  // not a ^ or / followed by a dot,
25
33
  // followed by anything, any number of times.
26
- var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
34
+ const twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
27
35
 
28
36
  // characters that need to be escaped in RegExp.
29
- var reSpecials = charSet('().*{}+?[]^$\\!')
37
+ const reSpecials = charSet('().*{}+?[]^$\\!')
30
38
 
31
39
  // "abc" -> { a:true, b:true, c:true }
32
40
  function charSet (s) {
@@ -37,7 +45,7 @@ function charSet (s) {
37
45
  }
38
46
 
39
47
  // normalizes slashes.
40
- var slashSplit = /\/+/
48
+ const slashSplit = /\/+/
41
49
 
42
50
  minimatch.filter = filter
43
51
  function filter (pattern, options) {
@@ -50,41 +58,63 @@ function filter (pattern, options) {
50
58
  function ext (a, b) {
51
59
  a = a || {}
52
60
  b = b || {}
53
- var t = {}
54
- Object.keys(b).forEach(function (k) {
55
- t[k] = b[k]
56
- })
61
+ const t = {}
57
62
  Object.keys(a).forEach(function (k) {
58
63
  t[k] = a[k]
59
64
  })
65
+ Object.keys(b).forEach(function (k) {
66
+ t[k] = b[k]
67
+ })
60
68
  return t
61
69
  }
62
70
 
63
71
  minimatch.defaults = function (def) {
64
- if (!def || !Object.keys(def).length) return minimatch
72
+ if (!def || typeof def !== 'object' || !Object.keys(def).length) {
73
+ return minimatch
74
+ }
65
75
 
66
- var orig = minimatch
76
+ const orig = minimatch
67
77
 
68
- var m = function minimatch (p, pattern, options) {
69
- return orig.minimatch(p, pattern, ext(def, options))
78
+ const m = function minimatch (p, pattern, options) {
79
+ return orig(p, pattern, ext(def, options))
70
80
  }
71
81
 
72
82
  m.Minimatch = function Minimatch (pattern, options) {
73
83
  return new orig.Minimatch(pattern, ext(def, options))
74
84
  }
85
+ m.Minimatch.defaults = options => {
86
+ return orig.defaults(ext(def, options)).Minimatch
87
+ }
88
+
89
+ m.filter = function filter (pattern, options) {
90
+ return orig.filter(pattern, ext(def, options))
91
+ }
92
+
93
+ m.defaults = function defaults (options) {
94
+ return orig.defaults(ext(def, options))
95
+ }
96
+
97
+ m.makeRe = function makeRe (pattern, options) {
98
+ return orig.makeRe(pattern, ext(def, options))
99
+ }
100
+
101
+ m.braceExpand = function braceExpand (pattern, options) {
102
+ return orig.braceExpand(pattern, ext(def, options))
103
+ }
104
+
105
+ m.match = function (list, pattern, options) {
106
+ return orig.match(list, pattern, ext(def, options))
107
+ }
75
108
 
76
109
  return m
77
110
  }
78
111
 
79
112
  Minimatch.defaults = function (def) {
80
- if (!def || !Object.keys(def).length) return Minimatch
81
113
  return minimatch.defaults(def).Minimatch
82
114
  }
83
115
 
84
116
  function minimatch (p, pattern, options) {
85
- if (typeof pattern !== 'string') {
86
- throw new TypeError('glob pattern string required')
87
- }
117
+ assertValidPattern(pattern)
88
118
 
89
119
  if (!options) options = {}
90
120
 
@@ -104,9 +134,7 @@ function Minimatch (pattern, options) {
104
134
  return new Minimatch(pattern, options)
105
135
  }
106
136
 
107
- if (typeof pattern !== 'string') {
108
- throw new TypeError('glob pattern string required')
109
- }
137
+ assertValidPattern(pattern)
110
138
 
111
139
  if (!options) options = {}
112
140
  pattern = pattern.trim()
@@ -234,12 +262,9 @@ function braceExpand (pattern, options) {
234
262
  pattern = typeof pattern === 'undefined'
235
263
  ? this.pattern : pattern
236
264
 
237
- if (typeof pattern === 'undefined') {
238
- throw new Error('undefined pattern')
239
- }
265
+ assertValidPattern(pattern)
240
266
 
241
- if (options.nobrace ||
242
- !pattern.match(/\{.*\}/)) {
267
+ if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
243
268
  // shortcut. no need to expand.
244
269
  return [pattern]
245
270
  }
@@ -247,6 +272,17 @@ function braceExpand (pattern, options) {
247
272
  return expand(pattern)
248
273
  }
249
274
 
275
+ const MAX_PATTERN_LENGTH = 1024 * 64
276
+ const assertValidPattern = pattern => {
277
+ if (typeof pattern !== 'string') {
278
+ throw new TypeError('invalid pattern')
279
+ }
280
+
281
+ if (pattern.length > MAX_PATTERN_LENGTH) {
282
+ throw new TypeError('pattern is too long')
283
+ }
284
+ }
285
+
250
286
  // parse a component of the expanded set.
251
287
  // At this point, no pattern may contain "/" in it
252
288
  // so we're going to return a 2d array, where each entry is the full
@@ -259,8 +295,10 @@ function braceExpand (pattern, options) {
259
295
  // of * is equivalent to a single *. Globstar behavior is enabled by
260
296
  // default, and can be disabled by setting options.noglobstar.
261
297
  Minimatch.prototype.parse = parse
262
- var SUBPARSE = {}
298
+ const SUBPARSE = {}
263
299
  function parse (pattern, isSub) {
300
+ assertValidPattern(pattern)
301
+
264
302
  var options = this.options
265
303
 
266
304
  // shortcuts
@@ -268,12 +306,11 @@ function parse (pattern, isSub) {
268
306
  if (pattern === '') return ''
269
307
 
270
308
  var re = ''
271
- var hasMagic = !!options.nocase
309
+ var hasMagic = false
272
310
  var escaping = false
273
311
  // ? => one single character
274
312
  var patternListStack = []
275
313
  var negativeLists = []
276
- var plType
277
314
  var stateChar
278
315
  var inClass = false
279
316
  var reClassStart = -1
@@ -321,10 +358,11 @@ function parse (pattern, isSub) {
321
358
  }
322
359
 
323
360
  switch (c) {
324
- case '/':
361
+ case '/': /* istanbul ignore next */ {
325
362
  // completely not allowed, even escaped.
326
363
  // Should already be path-split by now.
327
364
  return false
365
+ }
328
366
 
329
367
  case '\\':
330
368
  clearStateChar()
@@ -372,11 +410,12 @@ function parse (pattern, isSub) {
372
410
  continue
373
411
  }
374
412
 
375
- plType = stateChar
376
413
  patternListStack.push({
377
- type: plType,
414
+ type: stateChar,
378
415
  start: i - 1,
379
- reStart: re.length
416
+ reStart: re.length,
417
+ open: plTypes[stateChar].open,
418
+ close: plTypes[stateChar].close
380
419
  })
381
420
  // negation is (?:(?!js)[^/]*)
382
421
  re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
@@ -392,24 +431,14 @@ function parse (pattern, isSub) {
392
431
 
393
432
  clearStateChar()
394
433
  hasMagic = true
395
- re += ')'
396
434
  var pl = patternListStack.pop()
397
- plType = pl.type
398
435
  // negation is (?:(?!js)[^/]*)
399
436
  // The others are (?:<pattern>)<type>
400
- switch (plType) {
401
- case '!':
402
- negativeLists.push(pl)
403
- re += ')[^/]*?)'
404
- pl.reEnd = re.length
405
- break
406
- case '?':
407
- case '+':
408
- case '*':
409
- re += plType
410
- break
411
- case '@': break // the default anyway
437
+ re += pl.close
438
+ if (pl.type === '!') {
439
+ negativeLists.push(pl)
412
440
  }
441
+ pl.reEnd = re.length
413
442
  continue
414
443
 
415
444
  case '|':
@@ -516,9 +545,10 @@ function parse (pattern, isSub) {
516
545
  // Go through and escape them, taking care not to double-escape any
517
546
  // | chars that were already escaped.
518
547
  for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
519
- var tail = re.slice(pl.reStart + 3)
548
+ var tail = re.slice(pl.reStart + pl.open.length)
549
+ this.debug('setting tail', re, pl)
520
550
  // maybe some even number of \, then maybe 1 \, followed by a |
521
- tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
551
+ tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
522
552
  if (!$2) {
523
553
  // the | isn't already escaped, so escape it.
524
554
  $2 = '\\'
@@ -533,7 +563,7 @@ function parse (pattern, isSub) {
533
563
  return $1 + $1 + $2 + '|'
534
564
  })
535
565
 
536
- this.debug('tail=%j\n %s', tail, tail)
566
+ this.debug('tail=%j\n %s', tail, tail, pl, re)
537
567
  var t = pl.type === '*' ? star
538
568
  : pl.type === '?' ? qmark
539
569
  : '\\' + pl.type
@@ -615,7 +645,15 @@ function parse (pattern, isSub) {
615
645
  }
616
646
 
617
647
  var flags = options.nocase ? 'i' : ''
618
- var regExp = new RegExp('^' + re + '$', flags)
648
+ try {
649
+ var regExp = new RegExp('^' + re + '$', flags)
650
+ } catch (er) /* istanbul ignore next - should be impossible */ {
651
+ // If it was an invalid regular expression, then it can't match
652
+ // anything. This trick looks for a character after the end of
653
+ // the string, which is of course impossible, except in multi-line
654
+ // mode, but it's not a /m regex.
655
+ return new RegExp('$.')
656
+ }
619
657
 
620
658
  regExp._glob = pattern
621
659
  regExp._src = re
@@ -667,7 +705,7 @@ function makeRe () {
667
705
 
668
706
  try {
669
707
  this.regexp = new RegExp(re, flags)
670
- } catch (ex) {
708
+ } catch (ex) /* istanbul ignore next - should be impossible */ {
671
709
  this.regexp = false
672
710
  }
673
711
  return this.regexp
@@ -675,7 +713,7 @@ function makeRe () {
675
713
 
676
714
  minimatch.match = function (list, pattern, options) {
677
715
  options = options || {}
678
- var mm = new Minimatch(pattern, options)
716
+ const mm = new Minimatch(pattern, options)
679
717
  list = list.filter(function (f) {
680
718
  return mm.match(f)
681
719
  })
@@ -768,6 +806,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
768
806
 
769
807
  // should be impossible.
770
808
  // some invalid regexp stuff in the set.
809
+ /* istanbul ignore if */
771
810
  if (p === false) return false
772
811
 
773
812
  if (p === GLOBSTAR) {
@@ -841,6 +880,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
841
880
  // no match was found.
842
881
  // However, in partial mode, we can't say this is necessarily over.
843
882
  // If there's more *pattern* left, then
883
+ /* istanbul ignore if */
844
884
  if (partial) {
845
885
  // ran out of file
846
886
  this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
@@ -889,16 +929,16 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
889
929
  // this is ok if we're doing the match as part of
890
930
  // a glob fs traversal.
891
931
  return partial
892
- } else if (pi === pl) {
932
+ } else /* istanbul ignore else */ if (pi === pl) {
893
933
  // ran out of pattern, still have file left.
894
934
  // this is only acceptable if we're on the very last
895
935
  // empty segment of a file with a trailing slash.
896
936
  // a/* should match a/b/
897
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
898
- return emptyFileEnd
937
+ return (fi === fl - 1) && (file[fi] === '')
899
938
  }
900
939
 
901
940
  // should be unreachable.
941
+ /* istanbul ignore next */
902
942
  throw new Error('wtf?')
903
943
  }
904
944
 
package/package.json CHANGED
@@ -2,25 +2,26 @@
2
2
  "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
3
3
  "name": "minimatch",
4
4
  "description": "a glob matcher in javascript",
5
- "version": "3.0.0",
5
+ "version": "3.0.5",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git://github.com/isaacs/minimatch.git"
9
9
  },
10
10
  "main": "minimatch.js",
11
11
  "scripts": {
12
- "posttest": "standard minimatch.js test/*.js",
13
- "test": "tap test/*.js"
12
+ "test": "tap",
13
+ "preversion": "npm test",
14
+ "postversion": "npm publish",
15
+ "postpublish": "git push origin --all; git push origin --tags"
14
16
  },
15
17
  "engines": {
16
18
  "node": "*"
17
19
  },
18
20
  "dependencies": {
19
- "brace-expansion": "^1.0.0"
21
+ "brace-expansion": "^1.1.7"
20
22
  },
21
23
  "devDependencies": {
22
- "standard": "^3.7.2",
23
- "tap": "^1.2.0"
24
+ "tap": "^15.1.6"
24
25
  },
25
26
  "license": "ISC",
26
27
  "files": [