Skip to content

Commit 14da494

Browse files
committed
refactor(plugin-typescript): use dynamic tsconfig pattern matching
1 parent 6122c13 commit 14da494

File tree

6 files changed

+66
-24
lines changed

6 files changed

+66
-24
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"compilerOptions": { "strict": true }
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"files": [],
3+
"include": [],
4+
"references": [{ "path": "./tsconfig.lib.json" }]
5+
}

packages/plugin-typescript/src/lib/nx/tsconfig-paths.int.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ describe.skipIf(process.platform === 'win32')('Nx helpers', () => {
3737
});
3838

3939
describe('tsconfigFromAllNxProjects', () => {
40-
it('should find tsconfig.lib.json from all Nx projects', async () => {
40+
it('should find tsconfig files, filtering out empty configs and tsconfig.base.json', async () => {
41+
// cli project has tsconfig.json (empty arrays, filtered), tsconfig.base.json (excluded), tsconfig.lib.json (included)
42+
// other projects only have tsconfig.lib.json
4143
await expect(tsconfigFromAllNxProjects()).resolves.toEqual([
4244
'packages/cli/tsconfig.lib.json',
4345
'packages/core/tsconfig.lib.json',

packages/plugin-typescript/src/lib/nx/tsconfig-paths.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
import type { ProjectConfiguration } from '@nx/devkit';
22
import { readdir } from 'node:fs/promises';
33
import path from 'node:path';
4+
import { readConfigFile, sys } from 'typescript';
45
import { logger, pluralizeToken, stringifyError } from '@code-pushup/utils';
56
import { formatMetaLog } from '../format.js';
67

78
/**
8-
* TypeScript config patterns to look for in each project.
9+
* Matches tsconfig.json and tsconfig.*.json, excludes tsconfig.base.json.
910
*/
10-
const TSCONFIG_PATTERNS = new Set([
11-
'tsconfig.lib.json',
12-
'tsconfig.spec.json',
13-
'tsconfig.test.json',
14-
'tsconfig.app.json',
15-
]);
11+
function isTsconfigFile(filename: string): boolean {
12+
if (filename === 'tsconfig.base.json') {
13+
return false;
14+
}
15+
return (
16+
filename === 'tsconfig.json' ||
17+
(filename.startsWith('tsconfig.') && filename.endsWith('.json'))
18+
);
19+
}
20+
21+
/**
22+
* Returns false for empty configs (files and include both empty arrays).
23+
*/
24+
function hasFilesToCompile(tsconfigPath: string): boolean {
25+
const { config } = readConfigFile(tsconfigPath, sys.readFile);
26+
27+
if (!config) {
28+
return true;
29+
}
30+
31+
const { files, include } = config;
32+
const filesEmpty = Array.isArray(files) && files.length === 0;
33+
const includeEmpty = Array.isArray(include) && include.length === 0;
34+
35+
return !(filesEmpty && includeEmpty);
36+
}
1637

1738
/**
1839
* Resolves the cached project graph for the current Nx workspace.
@@ -40,13 +61,15 @@ function isProjectIncluded(
4061
}
4162

4263
/**
43-
* Finds tsconfig files matching known patterns in a project directory.
64+
* Finds non-empty tsconfig files in a project directory.
4465
*/
4566
async function findTsconfigsInProject(projectRoot: string): Promise<string[]> {
4667
const absoluteRoot = path.resolve(process.cwd(), projectRoot);
4768
const files = await readdir(absoluteRoot);
69+
4870
return files
49-
.filter(file => TSCONFIG_PATTERNS.has(file))
71+
.filter(isTsconfigFile)
72+
.filter(file => hasFilesToCompile(path.join(absoluteRoot, file)))
5073
.map(file => path.join(projectRoot, file));
5174
}
5275

packages/plugin-typescript/src/lib/runner/runner.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ function collectDiagnostics(tsconfigs: string[]): CollectResult {
3232
return tsconfigs.reduce<CollectResult>(
3333
(acc, config) => {
3434
try {
35-
const diagnostics = [
36-
...getTypeScriptDiagnostics({ tsconfig: config }),
37-
].map(diag => ({
38-
code: diag.code,
39-
issue: getIssueFromDiagnostic(diag),
40-
}));
41-
return { ...acc, diagnostics: [...acc.diagnostics, ...diagnostics] };
35+
const diagnostics = getTypeScriptDiagnostics({ tsconfig: config }).map(
36+
diag => ({
37+
code: diag.code,
38+
issue: getIssueFromDiagnostic(diag),
39+
}),
40+
);
41+
42+
return {
43+
...acc,
44+
diagnostics: [...acc.diagnostics, ...diagnostics],
45+
};
4246
} catch (error) {
4347
if (tsconfigs.length === 1) {
4448
throw error;
@@ -95,7 +99,7 @@ export function createRunnerFunction(options: RunnerOptions): RunnerFunction {
9599
logger.info(
96100
diagnostics.length === 0
97101
? 'No TypeScript errors found'
98-
: `TypeScript compiler found ${pluralizeToken('diagnostic', diagnostics.length)}`,
102+
: `TypeScript compiler found ${pluralizeToken('error', diagnostics.length)} in total`,
99103
);
100104

101105
const result = groupDiagnosticsByAudit(diagnostics);

packages/plugin-typescript/src/lib/runner/ts-runner.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@ export function getTypeScriptDiagnostics({
1414
tsconfig,
1515
}: DiagnosticsOptions): readonly Diagnostic[] {
1616
const { fileNames, options } = loadTargetConfig(tsconfig);
17-
logger.debug(
18-
`Parsed TypeScript config file ${tsconfig}, program includes ${pluralizeToken('file', fileNames.length)}`,
19-
);
2017
try {
2118
const program = createProgram(fileNames, options);
2219
const diagnostics = getPreEmitDiagnostics(program);
23-
logger.debug(
24-
`TypeScript compiler found ${pluralizeToken('diagnostic', diagnostics.length)}`,
25-
);
20+
21+
if (diagnostics.length > 0) {
22+
logger.info(
23+
` ${tsconfig} - ${pluralizeToken('error', diagnostics.length)}`,
24+
);
25+
} else {
26+
logger.debug(
27+
` ${tsconfig}: ${pluralizeToken('file', fileNames.length)}, 0 errors`,
28+
);
29+
}
30+
2631
return diagnostics;
2732
} catch (error) {
2833
throw new Error(

0 commit comments

Comments
 (0)