Skip to content

Commit

Permalink
Merge pull request #449 from mrmlnc/ISSUE-441_absolute_negrative
Browse files Browse the repository at this point in the history
ISSUE-441: apply absolute negative patterns to full path
  • Loading branch information
mrmlnc committed Jul 2, 2024
2 parents f3a7f21 + 4df40bd commit da64807
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 21 deletions.
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"
]
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"test:e2e:stream": "mocha \"out/**/*.e2e.js\" -s 0 --grep \"\\(stream\\)\"",
"_build:compile": "npm run clean && npm run compile",
"build": "npm run _build:compile && npm run lint && npm test",
"watch": "npm run _build:compile -- --sourceMap --watch",
"watch": "npm run _build:compile -- -- --sourceMap --watch",
"_bundle:dts": "tsc --emitDeclarationOnly --outDir ./build",
"_bundle:ts": "esbuild --bundle ./src/index.ts --outfile=./build/index.js --platform=node --target=node16.14 --format=cjs",
"_bundle:build": "npm run _bundle:dts && npm run _bundle:ts",
Expand Down
55 changes: 35 additions & 20 deletions src/providers/filters/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ import * as utils from '../../utils';
import type Settings from '../../settings';
import type { MicromatchOptions, Entry, EntryFilterFunction, Pattern, PatternRe } from '../../types';

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

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

Expand All @@ -15,16 +25,22 @@ export default class EntryFilter {
}

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);
}

#filter(entry: Entry, positiveRe: PatternRe[], negativeRe: PatternRe[]): boolean {
#filter(entry: Entry, pattens: PatternsRegexSet): boolean {
const filepath = utils.path.removeLeadingDotSegment(entry.path);

if (this.#settings.unique && this.#isDuplicateEntry(filepath)) {
Expand All @@ -35,13 +51,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, pattens, entry.dirent.isDirectory());

if (this.#settings.unique && isMatched) {
this.#createIndexRecord(filepath);
Expand All @@ -66,14 +76,19 @@ export default class EntryFilter {
return this.#settings.onlyDirectories && !entry.dirent.isDirectory();
}

#isSkippedByAbsoluteNegativePatterns(entryPath: string, patternsRe: PatternRe[]): boolean {
if (!this.#settings.absolute) {
return false;
#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)
);
}

#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 @@ -126,6 +126,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 @@ -540,4 +540,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 @@ -217,3 +217,22 @@ export function matchAny(entry: string, patternsRe: PatternRe[]): boolean {
export function removeDuplicateSlashes(pattern: string): string {
return pattern.replaceAll(DOUBLE_SLASH_RE, '/');
}

export function partitionAbsoluteAndRelative(patterns: Pattern[]): [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 da64807

Please sign in to comment.