Skip to content

Commit

Permalink
update benchmarks, upgrade devDependencies, lint
Browse files Browse the repository at this point in the history
  • Loading branch information
jonschlinkert committed Feb 8, 2024
1 parent 4bc439e commit 335eac6
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 86 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ vendor
temp
tmp
TODO.md
package-lock.json
package-lock.json
*.code-*
60 changes: 37 additions & 23 deletions .verb.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,11 @@ The following options may be used with the main `picomatch()` function or any of
| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. |
| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. |
| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. |
| `flags` | `boolean` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. |
| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. |
| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. |
| `ignore` | `array|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. |
| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. |
| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. |
| `lookbehinds` | `boolean` | `true` | Support regex positive and negative lookbehinds. Note that you must be using Node 8.1.10 or higher to enable regex lookbehinds. |
| `matchBase` | `boolean` | `false` | Alias for `basename` |
| `maxLength` | `boolean` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. |
| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. |
Expand All @@ -129,6 +128,7 @@ The following options may be used with the main `picomatch()` function or any of
| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. |
| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. |
| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. |
| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. |

### Scan Options

Expand Down Expand Up @@ -315,9 +315,9 @@ console.log(pm.isMatch('az', 'a*(z)')); // true
console.log(pm.isMatch('azzz', 'a*(z)')); // true

// +(pattern) matches ONE or more of "pattern"
console.log(pm.isMatch('a', 'a*(z)')); // true
console.log(pm.isMatch('az', 'a*(z)')); // true
console.log(pm.isMatch('azzz', 'a*(z)')); // true
console.log(pm.isMatch('a', 'a+(z)')); // false
console.log(pm.isMatch('az', 'a+(z)')); // true
console.log(pm.isMatch('azzz', 'a+(z)')); // true

// supports multiple extglobs
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false
Expand Down Expand Up @@ -407,30 +407,44 @@ The following table shows which features are supported by [minimatch][], [microm

Performance comparison of picomatch and minimatch.

_(Pay special attention to the last three benchmarks. Minimatch freezes on long ranges.)_

```
# .makeRe star
picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled)
minimatch x 627,206 ops/sec ±1.96% (87 runs sampled))
# .makeRe star (*)
picomatch x 4,449,159 ops/sec ±0.24% (97 runs sampled)
minimatch x 632,772 ops/sec ±0.14% (98 runs sampled)
# .makeRe star; dot=true (*)
picomatch x 3,500,079 ops/sec ±0.26% (99 runs sampled)
minimatch x 564,916 ops/sec ±0.23% (96 runs sampled)
# .makeRe globstar (**)
picomatch x 3,261,000 ops/sec ±0.27% (98 runs sampled)
minimatch x 1,664,766 ops/sec ±0.20% (100 runs sampled)
# .makeRe globstars (**/**/**)
picomatch x 3,284,469 ops/sec ±0.18% (97 runs sampled)
minimatch x 1,435,880 ops/sec ±0.34% (95 runs sampled)
# .makeRe star; dot=true
picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled)
minimatch x 525,876 ops/sec ±0.60% (88 runs sampled)
# .makeRe with leading star (*.txt)
picomatch x 3,100,197 ops/sec ±0.35% (99 runs sampled)
minimatch x 428,347 ops/sec ±0.42% (94 runs sampled)
# .makeRe globstar
picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled)
minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d)
# .makeRe - basic braces ({a,b,c}*.txt)
picomatch x 443,578 ops/sec ±1.33% (89 runs sampled)
minimatch x 107,143 ops/sec ±0.35% (94 runs sampled)
# .makeRe globstars
picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled)
minimatch x 477,179 ops/sec ±1.33% (91 runs sampled)
# .makeRe - short ranges ({a..z}*.txt)
picomatch x 415,484 ops/sec ±0.76% (96 runs sampled)
minimatch x 14,299 ops/sec ±0.26% (96 runs sampled)
# .makeRe with leading star
picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled)
minimatch x 453,564 ops/sec ±1.43% (94 runs sampled)
# .makeRe - medium ranges ({1..100000}*.txt)
picomatch x 395,020 ops/sec ±0.87% (89 runs sampled)
minimatch x 2 ops/sec ±4.59% (10 runs sampled)
# .makeRe - basic braces
picomatch x 392,067 ops/sec ±0.70% (90 runs sampled)
minimatch x 99,532 ops/sec ±2.03% (87 runs sampled))
# .makeRe - long ranges ({1..10000000}*.txt)
picomatch x 400,036 ops/sec ±0.83% (90 runs sampled)
minimatch (FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory)
```


Expand Down
74 changes: 42 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ console.log(isMatch('a/b.js')); //=> false

## API

### [picomatch](lib/picomatch.js#L32)
### [picomatch](lib/picomatch.js#L31)

Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information.

Expand All @@ -119,8 +119,6 @@ Creates a matcher function from one or more glob patterns. The returned function

**Example**

By default, `picomatch` uses [`os.platform()`](https://nodejs.org/api/os.html#osplatform) to detect the operating system.

```js
const picomatch = require('picomatch');
// picomatch(glob[, options]);
Expand All @@ -147,7 +145,7 @@ console.log(isMatch('a\\b')); //=> true
console.log(isMatch('a/b')); //=> true
```

### [.test](lib/picomatch.js#L117)
### [.test](lib/picomatch.js#L116)

Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string.

Expand All @@ -167,7 +165,7 @@ console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
```

