Fix #33189 - make rg command shorter by factoring out common excludes

pull/33454/head
Rob Lourens 2017-08-28 10:47:00 -07:00
parent 040fadfeec
commit 09d336e000
1 changed files with 35 additions and 8 deletions

View File

@ -369,12 +369,12 @@ interface IRgGlobResult {
siblingClauses: glob.IExpression;
}
function foldersToRgExcludeGlobs(folderQueries: IFolderSearch[], globalExclude: glob.IExpression): IRgGlobResult {
function foldersToRgExcludeGlobs(folderQueries: IFolderSearch[], globalExclude: glob.IExpression, excludesToSkip: Set<string>): IRgGlobResult {
const globArgs: string[] = [];
let siblingClauses: glob.IExpression = {};
folderQueries.forEach(folderQuery => {
const totalExcludePattern = objects.assign({}, folderQuery.excludePattern || {}, globalExclude || {});
const result = globExprsToRgGlobs(totalExcludePattern, folderQuery.folder);
const result = globExprsToRgGlobs(totalExcludePattern, folderQuery.folder, excludesToSkip);
globArgs.push(...result.globArgs);
if (result.siblingClauses) {
siblingClauses = objects.assign(siblingClauses, result.siblingClauses);
@ -395,11 +395,15 @@ function foldersToIncludeGlobs(folderQueries: IFolderSearch[], globalInclude: gl
return globArgs;
}
function globExprsToRgGlobs(patterns: glob.IExpression, folder: string): IRgGlobResult {
function globExprsToRgGlobs(patterns: glob.IExpression, folder: string, excludesToSkip?: Set<string>): IRgGlobResult {
const globArgs: string[] = [];
let siblingClauses: glob.IExpression = null;
Object.keys(patterns)
.forEach(key => {
if (excludesToSkip && excludesToSkip.has(key)) {
return;
}
const value = patterns[key];
key = getAbsoluteGlob(folder, key);
@ -424,14 +428,16 @@ function globExprsToRgGlobs(patterns: glob.IExpression, folder: string): IRgGlob
* Exported for testing
*/
export function getAbsoluteGlob(folder: string, key: string): string {
let absolute = paths.isAbsolute(key) ?
const absolute = paths.isAbsolute(key) ?
key :
path.join(folder, key);
absolute = strings.rtrim(absolute, '\\');
absolute = strings.rtrim(absolute, '/');
return trimTrailingSlash(absolute);
}
return absolute;
function trimTrailingSlash(str: string): string {
str = strings.rtrim(str, '\\');
return strings.rtrim(str, '/');
}
export function fixDriveC(path: string): string {
@ -451,9 +457,12 @@ function getRgArgs(config: IRawSearch): IRgGlobResult {
});
let siblingClauses: glob.IExpression;
const rgGlobs = foldersToRgExcludeGlobs(config.folderQueries, config.excludePattern);
const universalExcludes = findUniversalExcludes(config.folderQueries);
const rgGlobs = foldersToRgExcludeGlobs(config.folderQueries, config.excludePattern, universalExcludes);
rgGlobs.globArgs
.forEach(rgGlob => args.push('-g', `!${rgGlob}`));
universalExcludes
.forEach(exclude => args.push('-g', `!${trimTrailingSlash(exclude)}`));
siblingClauses = rgGlobs.siblingClauses;
if (config.maxFilesize) {
@ -517,3 +526,21 @@ function getSiblings(file: string): TPromise<string[]> {
});
});
}
function findUniversalExcludes(folderQueries: IFolderSearch[]): Set<string> {
if (folderQueries.length < 2) {
// Nothing to simplify
return null;
}
const firstFolder = folderQueries[0];
const universalExcludes = new Set<string>();
Object.keys(firstFolder.excludePattern).forEach(key => {
if (strings.startsWith(key, '**') && folderQueries.every(q => q.excludePattern[key] === true)) {
universalExcludes.add(key);
}
});
return universalExcludes;
}