Skip to content

Commit

Permalink
Replace node-glob by fast-glob (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdlg authored and sindresorhus committed Feb 13, 2018
1 parent 4fdf133 commit ba08350
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 27 deletions.
15 changes: 11 additions & 4 deletions gitignore.js
@@ -1,12 +1,19 @@
'use strict';
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const fastGlob = require('fast-glob');
const gitIgnore = require('ignore');
const pify = require('pify');
const slash = require('slash');

const globP = pify(glob);
const DEFAULT_IGNORE = [
'**/node_modules/**',
'**/bower_components/**',
'**/flow-typed/**',
'**/coverage/**',
'**/.git'
];

const readFileP = pify(fs.readFile);

const mapGitIgnorePatternTo = base => ignore => {
Expand Down Expand Up @@ -72,7 +79,7 @@ const normalizeOpts = opts => {
module.exports = o => {
const opts = normalizeOpts(o);

return globP('**/.gitignore', {ignore: opts.ignore, cwd: opts.cwd})
return fastGlob('**/.gitignore', {ignore: DEFAULT_IGNORE.concat(opts.ignore), cwd: opts.cwd})
.then(paths => Promise.all(paths.map(file => getFile(file, opts.cwd))))
.then(files => reduceIgnore(files))
.then(ignores => getIsIgnoredPredecate(ignores, opts.cwd));
Expand All @@ -81,7 +88,7 @@ module.exports = o => {
module.exports.sync = o => {
const opts = normalizeOpts(o);

const paths = glob.sync('**/.gitignore', {ignore: opts.ignore, cwd: opts.cwd});
const paths = fastGlob.sync('**/.gitignore', {ignore: DEFAULT_IGNORE.concat(opts.ignore), cwd: opts.cwd});
const files = paths.map(file => getFileSync(file, opts.cwd));
const ignores = reduceIgnore(files);
return getIsIgnoredPredecate(ignores, opts.cwd);
Expand Down
11 changes: 3 additions & 8 deletions index.js
@@ -1,11 +1,10 @@
'use strict';
const arrayUnion = require('array-union');
const glob = require('glob');
const pify = require('pify');
const fastGlob = require('fast-glob');
const dirGlob = require('dir-glob');
const gitignore = require('./gitignore');

const globP = pify(glob);
const DEFAULT_FILTER = () => false;

const isNegative = pattern => pattern[0] === '!';
Expand All @@ -23,10 +22,6 @@ const generateGlobTasks = (patterns, taskOpts) => {
const globTasks = [];

taskOpts = Object.assign({
cache: Object.create(null),
statCache: Object.create(null),
realpathCache: Object.create(null),
symlinks: Object.create(null),
ignore: [],
expandDirectories: true,
nodir: true
Expand Down Expand Up @@ -94,7 +89,7 @@ module.exports = (patterns, opts) => {
return getFilter()
.then(filter => {
return getTasks
.then(tasks => Promise.all(tasks.map(task => globP(task.pattern, task.opts))))
.then(tasks => Promise.all(tasks.map(task => fastGlob(task.pattern, task.opts))))
.then(paths => arrayUnion.apply(null, paths))
.then(paths => paths.filter(p => !filter(p)));
});
Expand All @@ -120,7 +115,7 @@ module.exports.sync = (patterns, opts) => {
const filter = getFilter();

return tasks.reduce(
(matches, task) => arrayUnion(matches, glob.sync(task.pattern, task.opts)),
(matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.opts)),
[]
).filter(p => !filter(p));
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -57,14 +57,14 @@
"dependencies": {
"array-union": "^1.0.1",
"dir-glob": "^2.0.0",
"fast-glob": "^2.0.2",
"glob": "^7.1.2",
"ignore": "^3.3.5",
"pify": "^3.0.0",
"slash": "^1.0.0"
},
"devDependencies": {
"ava": "*",
"fast-glob": "^2.0.1",
"glob-stream": "^6.1.0",
"globby": "sindresorhus/globby#master",
"matcha": "^0.7.0",
Expand Down
10 changes: 5 additions & 5 deletions readme.md
Expand Up @@ -2,7 +2,7 @@

> User-friendly glob matching
Based on [`glob`](https://github.com/isaacs/node-glob), but adds a bunch of useful features and a nicer API.
Based on [`fast-glob`](https://github.com/mrmlnc/fast-glob), but adds a bunch of useful features and a nicer API.


## Features
Expand Down Expand Up @@ -57,9 +57,7 @@ See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage).

Type: `Object`

See the [`node-glob` options](https://github.com/isaacs/node-glob#options) in addition to the ones below.

One difference is that `nodir` is `true` by default here.
See the [`fast-glob` options](https://github.com/mrmlnc/fast-glob#options) in addition to the ones below.

##### expandDirectories

Expand Down Expand Up @@ -97,7 +95,7 @@ Returns an `Array` of matching paths.

### globby.generateGlobTasks(patterns, [options])

Returns an `Array<Object>` in the format `{pattern: string, opts: Object}`, which can be passed as arguments to [`node-glob`](https://github.com/isaacs/node-glob). This is useful for other globbing-related packages.
Returns an `Array<Object>` in the format `{pattern: string, opts: Object}`, which can be passed as arguments to [`fast-glob`](https://github.com/mrmlnc/fast-glob). This is useful for other globbing-related packages.

Note that you should avoid running the same tasks multiple times as they contain a file system cache. Instead, run this method each time to ensure file system changes are taken into consideration.

Expand All @@ -107,6 +105,8 @@ Returns a `boolean` of whether there are any special glob characters in the `pat

Note that the options affect the results. If `noext: true` is set, then `+(a|b)` will not be considered a magic pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}`, then that is considered magical, unless `nobrace: true` is set.

This function is backed by [`node-glob`](https://github.com/isaacs/node-glob#globhasmagicpattern-options)

### globby.gitignore([options])

Returns a `Promise<(path: string) => boolean>` indicating whether a given path is ignored via a `.gitignore` file.
Expand Down
28 changes: 19 additions & 9 deletions test.js
Expand Up @@ -42,6 +42,10 @@ test('respect patterns order - async', async t => {
t.deepEqual(await m(['!*.tmp', 'a.tmp']), ['a.tmp']);
});

test('respect patterns order - sync', t => {
t.deepEqual(m.sync(['!*.tmp', 'a.tmp']), ['a.tmp']);
});

test('glob - sync', t => {
t.deepEqual(m.sync('*.tmp'), ['a.tmp', 'b.tmp', 'c.tmp', 'd.tmp', 'e.tmp']);
t.deepEqual(m.sync(['a.tmp', '*.tmp', '!{c,d,e}.tmp']), ['a.tmp', 'b.tmp']);
Expand Down Expand Up @@ -109,9 +113,15 @@ test('expandDirectories option', t => {
}), ['tmp/a.tmp']);
});

test('expandDirectories:true and nodir:true option', t => {
t.deepEqual(m.sync('tmp', {nodir: true}), ['tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']);
t.deepEqual(m.sync('tmp', {nodir: false}), ['tmp', 'tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']);
test('expandDirectories:true and onlyFiles:true option', t => {
t.deepEqual(m.sync('tmp', {onlyFiles: true}), ['tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']);
});

test.failing('expandDirectories:true and onlyFiles:false option', t => {
// Node-glob('tmp/**') => ['tmp', 'tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']
// Fast-glob('tmp/**') => ['tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']
// See https://github.com/mrmlnc/fast-glob/issues/47
t.deepEqual(m.sync('tmp', {onlyFiles: false}), ['tmp', 'tmp/a.tmp', 'tmp/b.tmp', 'tmp/c.tmp', 'tmp/d.tmp', 'tmp/e.tmp']);
});

// Rejected for being an invalid pattern
Expand Down Expand Up @@ -155,31 +165,31 @@ test('expandDirectories:true and nodir:true option', t => {
});

test('gitignore option defaults to false', async t => {
const actual = await m('*', {nodir: false});
const actual = await m('*', {onlyFiles: false});
t.true(actual.indexOf('node_modules') > -1);
});

test('gitignore option defaults to false - sync', t => {
const actual = m.sync('*', {nodir: false});
const actual = m.sync('*', {onlyFiles: false});
t.true(actual.indexOf('node_modules') > -1);
});

test('respects gitignore option true', async t => {
const actual = await m('*', {gitignore: true, nodir: false});
const actual = await m('*', {gitignore: true, onlyFiles: false});
t.false(actual.indexOf('node_modules') > -1);
});

test('respects gitignore option true - sync', t => {
const actual = m.sync('*', {gitignore: true, nodir: false});
const actual = m.sync('*', {gitignore: true, onlyFiles: false});
t.false(actual.indexOf('node_modules') > -1);
});

test('respects gitignore option false', async t => {
const actual = await m('*', {gitignore: false, nodir: false});
const actual = await m('*', {gitignore: false, onlyFiles: false});
t.true(actual.indexOf('node_modules') > -1);
});

test('respects gitignore option false - sync', t => {
const actual = m.sync('*', {gitignore: false, nodir: false});
const actual = m.sync('*', {gitignore: false, onlyFiles: false});
t.true(actual.indexOf('node_modules') > -1);
});

0 comments on commit ba08350

Please sign in to comment.