d11 theme
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

92 lines
3.7 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GlobMatcher = void 0;
const mm = require("micromatch");
const path = require("path");
class GlobMatcher {
/**
* Construct a `.gitignore` emulator
* @param patterns the contents of a `.gitignore` style file or an array of individual glob rules.
* @param root the working directory
*/
constructor(patterns, root, nodePath) {
this.patterns = patterns;
this.root = root;
this.path = nodePath !== null && nodePath !== void 0 ? nodePath : path;
this.matchEx = buildMatcherFn(this.path, patterns, root);
}
/**
* Check to see if a filename matches any of the globs.
* If filename is relative, it is considered relative to the root.
* If filename is absolute and contained within the root, it will be made relative before being tested for a glob match.
* If filename is absolute and not contained within the root, it will be tested as is.
* @param filename full path of the file to check.
*/
match(filename) {
return this.matchEx(filename).matched;
}
}
exports.GlobMatcher = GlobMatcher;
/**
* This function attempts to emulate .gitignore functionality as much as possible.
*
* The resulting matcher function: (filename: string) => GlobMatch
*
* If filename is relative, it is considered relative to the root.
* If filename is absolute and contained within the root, it will be made relative before being tested for a glob match.
* If filename is absolute and not contained within the root, it will be tested as is.
*
* @param patterns the contents of a .gitignore style file or an array of individual glob rules.
* @param root the working directory
* @returns a function given a filename returns true if it matches.
*/
function buildMatcherFn(path, patterns, root) {
if (typeof patterns == 'string') {
patterns = patterns.split(/\r?\n/g);
}
const dirRoot = path.normalize(root || '/');
const rules = patterns
.map((p) => p.trim())
.map((p, index) => ({ glob: p, index }))
.filter((r) => !!r.glob)
.map(({ glob, index }) => {
const matchNeg = glob.match(/^!+/);
const isNeg = (matchNeg && matchNeg[0].length & 1 && true) || false;
const pattern = mutations.reduce((p, [regex, replace]) => p.replace(regex, replace), glob);
const reg = mm.makeRe(pattern);
const fn = (filename) => {
const match = filename.match(reg);
return !!match;
};
return { glob, index, isNeg, fn, reg };
});
const negRules = rules.filter((r) => r.isNeg);
const posRules = rules.filter((r) => !r.isNeg);
const fn = (filename) => {
filename = path.normalize(filename);
const offset = dirRoot === filename.slice(0, dirRoot.length) ? dirRoot.length : 0;
const lName = filename.slice(offset);
const filePath = path.parse(lName);
const relPath = path.join(filePath.dir.slice(filePath.root.length), filePath.base);
const fname = relPath.split(path.sep).join('/');
for (const rule of negRules) {
if (rule.fn(fname)) {
return { matched: false, glob: rule.glob, index: rule.index, isNeg: rule.isNeg };
}
}
for (const rule of posRules) {
if (rule.fn(fname)) {
return { matched: true, glob: rule.glob, index: rule.index, isNeg: rule.isNeg };
}
}
return { matched: false };
};
return fn;
}
const mutations = [
[/^!+/, ''],
[/^[^/#][^/]*$/, '**/{$&,$&/**}'],
[/^\/(?!\/)/, ''],
[/\/$/, '$&**'],
];
//# sourceMappingURL=GlobMatcher.js.map