mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-28 07:40:30 -04:00
Merge from master
This commit is contained in:
@@ -4,22 +4,23 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as cp from 'child_process';
|
||||
import { rgPath } from 'vscode-ripgrep';
|
||||
|
||||
import { isMacintosh as isMac } from 'vs/base/common/platform';
|
||||
import * as path from 'path';
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { startsWith } from 'vs/base/common/strings';
|
||||
import { normalizeNFD } from 'vs/base/common/normalization';
|
||||
|
||||
import { IFolderSearch, IRawSearch } from './search';
|
||||
import { foldersToIncludeGlobs, foldersToRgExcludeGlobs } from './ripgrepTextSearch';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import { isMacintosh as isMac } from 'vs/base/common/platform';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { IFileQuery, IFolderQuery } from 'vs/platform/search/common/search';
|
||||
import { anchorGlob } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
|
||||
import { rgPath } from 'vscode-ripgrep';
|
||||
|
||||
// If vscode-ripgrep is in an .asar file, then the binary is unpacked.
|
||||
const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked');
|
||||
|
||||
export function spawnRipgrepCmd(config: IRawSearch, folderQuery: IFolderSearch, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
|
||||
export function spawnRipgrepCmd(config: IFileQuery, folderQuery: IFolderQuery, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
|
||||
const rgArgs = getRgArgs(config, folderQuery, includePattern, excludePattern);
|
||||
const cwd = folderQuery.folder;
|
||||
const cwd = folderQuery.folder.fsPath;
|
||||
return {
|
||||
cmd: cp.spawn(rgDiskPath, rgArgs.args, { cwd }),
|
||||
siblingClauses: rgArgs.siblingClauses,
|
||||
@@ -28,12 +29,12 @@ export function spawnRipgrepCmd(config: IRawSearch, folderQuery: IFolderSearch,
|
||||
};
|
||||
}
|
||||
|
||||
function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
|
||||
function getRgArgs(config: IFileQuery, folderQuery: IFolderQuery, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
|
||||
const args = ['--files', '--hidden', '--case-sensitive'];
|
||||
|
||||
// includePattern can't have siblingClauses
|
||||
foldersToIncludeGlobs([folderQuery], includePattern, false).forEach(globArg => {
|
||||
const inclusion = anchor(globArg);
|
||||
const inclusion = anchorGlob(globArg);
|
||||
args.push('-g', inclusion);
|
||||
if (isMac) {
|
||||
const normalized = normalizeNFD(inclusion);
|
||||
@@ -43,11 +44,11 @@ function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePatter
|
||||
}
|
||||
});
|
||||
|
||||
let siblingClauses: glob.IExpression;
|
||||
let siblingClauses: glob.IExpression | null;
|
||||
|
||||
const rgGlobs = foldersToRgExcludeGlobs([folderQuery], excludePattern, undefined, false);
|
||||
rgGlobs.globArgs.forEach(globArg => {
|
||||
const exclusion = `!${anchor(globArg)}`;
|
||||
const exclusion = `!${anchorGlob(globArg)}`;
|
||||
args.push('-g', exclusion);
|
||||
if (isMac) {
|
||||
const normalized = normalizeNFD(exclusion);
|
||||
@@ -66,7 +67,7 @@ function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePatter
|
||||
}
|
||||
|
||||
// Follow symlinks
|
||||
if (!config.ignoreSymlinks) {
|
||||
if (!folderQuery.ignoreSymlinks) {
|
||||
args.push('--follow');
|
||||
}
|
||||
|
||||
@@ -74,14 +75,108 @@ function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePatter
|
||||
args.push('--quiet');
|
||||
}
|
||||
|
||||
// Folder to search
|
||||
args.push('--');
|
||||
|
||||
args.push('.');
|
||||
args.push('--no-config');
|
||||
if (folderQuery.disregardGlobalIgnoreFiles) {
|
||||
args.push('--no-ignore-global');
|
||||
}
|
||||
|
||||
return { args, siblingClauses };
|
||||
}
|
||||
|
||||
function anchor(glob: string) {
|
||||
return startsWith(glob, '**') || startsWith(glob, '/') ? glob : `/${glob}`;
|
||||
export interface IRgGlobResult {
|
||||
globArgs: string[];
|
||||
siblingClauses: glob.IExpression | null;
|
||||
}
|
||||
|
||||
export function foldersToRgExcludeGlobs(folderQueries: IFolderQuery[], globalExclude: glob.IExpression, excludesToSkip?: Set<string>, absoluteGlobs = true): IRgGlobResult {
|
||||
const globArgs: string[] = [];
|
||||
let siblingClauses: glob.IExpression = {};
|
||||
folderQueries.forEach(folderQuery => {
|
||||
const totalExcludePattern = objects.assign({}, folderQuery.excludePattern || {}, globalExclude || {});
|
||||
const result = globExprsToRgGlobs(totalExcludePattern, absoluteGlobs ? folderQuery.folder.fsPath : undefined, excludesToSkip);
|
||||
globArgs.push(...result.globArgs);
|
||||
if (result.siblingClauses) {
|
||||
siblingClauses = objects.assign(siblingClauses, result.siblingClauses);
|
||||
}
|
||||
});
|
||||
|
||||
return { globArgs, siblingClauses };
|
||||
}
|
||||
|
||||
export function foldersToIncludeGlobs(folderQueries: IFolderQuery[], globalInclude: glob.IExpression, absoluteGlobs = true): string[] {
|
||||
const globArgs: string[] = [];
|
||||
folderQueries.forEach(folderQuery => {
|
||||
const totalIncludePattern = objects.assign({}, globalInclude || {}, folderQuery.includePattern || {});
|
||||
const result = globExprsToRgGlobs(totalIncludePattern, absoluteGlobs ? folderQuery.folder.fsPath : undefined);
|
||||
globArgs.push(...result.globArgs);
|
||||
});
|
||||
|
||||
return globArgs;
|
||||
}
|
||||
|
||||
function globExprsToRgGlobs(patterns: glob.IExpression, folder?: string, excludesToSkip?: Set<string>): IRgGlobResult {
|
||||
const globArgs: string[] = [];
|
||||
let siblingClauses: glob.IExpression | null = null;
|
||||
Object.keys(patterns)
|
||||
.forEach(key => {
|
||||
if (excludesToSkip && excludesToSkip.has(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = patterns[key];
|
||||
key = trimTrailingSlash(folder ? getAbsoluteGlob(folder, key) : key);
|
||||
|
||||
// glob.ts requires forward slashes, but a UNC path still must start with \\
|
||||
// #38165 and #38151
|
||||
if (strings.startsWith(key, '\\\\')) {
|
||||
key = '\\\\' + key.substr(2).replace(/\\/g, '/');
|
||||
} else {
|
||||
key = key.replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean' && value) {
|
||||
if (strings.startsWith(key, '\\\\')) {
|
||||
// Absolute globs UNC paths don't work properly, see #58758
|
||||
key += '**';
|
||||
}
|
||||
|
||||
globArgs.push(fixDriveC(key));
|
||||
} else if (value && value.when) {
|
||||
if (!siblingClauses) {
|
||||
siblingClauses = {};
|
||||
}
|
||||
|
||||
siblingClauses[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return { globArgs, siblingClauses };
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a glob like "node_modules/**" in "/foo/bar" to "/foo/bar/node_modules/**".
|
||||
* Special cases C:/foo paths to write the glob like /foo instead - see https://github.com/BurntSushi/ripgrep/issues/530.
|
||||
*
|
||||
* Exported for testing
|
||||
*/
|
||||
export function getAbsoluteGlob(folder: string, key: string): string {
|
||||
return paths.isAbsolute(key) ?
|
||||
key :
|
||||
path.join(folder, key);
|
||||
}
|
||||
|
||||
function trimTrailingSlash(str: string): string {
|
||||
str = strings.rtrim(str, '\\');
|
||||
return strings.rtrim(str, '/');
|
||||
}
|
||||
|
||||
export function fixDriveC(path: string): string {
|
||||
const root = paths.getRoot(path);
|
||||
return root.toLowerCase() === 'c:/' ?
|
||||
path.replace(/^c:[/\\]/i, '/') :
|
||||
path;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user