From 0ab0ed8c4bd3b482c853de061154e5f89d61a173 Mon Sep 17 00:00:00 2001 From: dominikg Date: Wed, 9 Oct 2024 14:06:39 +0200 Subject: [PATCH] fix(globMatch): support implicit globs --- .changeset/neat-carpets-roll.md | 5 +++ packages/tsconfck/src/util.js | 39 ++++++++++++++++--- .../referenced-with-implicit-globs/src/foo.ts | 3 ++ .../tests/foo.test.ts | 9 +++++ .../tsconfig.json | 7 ++++ .../tsconfig.src.json | 7 ++++ .../tsconfig.test.json | 7 ++++ ...ts.tsconfig.parse-native.ignore-files.json | 12 ++++++ .../src/foo.ts.tsconfig.parse-native.json | 9 +++++ .../src/foo.ts.tsconfig.parse.json | 9 +++++ ...ts.tsconfig.parse-native.ignore-files.json | 12 ++++++ .../foo.test.ts.tsconfig.parse-native.json | 9 +++++ .../tests/foo.test.ts.tsconfig.parse.json | 9 +++++ .../tsconfig.json.parse-native.json | 11 ++++++ .../tsconfig.json.parse.json | 11 ++++++ .../tsconfig.src.json.tsconfig.parse.json | 9 +++++ .../tsconfig.test.json.tsconfig.parse.json | 9 +++++ 17 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 .changeset/neat-carpets-roll.md create mode 100644 packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/src/foo.ts create mode 100644 packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts create mode 100644 packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.json create mode 100644 packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.src.json create mode 100644 packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.test.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.ignore-files.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.ignore-files.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse-native.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.src.json.tsconfig.parse.json create mode 100644 packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.test.json.tsconfig.parse.json diff --git a/.changeset/neat-carpets-roll.md b/.changeset/neat-carpets-roll.md new file mode 100644 index 0000000..44ab2dd --- /dev/null +++ b/.changeset/neat-carpets-roll.md @@ -0,0 +1,5 @@ +--- +'tsconfck': patch +--- + +fix(glob-matching): add implicit **/\* to path patterns that do not have an extension or wildcard in their last segment, eg `src` becomes `src/**/\*` for matching. diff --git a/packages/tsconfck/src/util.js b/packages/tsconfck/src/util.js index 3ef3914..75ac2d7 100644 --- a/packages/tsconfck/src/util.js +++ b/packages/tsconfck/src/util.js @@ -199,13 +199,35 @@ export function isGlobMatch(filename, dir, patterns, allowJs) { // filename must end with part of pattern that comes after last wildcard let lastWildcardIndex = pattern.length; let hasWildcard = false; + let hasExtension = false; + let hasSlash = false; + let lastSlashIndex = -1; for (let i = pattern.length - 1; i > -1; i--) { - if (pattern[i] === '*' || pattern[i] === '?') { - lastWildcardIndex = i; - hasWildcard = true; + const c = pattern[i]; + if (!hasWildcard) { + if (c === '*' || c === '?') { + lastWildcardIndex = i; + hasWildcard = true; + } + } + if (!hasSlash) { + if (c === '.') { + hasExtension = true; + } else if (c === '/') { + lastSlashIndex = i; + hasSlash = true; + } + } + if (hasWildcard && hasSlash) { break; } } + if (!hasExtension && (!hasWildcard || lastWildcardIndex < lastSlashIndex)) { + // add implicit glob + pattern += `${pattern.endsWith('/') ? '' : '/'}${GLOB_ALL_PATTERN}`; + lastWildcardIndex = pattern.length - 1; + hasWildcard = true; + } // if pattern does not end with wildcard, filename must end with pattern after last wildcard if ( @@ -243,11 +265,18 @@ export function isGlobMatch(filename, dir, patterns, allowJs) { return false; } - // if no wildcard in pattern, filename must be equal to resolved pattern if (!hasWildcard) { + // no wildcard in pattern, filename must be equal to resolved pattern return filename === resolvedPattern; + } else if ( + firstWildcardIndex + GLOB_ALL_PATTERN.length === + resolvedPattern.length - (pattern.length - 1 - lastWildcardIndex) && + resolvedPattern.slice(firstWildcardIndex, firstWildcardIndex + GLOB_ALL_PATTERN.length) === + GLOB_ALL_PATTERN + ) { + // singular glob-all pattern and we already validated prefix and suffix matches + return true; } - // complex pattern, use regex to check it if (PATTERN_REGEX_CACHE.has(resolvedPattern)) { return PATTERN_REGEX_CACHE.get(resolvedPattern).test(filename); diff --git a/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/src/foo.ts b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/src/foo.ts new file mode 100644 index 0000000..b071191 --- /dev/null +++ b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/src/foo.ts @@ -0,0 +1,3 @@ +export function foo() { + return 'foo'; +} diff --git a/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts new file mode 100644 index 0000000..9e5f167 --- /dev/null +++ b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts @@ -0,0 +1,9 @@ +import { foo } from '../src/foo'; +import * as assert from 'assert'; + +function test() { + const actual = foo(); + const expected = 'foo'; + assert.strictEqual(actual, expected); +} +test(); diff --git a/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.json b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.json new file mode 100644 index 0000000..c8dcb3a --- /dev/null +++ b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + {"path": "./tsconfig.src.json"}, + {"path": "./tsconfig.test.json"} + ] +} diff --git a/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.src.json b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.src.json new file mode 100644 index 0000000..0603077 --- /dev/null +++ b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.src.json @@ -0,0 +1,7 @@ +{ + "include": ["src"], + "compilerOptions": { + "composite": true, + "strict": true + } +} diff --git a/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.test.json b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.test.json new file mode 100644 index 0000000..6b9198b --- /dev/null +++ b/packages/tsconfck/tests/fixtures/parse/solution/referenced-with-implicit-globs/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "include": ["tests"], + "compilerOptions": { + "composite": true, + "strict": false + } +} diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.ignore-files.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.ignore-files.json new file mode 100644 index 0000000..e118e92 --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.ignore-files.json @@ -0,0 +1,12 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.src.json" + }, + { + "path": "./tsconfig.test.json" + } + ], + "include": [] +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.json new file mode 100644 index 0000000..f5a897c --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse-native.json @@ -0,0 +1,9 @@ +{ + "include": [ + "src" + ], + "compilerOptions": { + "composite": true, + "strict": true + } +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse.json new file mode 100644 index 0000000..f5a897c --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/src/foo.ts.tsconfig.parse.json @@ -0,0 +1,9 @@ +{ + "include": [ + "src" + ], + "compilerOptions": { + "composite": true, + "strict": true + } +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.ignore-files.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.ignore-files.json new file mode 100644 index 0000000..e118e92 --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.ignore-files.json @@ -0,0 +1,12 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.src.json" + }, + { + "path": "./tsconfig.test.json" + } + ], + "include": [] +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.json new file mode 100644 index 0000000..e034a84 --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse-native.json @@ -0,0 +1,9 @@ +{ + "include": [ + "tests" + ], + "compilerOptions": { + "composite": true, + "strict": false + } +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse.json new file mode 100644 index 0000000..e034a84 --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tests/foo.test.ts.tsconfig.parse.json @@ -0,0 +1,9 @@ +{ + "include": [ + "tests" + ], + "compilerOptions": { + "composite": true, + "strict": false + } +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse-native.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse-native.json new file mode 100644 index 0000000..e3d609b --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse-native.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.src.json" + }, + { + "path": "./tsconfig.test.json" + } + ] +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse.json new file mode 100644 index 0000000..e3d609b --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.json.parse.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.src.json" + }, + { + "path": "./tsconfig.test.json" + } + ] +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.src.json.tsconfig.parse.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.src.json.tsconfig.parse.json new file mode 100644 index 0000000..f5a897c --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.src.json.tsconfig.parse.json @@ -0,0 +1,9 @@ +{ + "include": [ + "src" + ], + "compilerOptions": { + "composite": true, + "strict": true + } +} \ No newline at end of file diff --git a/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.test.json.tsconfig.parse.json b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.test.json.tsconfig.parse.json new file mode 100644 index 0000000..e034a84 --- /dev/null +++ b/packages/tsconfck/tests/snapshots/parse/solution/referenced-with-implicit-globs/tsconfig.test.json.tsconfig.parse.json @@ -0,0 +1,9 @@ +{ + "include": [ + "tests" + ], + "compilerOptions": { + "composite": true, + "strict": false + } +} \ No newline at end of file