diff --git a/gitignore.js b/ignore.js similarity index 93% rename from gitignore.js rename to ignore.js index 2f77baa..ee6a142 100644 --- a/gitignore.js +++ b/ignore.js @@ -91,10 +91,10 @@ const normalizeOptions = ({ return {ignore, cwd}; }; -module.exports = async options => { +module.exports = async (pattern, options) => { options = normalizeOptions(options); - const paths = await fastGlob('**/.gitignore', { + const paths = await fastGlob(pattern, { ignore: DEFAULT_IGNORE.concat(options.ignore), cwd: options.cwd }); @@ -105,10 +105,10 @@ module.exports = async options => { return getIsIgnoredPredecate(ignores, options.cwd); }; -module.exports.sync = options => { +module.exports.sync = (pattern, options) => { options = normalizeOptions(options); - const paths = fastGlob.sync('**/.gitignore', { + const paths = fastGlob.sync(pattern, { ignore: DEFAULT_IGNORE.concat(options.ignore), cwd: options.cwd }); diff --git a/gitignore.test.js b/ignore.test.js similarity index 68% rename from gitignore.test.js rename to ignore.test.js index fd25b31..efd2a2a 100644 --- a/gitignore.test.js +++ b/ignore.test.js @@ -1,67 +1,69 @@ const path = require('path'); const test = require('ava'); const slash = require('slash'); -const gitignore = require('./gitignore'); +const ignoreFiles = require('./ignore'); -test('gitignore', async t => { +const gitignorePattern = '**/.gitignore'; + +test('ignore', async t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); - const isIgnored = await gitignore({cwd}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['bar.js']; t.deepEqual(actual, expected); }); -test('gitignore - mixed path styles', async t => { +test('ignore - mixed path styles', async t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); - const isIgnored = await gitignore({cwd}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd}); t.true(isIgnored(slash(path.resolve(cwd, 'foo.js')))); }); -test('gitignore - os paths', async t => { +test('ignore - os paths', async t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); - const isIgnored = await gitignore({cwd}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd}); t.true(isIgnored(path.resolve(cwd, 'foo.js'))); }); -test('gitignore - sync', t => { +test('ignore - sync', t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); - const isIgnored = gitignore.sync({cwd}); + const isIgnored = ignoreFiles.sync(gitignorePattern, {cwd}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['bar.js']; t.deepEqual(actual, expected); }); -test('ignore ignored .gitignore', async t => { +test('ignore ignored .ignore', async t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); const ignore = ['**/.gitignore']; - const isIgnored = await gitignore({cwd, ignore}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd, ignore}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['foo.js', 'bar.js']; t.deepEqual(actual, expected); }); -test('ignore ignored .gitignore - sync', t => { +test('ignore ignored .ignore - sync', t => { const cwd = path.join(__dirname, 'fixtures/gitignore'); const ignore = ['**/.gitignore']; - const isIgnored = gitignore.sync({cwd, ignore}); + const isIgnored = ignoreFiles.sync(gitignorePattern, {cwd, ignore}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['foo.js', 'bar.js']; t.deepEqual(actual, expected); }); -test('negative gitignore', async t => { +test('negative ignore', async t => { const cwd = path.join(__dirname, 'fixtures/negative'); - const isIgnored = await gitignore({cwd}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['foo.js']; t.deepEqual(actual, expected); }); -test('negative gitignore - sync', t => { +test('negative ignore - sync', t => { const cwd = path.join(__dirname, 'fixtures/negative'); - const isIgnored = gitignore.sync({cwd}); + const isIgnored = ignoreFiles.sync(gitignorePattern, {cwd}); const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file)); const expected = ['foo.js']; t.deepEqual(actual, expected); @@ -69,7 +71,7 @@ test('negative gitignore - sync', t => { test('multiple negation', async t => { const cwd = path.join(__dirname, 'fixtures/multiple-negation'); - const isIgnored = await gitignore({cwd}); + const isIgnored = await ignoreFiles(gitignorePattern, {cwd}); const actual = [ '!!!unicorn.js', @@ -84,7 +86,7 @@ test('multiple negation', async t => { test('multiple negation - sync', t => { const cwd = path.join(__dirname, 'fixtures/multiple-negation'); - const isIgnored = gitignore.sync({cwd}); + const isIgnored = ignoreFiles.sync(gitignorePattern, {cwd}); const actual = [ '!!!unicorn.js', diff --git a/index.d.ts b/index.d.ts index 1e2448b..76485fe 100644 --- a/index.d.ts +++ b/index.d.ts @@ -35,10 +35,19 @@ declare namespace globby { /** Respect ignore patterns in `.gitignore` files that apply to the globbed files. + This option takes precedence over the `ignoreFiles` option. @default false */ readonly gitignore?: boolean; + + /** + A glob pattern to look for ignore files, which are then used to ignore globbed files. This is a more generic form of the `gitignore` option, allowing you to find ignore files with a [compatible syntax](http://git-scm.com/docs/gitignore). For instance, this is works with Babel's `.babelignore`, Prettier's `.prettierignore`, or ESLint's `.eslintignore` files. + This value is unused if `{ gitignore: true }`, since `gitignore` takes precedence. + + @default undefined + */ + readonly ignoreFiles?: string; } interface GlobTask { diff --git a/index.js b/index.js index b2d503b..d20fb63 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ const arrayUnion = require('array-union'); const merge2 = require('merge2'); const fastGlob = require('fast-glob'); const dirGlob = require('dir-glob'); -const gitignore = require('./gitignore'); +const ignore = require('./ignore'); const {FilterStream, UniqueStream} = require('./stream-utils'); const DEFAULT_FILTER = () => false; @@ -91,11 +91,14 @@ const globDirs = (task, fn) => { return fn(task.pattern, options); }; +const getIgnoreFiles = options => options && options.gitignore ? '**/.gitignore' : options && options.ignoreFiles; + const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; const getFilterSync = options => { - return options && options.gitignore ? - gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : + const ignoreFiles = getIgnoreFiles(options); + return ignoreFiles ? + ignore.sync(ignoreFiles, {cwd: options.cwd, ignore: options.ignore}) : DEFAULT_FILTER; }; @@ -115,8 +118,9 @@ module.exports = async (patterns, options) => { const globTasks = generateGlobTasks(patterns, options); const getFilter = async () => { - return options && options.gitignore ? - gitignore({cwd: options.cwd, ignore: options.ignore}) : + const ignoreFiles = getIgnoreFiles(options); + return ignoreFiles ? + ignore(ignoreFiles, {cwd: options.cwd, ignore: options.ignore}) : DEFAULT_FILTER; }; @@ -178,4 +182,6 @@ module.exports.hasMagic = (patterns, options) => [] .concat(patterns) .some(pattern => fastGlob.isDynamicPattern(pattern, options)); -module.exports.gitignore = gitignore; +module.exports.ignoreFiles = ignore; +module.exports.gitignore = options => ignore('**/.gitignore', options); +module.exports.gitignore.sync = options => ignore.sync('**/.gitignore', options); diff --git a/readme.md b/readme.md index b39ae43..de66d7e 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,7 @@ Based on [`fast-glob`](https://github.com/mrmlnc/fast-glob) but adds a bunch of - Multiple patterns - Negated patterns: `['foo*', '!foobar']` - Expands directories: `foo` → `foo/**/*` -- Supports `.gitignore` +- Supports `.gitignore`, or any similar ignore file configuration. ## Install @@ -89,6 +89,17 @@ Default: `false` Respect ignore patterns in `.gitignore` files that apply to the globbed files. +This option takes precedence over the `ignoreFiles` option. + +##### ignoreFiles + +Type: `string`\ +Default: `undefined` + +A glob pattern to look for ignore files, which are then used to ignore globbed files. This is a more generic form of the `gitignore` option, allowing you to find ignore files with a [compatible syntax](http://git-scm.com/docs/gitignore). For instance, this is works with Babel's `.babelignore`, Prettier's `.prettierignore`, or ESLint's `.eslintignore` files. + +This value is unused if `{ gitignore: true }`, because `gitignore` takes precedence. + ### globby.sync(patterns, options?) Returns `string[]` of matching paths.