Skip to content

Commit

Permalink
Add ignoreFiles option
Browse files Browse the repository at this point in the history
This is very similar to the `gitignore` option, except it allows globing for any compatible ignore file (eg, `.prettierignore` or `.eslintignore`).
  • Loading branch information
jridgewell committed Apr 29, 2021
1 parent c1a3b32 commit bce9eff
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 30 deletions.
8 changes: 4 additions & 4 deletions gitignore.js → ignore.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand All @@ -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
});
Expand Down
40 changes: 21 additions & 19 deletions gitignore.test.js → ignore.test.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,77 @@
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);
});

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',
Expand All @@ -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',
Expand Down
9 changes: 9 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 12 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};

Expand All @@ -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;
};

Expand Down Expand Up @@ -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);
13 changes: 12 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit bce9eff

Please sign in to comment.