### [.matchBase](lib/picomatch.js#L161)
### [.matchBase](lib/picomatch.js#L160)

Match the basename of a filepath.

Expand All @@ -185,7 +183,7 @@ const picomatch = require('picomatch');
console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
```
### [.isMatch](lib/picomatch.js#L183)
### [.isMatch](lib/picomatch.js#L182)
Returns true if **any** of the given glob `patterns` match the specified `string`.
Expand All @@ -206,7 +204,7 @@ console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
```
### [.parse](lib/picomatch.js#L199)
### [.parse](lib/picomatch.js#L198)
Parse a glob pattern to create the source string for a regular expression.
Expand All @@ -223,7 +221,7 @@ const picomatch = require('picomatch');
const result = picomatch.parse(pattern[, options]);
```
### [.scan](lib/picomatch.js#L231)
### [.scan](lib/picomatch.js#L230)
Scan a glob pattern to separate the pattern into segments.
Expand Down Expand Up @@ -254,7 +252,7 @@ console.log(result);
negated: true }
```
### [.compileRe](lib/picomatch.js#L245)
### [.compileRe](lib/picomatch.js#L244)
Compile a regular expression from the `state` object returned by the
[parse()](#parse) method.
Expand All @@ -267,7 +265,7 @@ Compile a regular expression from the `state` object returned by the
* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
* `returns` **{RegExp}**
### [.makeRe](lib/picomatch.js#L286)
### [.makeRe](lib/picomatch.js#L285)
Create a regular expression from a parsed glob pattern.
Expand All @@ -290,7 +288,7 @@ console.log(picomatch.compileRe(state));
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
```
### [.toRegex](lib/picomatch.js#L321)
### [.toRegex](lib/picomatch.js#L320)
Create a regular expression from the given regex source string.
Expand Down Expand Up @@ -358,9 +356,7 @@ The following options may be used with the main `picomatch()` function or any of
| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. |
| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. |
| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. |
| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. |

picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error.
| `windows` | `boolean` | `false` | Also accept backslashes as the path separator. |

### Scan Options

Expand Down Expand Up @@ -633,30 +629,44 @@ The following table shows which features are supported by [minimatch](https://gi
Performance comparison of picomatch and minimatch.
_(Pay special attention to the last three benchmarks. Minimatch freezes on long ranges.)_
```
# .makeRe star
picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled)
minimatch x 627,206 ops/sec ±1.96% (87 runs sampled))
# .makeRe star (*)
picomatch x 4,449,159 ops/sec ±0.24% (97 runs sampled)
minimatch x 632,772 ops/sec ±0.14% (98 runs sampled)
# .makeRe star; dot=true (*)
picomatch x 3,500,079 ops/sec ±0.26% (99 runs sampled)
minimatch x 564,916 ops/sec ±0.23% (96 runs sampled)
# .makeRe globstar (**)
picomatch x 3,261,000 ops/sec ±0.27% (98 runs sampled)
minimatch x 1,664,766 ops/sec ±0.20% (100 runs sampled)
# .makeRe globstars (**/**/**)
picomatch x 3,284,469 ops/sec ±0.18% (97 runs sampled)
minimatch x 1,435,880 ops/sec ±0.34% (95 runs sampled)
# .makeRe star; dot=true
picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled)
minimatch x 525,876 ops/sec ±0.60% (88 runs sampled)
# .makeRe with leading star (*.txt)
picomatch x 3,100,197 ops/sec ±0.35% (99 runs sampled)
minimatch x 428,347 ops/sec ±0.42% (94 runs sampled)
# .makeRe globstar
picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled)
minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d)
# .makeRe - basic braces ({a,b,c}*.txt)
picomatch x 443,578 ops/sec ±1.33% (89 runs sampled)
minimatch x 107,143 ops/sec ±0.35% (94 runs sampled)
# .makeRe globstars
picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled)
minimatch x 477,179 ops/sec ±1.33% (91 runs sampled)
# .makeRe - short ranges ({a..z}*.txt)
picomatch x 415,484 ops/sec ±0.76% (96 runs sampled)
minimatch x 14,299 ops/sec ±0.26% (96 runs sampled)
# .makeRe with leading star
picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled)
minimatch x 453,564 ops/sec ±1.43% (94 runs sampled)
# .makeRe - medium ranges ({1..100000}*.txt)
picomatch x 395,020 ops/sec ±0.87% (89 runs sampled)
minimatch x 2 ops/sec ±4.59% (10 runs sampled)
# .makeRe - basic braces
picomatch x 392,067 ops/sec ±0.70% (90 runs sampled)
minimatch x 99,532 ops/sec ±2.03% (87 runs sampled))
# .makeRe - long ranges ({1..10000000}*.txt)
picomatch x 400,036 ops/sec ±0.83% (90 runs sampled)
minimatch (FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory)
```
<br>
Expand Down
27 changes: 21 additions & 6 deletions bench/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,32 +43,47 @@ const bench = (name, options) => {
return suite;
};

bench(`${red('.makeRe')} star`)
bench(`${red('.makeRe')} star (*)`)
.add('picomatch', () => pm.makeRe('*'))
.add('minimatch', () => mm.makeRe('*'))
.run();

bench(`${red('.makeRe')} star; dot=true`)
bench(`${red('.makeRe')} star; dot=true (*)`)
.add('picomatch', () => pm.makeRe('*', { dot: true }))
.add('minimatch', () => mm.makeRe('*', { dot: true }))
.run();

bench(`${red('.makeRe')} globstar`)
bench(`${red('.makeRe')} globstar (**)`)
.add('picomatch', () => pm.makeRe('**'))
.add('minimatch', () => mm.makeRe('**'))
.run();

bench(`${red('.makeRe')} globstars`)
bench(`${red('.makeRe')} globstars (**/**/**)`)
.add('picomatch', () => pm.makeRe('**/**/**'))
.add('minimatch', () => mm.makeRe('**/**/**'))
.run();

bench(`${red('.makeRe')} with leading star`)
bench(`${red('.makeRe')} with leading star (*.txt)`)
.add('picomatch', () => pm.makeRe('*.txt'))
.add('minimatch', () => mm.makeRe('*.txt'))
.run();

bench(`${red('.makeRe')} - basic braces`)
bench(`${red('.makeRe')} - basic braces ({a,b,c}*.txt)`)
.add('picomatch', () => pm.makeRe('{a,b,c}*.txt'))
.add('minimatch', () => mm.makeRe('{a,b,c}*.txt'))
.run();

bench(`${red('.makeRe')} - short ranges ({a..z}*.txt)`)
.add('picomatch', () => pm.makeRe('{a..z}*.txt'))
.add('minimatch', () => mm.makeRe('{a..z}*.txt'))
.run();

bench(`${red('.makeRe')} - medium ranges ({1..100000}*.txt)`)
.add('picomatch', () => pm.makeRe('{1..100000}*.txt'))
.add('minimatch', () => mm.makeRe('{1..100000}*.txt'))
.run();

bench(`${red('.makeRe')} - long ranges ({1..10000000}*.txt)`)
.add('picomatch', () => pm.makeRe('{1..10000000}*.txt'))
.add('minimatch', () => mm.makeRe('{1..10000000}*.txt'))
.run();
4 changes: 2 additions & 2 deletions bench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"minimist": "^1.2.0"
},
"devDependencies": {
"glob-parent": "^3.1.0",
"minimatch": "^3.0.4"
"glob-parent": "^6.0.2",
"minimatch": "^9.0.3"
},
"lintDeps": {
"devDependencies": {
Expand Down
31 changes: 13 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,28 @@

const pico = require('./lib/picomatch');

function isWindows() {
const isWindows = () => {
if (typeof navigator !== 'undefined' && navigator.platform) {
return navigator.platform.toLowerCase().indexOf('win') !== -1;
} else if (typeof process !== 'undefined' && process.platform) {
return process.platform.toLowerCase().indexOf('win') !== -1;
} else return false;
}
const platform = navigator.platform.toLowerCase();
return platform === 'win32' || platform === 'windows';
}

const windows = isWindows();
if (typeof process !== 'undefined' && process.platform) {
return process.platform === 'win32';
}

return false;
};

function picomatch(glob, options, returnState = false) {
// default to os.platform()
if (options && (options.windows === null || options.windows === undefined)) {
// don't mutate the original options object
options = { ...options, windows };
options = { ...options, windows: isWindows() };
}

return pico(glob, options, returnState);
}

Object.assign(picomatch, pico);
module.exports = picomatch;
// public api
module.exports.test = pico.test;
module.exports.matchBase = pico.matchBase;
module.exports.isMatch = pico.isMatch;
module.exports.parse = pico.parse;
module.exports.scan = pico.scan;
module.exports.compileRe = pico.compileRe;
module.exports.toRegex = pico.toRegex;
// for tests
module.exports.makeRe = pico.makeRe;
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
"test:cover": "nyc npm run mocha"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint": "^8.56.0",
"fill-range": "^7.0.1",
"gulp-format-md": "^2.0.0",
"mocha": "^6.2.2",
"nyc": "^15.0.0",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"time-require": "github:jonschlinkert/time-require"
},
"keywords": [
Expand Down
Loading

0 comments on commit 335eac6

Please sign in to comment.