Skip to content

Commit

Permalink
fix: apply absolute negative patterns to full path instead of file path
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmlnc committed Nov 23, 2024
1 parent 54ad12d commit 41e4730
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 21 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"extends": "mrmlnc",
"rules": {
"no-magic-numbers": "off",
"@typescript-eslint/no-magic-numbers": "off"
"@typescript-eslint/no-magic-numbers": "off",
"import/namespace": "off",
"import/no-deprecated": "off"
},
"overrides": [
{
Expand Down
12 changes: 12 additions & 0 deletions __snapshots__/absolute.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,15 @@ exports['Options Absolute (cwd & ignore) {"pattern":"**","options":{"ignore":["<
exports['Options Absolute (cwd & ignore) {"pattern":"**","options":{"ignore":["<root>/fixtures/**"],"cwd":"fixtures","absolute":true}} (async) 1'] = []

exports['Options Absolute (cwd & ignore) {"pattern":"**","options":{"ignore":["<root>/fixtures/**"],"cwd":"fixtures","absolute":true}} (stream) 1'] = []

exports['Options Absolute (cwd & ignore) {"pattern":"file.md","options":{"ignore":["**/fixtures/**"],"cwd":"fixtures","absolute":true}} (sync) 1'] = [
"<root>/fixtures/file.md"
]

exports['Options Absolute (cwd & ignore) {"pattern":"file.md","options":{"ignore":["**/fixtures/**"],"cwd":"fixtures","absolute":true}} (async) 1'] = [
"<root>/fixtures/file.md"
]

exports['Options Absolute (cwd & ignore) {"pattern":"file.md","options":{"ignore":["**/fixtures/**"],"cwd":"fixtures","absolute":true}} (stream) 1'] = [
"<root>/fixtures/file.md"
]
55 changes: 35 additions & 20 deletions src/providers/filters/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@ import Settings from '../../settings';
import { Entry, EntryFilterFunction, MicromatchOptions, Pattern, PatternRe } from '../../types';
import * as utils from '../../utils';

type PatternsRegexSet = {
positive: {
all: PatternRe[];
};
negative: {
absolute: PatternRe[];
relative: PatternRe[];
};
};

export default class EntryFilter {
public readonly index: Map<string, undefined> = new Map();

constructor(private readonly _settings: Settings, private readonly _micromatchOptions: MicromatchOptions) {}

public getFilter(positive: Pattern[], negative: Pattern[]): EntryFilterFunction {
const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions);
const negativeRe = utils.pattern.convertPatternsToRe(negative, {
...this._micromatchOptions,
dot: true
});

return (entry) => this._filter(entry, positiveRe, negativeRe);
const [absoluteNegative, relativeNegative] = utils.pattern.partitionAbsoluteAndRelative(negative);

const patterns: PatternsRegexSet = {
positive: {
all: utils.pattern.convertPatternsToRe(positive, this._micromatchOptions)
},
negative: {
absolute: utils.pattern.convertPatternsToRe(absoluteNegative, { ...this._micromatchOptions, dot: true }),
relative: utils.pattern.convertPatternsToRe(relativeNegative, { ...this._micromatchOptions, dot: true })
}
};

return (entry) => this._filter(entry, patterns);
}

private _filter(entry: Entry, positiveRe: PatternRe[], negativeRe: PatternRe[]): boolean {
private _filter(entry: Entry, patterns: PatternsRegexSet): boolean {
const filepath = utils.path.removeLeadingDotSegment(entry.path);

if (this._settings.unique && this._isDuplicateEntry(filepath)) {
Expand All @@ -28,13 +44,7 @@ export default class EntryFilter {
return false;
}

if (this._isSkippedByAbsoluteNegativePatterns(filepath, negativeRe)) {
return false;
}

const isDirectory = entry.dirent.isDirectory();

const isMatched = this._isMatchToPatterns(filepath, positiveRe, isDirectory) && !this._isMatchToPatterns(filepath, negativeRe, isDirectory);
const isMatched = this._isMatchToPatternsSet(filepath, patterns, entry.dirent.isDirectory());

if (this._settings.unique && isMatched) {
this._createIndexRecord(filepath);
Expand All @@ -59,14 +69,19 @@ export default class EntryFilter {
return this._settings.onlyDirectories && !entry.dirent.isDirectory();
}

private _isSkippedByAbsoluteNegativePatterns(entryPath: string, patternsRe: PatternRe[]): boolean {
if (!this._settings.absolute) {
return false;
private _isMatchToPatternsSet(filepath: string, patterns: PatternsRegexSet, isDirectory: boolean): boolean {
let fullpath = filepath;

if (patterns.negative.absolute.length > 0) {
fullpath = utils.path.makeAbsolute(this._settings.cwd, filepath);
}

const fullpath = utils.path.makeAbsolute(this._settings.cwd, entryPath);
const isMatched = this._isMatchToPatterns(filepath, patterns.positive.all, isDirectory);

return utils.pattern.matchAny(fullpath, patternsRe);
return isMatched && !(
this._isMatchToPatterns(filepath, patterns.negative.relative, isDirectory) ||
this._isMatchToPatterns(fullpath, patterns.negative.absolute, isDirectory)
);
}

private _isMatchToPatterns(filepath: string, patternsRe: PatternRe[], isDirectory: boolean): boolean {
Expand Down
8 changes: 8 additions & 0 deletions src/tests/e2e/options/absolute.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ runner.suite('Options Absolute (cwd & ignore)', {
absolute: true
}
},
{
pattern: 'file.md',
options: {
ignore: [path.posix.join('**', 'fixtures', '**')],
cwd: 'fixtures',
absolute: true
}
},

{
pattern: '*',
Expand Down
14 changes: 14 additions & 0 deletions src/utils/pattern.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,4 +539,18 @@ describe('Utils → Pattern', () => {
assert.strictEqual(action('///?/D:/'), '//?/D:/');
});
});

describe('.isAbsolute', () => {
it('should return true', () => {
const actual = util.isAbsolute('/directory/file.txt');

assert.ok(actual);
});

it('should return false', () => {
const actual = util.isAbsolute('directory/file.txt');

assert.ok(!actual);
});
});
});
19 changes: 19 additions & 0 deletions src/utils/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,22 @@ export function matchAny(entry: string, patternsRe: PatternRe[]): boolean {
export function removeDuplicateSlashes(pattern: string): string {
return pattern.replace(DOUBLE_SLASH_RE, '/');
}

export function partitionAbsoluteAndRelative(patterns: Pattern[]): Pattern[][] {
const absolute: Pattern[] = [];
const relative: Pattern[] = [];

for (const pattern of patterns) {
if (isAbsolute(pattern)) {
absolute.push(pattern);
} else {
relative.push(pattern);
}
}

return [absolute, relative];
}

export function isAbsolute(pattern: string): boolean {
return path.isAbsolute(pattern);
}

0 comments on commit 41e4730

Please sign in to comment.