Skip to content
This repository has been archived by the owner on Jun 10, 2024. It is now read-only.

Commit

Permalink
fix: Ensure subdirectories of ignored directories are ignored
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Oct 14, 2022
1 parent 8696f9c commit 0df450e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 4 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,38 @@ A few things to keep in mind:
* The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation.
* A config will only be generated if the filename matches an entry in a `files` key. A config will not be generated without matching a `files` key (configs without a `files` key are only applied when another config with a `files` key is applied; configs without `files` are never applied on their own).

## Determining Ignored Paths

You can determine if a file is ignored by using the `isFileIgnored()` method and passing in the absolute path of any file, as in this example:

```js
const ignored = configs.isFileIgnored('/foo/bar/baz.txt');
```

A file is considered ignored if any of the following is true:

* **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/a.js` is considered ignored.
* **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/baz/a.js` is considered ignored.
* **It matches an ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
* **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
* **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.

For directories, use the `isDirectoryIgnored()` method and pass in the absolute path of any directory, as in this example:

```js
const ignored = configs.isDirectoryIgnored('/foo/bar/');
```

A directory is considered ignored if any of the following is true:

* **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/baz` is considered ignored.
* **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/bar/baz/a.js` is considered ignored.
* **It matches and ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
* **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored.
* **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored.

**Important:** A pattern such as `foo/**` means that `foo` and `foo/` are *not* ignored whereas `foo/bar` is ignored. If you want to ignore `foo` and all of its subdirectories, use the pattern `foo` or `foo/` in `ignores`.

## Caching Mechanisms

Each `ConfigArray` aggressively caches configuration objects to avoid unnecessary work. This caching occurs in two ways:
Expand Down
30 changes: 26 additions & 4 deletions src/config-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,28 @@ export class ConfigArray extends Array {
* are additional keys, then ignores act like exclusions.
*/
if (config.ignores && Object.keys(config).length === 1) {
result.push(...config.ignores);

/*
* If there are directory ignores, then we need to double up
* the patterns to be ignored. For instance, `foo` will also
* need `foo/**` in order to account for subdirectories.
*/
config.ignores.forEach(ignore => {

result.push(ignore);

if (typeof ignore === 'string') {

// directories should work with or without a trailing slash
if (ignore.endsWith('/')) {
result.push(ignore.slice(0, ignore.length - 1));
result.push(ignore + '**');
} else if (!ignore.endsWith('*')) {
result.push(ignore + '/**');
}

}
});
}
}

Expand Down Expand Up @@ -745,7 +766,7 @@ export class ConfigArray extends Array {

assertNormalized(this);

const relativeDirectoryPath = path.relative(this.basePath, directoryPath) + '/';
const relativeDirectoryPath = path.relative(this.basePath, directoryPath);
if (relativeDirectoryPath.startsWith('..')) {
return true;
}
Expand All @@ -756,9 +777,10 @@ export class ConfigArray extends Array {
if (cache.has(relativeDirectoryPath)) {
return cache.get(relativeDirectoryPath);
}


// first check non-/** paths
const result = shouldIgnorePath(
this.ignores.filter(matcher => typeof matcher === 'function' || !matcher.endsWith('/**')),
this.ignores, //.filter(matcher => typeof matcher === "function" || !matcher.endsWith("/**")),
directoryPath,
relativeDirectoryPath
);
Expand Down
40 changes: 40 additions & 0 deletions tests/config-array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,25 @@ describe('ConfigArray', () => {
expect(configs.isFileIgnored(path.join(basePath, 'a.js'))).to.be.true;
});

it('should return true when the parent directory of a file is ignored', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
},
{
ignores: [
'foo'
]
}
], {
basePath
});

configs.normalizeSync();

expect(configs.isFileIgnored(path.join(basePath, 'foo/bar/a.js'))).to.be.true;
});

});

describe('isDirectoryIgnored()', () => {
Expand Down Expand Up @@ -1150,6 +1169,27 @@ describe('ConfigArray', () => {
expect(configs.isDirectoryIgnored(path.resolve(basePath, '../foo/bar'))).to.be.true;
});

it('should return true when the parent directory of a directory is ignored', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
},
{
ignores: [
'foo'
]
}
], {
basePath
});

configs.normalizeSync();

expect(configs.isDirectoryIgnored(path.join(basePath, 'foo/bar'))).to.be.true;
expect(configs.isDirectoryIgnored(path.join(basePath, 'foo/bar/'))).to.be.true;
});


});

describe('isExplicitMatch()', () => {
Expand Down

0 comments on commit 0df450e

Please sign in to comment.