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

Commit

Permalink
fix: Ensure gitignore-style directory ignores (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Dec 14, 2022
1 parent 8b22cd0 commit 8e17f4a
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 21 deletions.
39 changes: 31 additions & 8 deletions src/config-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,9 @@ export class ConfigArray extends Array {

assertNormalized(this);

const relativeDirectoryPath = path.relative(this.basePath, directoryPath);
const relativeDirectoryPath = path.relative(this.basePath, directoryPath)
.replace(/\\/g, '/');

if (relativeDirectoryPath.startsWith('..')) {
return true;
}
Expand All @@ -852,14 +854,35 @@ 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("/**")),
directoryPath,
relativeDirectoryPath
);

const directoryParts = relativeDirectoryPath.split('/');
let relativeDirectoryToCheck = '';
let result = false;

/*
* In order to get the correct gitignore-style ignores, where an
* ignored parent directory cannot have any descendants unignored,
* we need to check every directory starting at the parent all
* the way down to the actual requested directory.
*
* We aggressively cache all of this info to make sure we don't
* have to recalculate everything for every call.
*/
do {

relativeDirectoryToCheck += directoryParts.shift() + '/';

result = shouldIgnorePath(
this.ignores,
path.join(this.basePath, relativeDirectoryToCheck),
relativeDirectoryToCheck
);

cache.set(relativeDirectoryToCheck, result);

} while (!result && directoryParts.length);

// also cache the result for the requested path
cache.set(relativeDirectoryPath, result);

return result;
Expand Down
93 changes: 80 additions & 13 deletions tests/config-array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ describe('ConfigArray', () => {
expect(configs.isFileIgnored(path.join(basePath, 'foo/bar/a.js'))).to.be.true;
});

it('should return false when an ignored directory is later unignored with **', () => {
it('should return true when an ignored directory is later negated with **', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
Expand All @@ -1028,10 +1028,10 @@ describe('ConfigArray', () => {

configs.normalizeSync();

expect(configs.isFileIgnored(path.join(basePath, 'node_modules/package/a.js'))).to.be.false;
expect(configs.isFileIgnored(path.join(basePath, 'node_modules/package/a.js'))).to.be.true;
});

it('should return false when an ignored directory is later unignored with *', () => {
it('should return true when an ignored directory is later negated with *', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
Expand All @@ -1052,7 +1052,7 @@ describe('ConfigArray', () => {

configs.normalizeSync();

expect(configs.isFileIgnored(path.join(basePath, 'node_modules/package/a.js'))).to.be.false;
expect(configs.isFileIgnored(path.join(basePath, 'node_modules/package/a.js'))).to.be.true;
});

it('should return true when there are only patterns ending with /*', () => {
Expand Down Expand Up @@ -1216,7 +1216,7 @@ describe('ConfigArray', () => {
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules') + '/'), 'Trailing slash').to.be.true;
});

it('should return false when a directory followed by ** is in ignores', () => {
it('should return true when a directory followed by ** is in ignores', () => {
configs = new ConfigArray([
{
ignores: ['**/node_modules/**']
Expand All @@ -1227,8 +1227,8 @@ describe('ConfigArray', () => {

configs.normalizeSync();

expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules'))).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules') + '/')).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules'))).to.be.true;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules') + '/')).to.be.true;

});

Expand Down Expand Up @@ -1361,7 +1361,7 @@ describe('ConfigArray', () => {
});


it('should return false when an ignored directory is later unignored with **', () => {
it('should return true when an ignored directory is later negated with **', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
Expand All @@ -1382,11 +1382,11 @@ describe('ConfigArray', () => {

configs.normalizeSync();

expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package'))).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package/'))).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package'))).to.be.true;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package/'))).to.be.true;
});

it('should return false when an ignored directory is later unignored with *', () => {
it('should return true when an ignored directory is later unignored with *', () => {
configs = new ConfigArray([
{
files: ['**/*.js']
Expand All @@ -1407,10 +1407,77 @@ describe('ConfigArray', () => {

configs.normalizeSync();

expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package'))).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package/'))).to.be.false;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package'))).to.be.true;
expect(configs.isDirectoryIgnored(path.join(basePath, 'node_modules/package/'))).to.be.true;
});

// https://github.com/eslint/eslint/pull/16579/files
describe('gitignore-style unignores', () => {

it('should return false when first-level subdirectories are ignored and then one is negated', () => {
configs = new ConfigArray([
{
ignores: [
'**/node_modules/*',
'!**/node_modules/foo/'
],
}
], { basePath });

configs.normalizeSync();
const directoryPath = path.resolve(basePath, 'node_modules/foo');

expect(configs.isDirectoryIgnored(directoryPath)).to.be.false;
});

it('should return false when first-level subdirectories are ignored with leading slash and then one is negated', () => {
configs = new ConfigArray([
{
ignores: [
'/**/node_modules/*',
'!**/node_modules/foo/'
],
}
], { basePath });

configs.normalizeSync();
const directoryPath = path.resolve(basePath, 'node_modules/foo');

expect(configs.isDirectoryIgnored(directoryPath)).to.be.false;
});

it('should return true when all descendant subdirectories are ignored and then one is negated', () => {
configs = new ConfigArray([
{
ignores: [
'**/node_modules/**',
'!**/node_modules/foo/'
],
}
], { basePath });

configs.normalizeSync();
const directoryPath = path.resolve(basePath, 'node_modules/foo');

expect(configs.isDirectoryIgnored(directoryPath)).to.be.true;
});

it('should return true when all descendant subdirectories are ignored and then other descendants are negated', () => {
configs = new ConfigArray([
{
ignores: [
'**/node_modules/**',
'!**/node_modules/foo/**'
],
}
], { basePath });

configs.normalizeSync();
const directoryPath = path.resolve(basePath, 'node_modules/foo');

expect(configs.isDirectoryIgnored(directoryPath)).to.be.true;
});
});

});

Expand Down

0 comments on commit 8e17f4a

Please sign in to comment.