Allow multiple star-star globs in one pattern (#20639)

* Allow multiple starglobs in one pattern

* Add extra test case
This commit is contained in:
Wesley Wigham 2017-12-13 12:57:16 -08:00 committed by GitHub
parent f6603cd9f2
commit 2c6501db52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 39 deletions

View File

@ -1906,21 +1906,6 @@ namespace ts {
*/
const invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
/**
* Tests for a path with multiple recursive directory wildcards.
* Matches **\** and **\a\**, but not **\a**b.
*
* NOTE: used \ in place of / above to avoid issues with multiline comments.
*
* Breakdown:
* (^|\/) # matches either the beginning of the string or a directory separator.
* \*\*\/ # matches a recursive directory wildcard "**" followed by a directory separator.
* (.*\/)? # optionally matches any number of characters followed by a directory separator.
* \*\* # matches a recursive directory wildcard "**"
* ($|\/) # matches either the end of the string or a directory separator.
*/
const invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/;
/**
* Tests for a path where .. appears after a recursive directory wildcard.
* Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
@ -2115,9 +2100,6 @@ namespace ts {
if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
return Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
}
else if (invalidMultipleRecursionPatterns.test(spec)) {
return Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0;
}
else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
return Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
}

View File

@ -2376,7 +2376,6 @@ namespace ts {
function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter }: WildcardMatcher): string | undefined {
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
const lastComponent = lastOrUndefined(components);
@ -2395,12 +2394,7 @@ namespace ts {
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
return undefined;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
}
else {
if (usage === "directories") {

View File

@ -2623,10 +2623,6 @@
"category": "Error",
"code": 5010
},
"File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'.": {
"category": "Error",
"code": 5011
},
"Cannot read file '{0}': {1}.": {
"category": "Error",
"code": 5012

View File

@ -50,6 +50,7 @@ namespace ts {
"/dev/x/b.ts",
"/dev/x/y/a.ts",
"/dev/x/y/b.ts",
"/dev/q/a/c/b/d.ts",
"/dev/js/a.js",
"/dev/js/b.js",
]);
@ -1171,13 +1172,17 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
errors: [],
fileNames: [
"c:/dev/x/a.ts",
"c:/dev/x/aa.ts",
"c:/dev/x/b.ts",
"c:/dev/x/y/a.ts",
"c:/dev/x/y/b.ts",
],
fileNames: [],
wildcardDirectories: {}
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
});
@ -1192,13 +1197,9 @@ namespace ts {
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [
createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**")
],
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/x/a.ts",
"c:/dev/x/y/a.ts",
"c:/dev/z/a.ts"
],
wildcardDirectories: {
@ -1426,5 +1427,60 @@ namespace ts {
});
});
});
describe("exclude or include patterns which start with **", () => {
it("can exclude dirs whose pattern starts with **", () => {
const json = {
exclude: [
"**/x"
]
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
fileNames: [
"/dev/A.ts",
"/dev/B.ts",
"/dev/a.ts",
"/dev/b.ts",
"/dev/c.d.ts",
"/dev/q/a/c/b/d.ts",
"/dev/z/a.ts",
"/dev/z/aba.ts",
"/dev/z/abz.ts",
"/dev/z/b.ts",
"/dev/z/bba.ts",
"/dev/z/bbz.ts",
],
wildcardDirectories: {
"/dev": ts.WatchDirectoryFlags.Recursive
}
};
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
});
it("can include dirs whose pattern starts with **", () => {
const json = {
include: [
"**/x",
"**/a/**/b"
]
};
const expected: ts.ParsedCommandLine = {
options: {},
errors: [],
fileNames: [
"/dev/x/a.ts",
"/dev/x/b.ts",
"/dev/x/y/a.ts",
"/dev/x/y/b.ts",
"/dev/q/a/c/b/d.ts",
],
wildcardDirectories: {
"/dev": ts.WatchDirectoryFlags.Recursive
}
};
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
});
});
});
}