Skip to content

Commit 5d40c59

Browse files
committed
docs(plugin-eslint): fix code fro new loader
1 parent 00e3fe7 commit 5d40c59

File tree

4 files changed

+42
-25
lines changed

4 files changed

+42
-25
lines changed

packages/plugin-eslint/src/lib/runner/lint.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ async function executeLint({
3636
const outputDir =
3737
providedOutputDir ?? path.join(DEFAULT_PERSIST_OUTPUT_DIR, 'eslint');
3838
const filename = `eslint-report-${++rotation}`;
39-
39+
const outputFile = path.join(outputDir, `${filename}.json`);
4040
// running as CLI because ESLint#lintFiles() runs out of memory
4141
await executeProcess({
4242
command: 'npx',
@@ -45,30 +45,18 @@ async function executeLint({
4545
...(eslintrc ? [`--config=${filePathToCliArg(eslintrc)}`] : []),
4646
...(typeof eslintrc === 'object' ? ['--no-eslintrc'] : []),
4747
'--no-error-on-unmatched-pattern',
48-
`--format=${path.join(
49-
path.dirname(fileURLToPath(import.meta.url)),
50-
'../formatter/multiple-formats.js',
51-
)}`,
48+
'--format=json',
49+
`--output-file=${outputFile}`,
5250
...toArray(patterns).map(pattern =>
5351
// globs need to be escaped on Unix
5452
platform() === 'win32' ? pattern : `'${pattern}'`,
5553
),
5654
],
5755
ignoreExitCode: true,
5856
cwd: process.cwd(),
59-
env: {
60-
ESLINT_FORMATTER_CONFIG: JSON.stringify({
61-
outputDir,
62-
filename,
63-
formats: ['json'], // Always write JSON to file for tracking
64-
terminal: 'stylish', // Always show stylish terminal output for DX
65-
}),
66-
},
6757
});
6858

69-
return readJsonFile<ESLint.LintResult[]>(
70-
path.join(outputDir, `${filename}.json`),
71-
);
59+
return readJsonFile<ESLint.LintResult[]>(outputFile);
7260
}
7361

7462
function loadRuleOptionsPerFile(

packages/plugin-eslint/src/lib/runner/lint.unit.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import { executeProcess } from '@code-pushup/utils';
44
import type { ESLintPluginConfig } from '../config.js';
55
import { lint } from './lint.js';
66

7+
/**
8+
* Regex pattern to match ESLint report filename format.
9+
* Matches: eslint-report.json or eslint-report-{number}.json
10+
* - No number: eslint-report.json (no dash)
11+
* - With number: eslint-report-123.json (with dash and digits)
12+
*/
13+
const ESLINT_REPORT_FILENAME_PATTERN = /eslint-report(?:-\d+)?\.json/;
14+
715
class MockESLint {
816
calculateConfigForFile = vi.fn().mockImplementation(
917
(path: string) =>
@@ -133,7 +141,7 @@ describe('lint', () => {
133141
'--config=".eslintrc.js"',
134142
'--no-error-on-unmatched-pattern',
135143
'--format=json',
136-
expect.stringMatching(/--output-file=.*eslint-report\.\d+\.json/),
144+
expect.stringMatching(ESLINT_REPORT_FILENAME_PATTERN),
137145
expect.stringMatching(/^'?\*\*\/\*\.js'?$/),
138146
],
139147
ignoreExitCode: true,

packages/plugin-eslint/src/lib/runner/utils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ export async function loadArtifacts(
2727
typeof artifacts.generateArtifactsCommand === 'string'
2828
? { command: artifacts.generateArtifactsCommand }
2929
: artifacts.generateArtifactsCommand;
30-
await executeProcess({
31-
command,
32-
args,
33-
ignoreExitCode: true,
34-
});
3530

3631
// Log the actual command that was executed
3732
const commandString =
3833
typeof artifacts.generateArtifactsCommand === 'string'
3934
? artifacts.generateArtifactsCommand
4035
: `${command} ${args.join(' ')}`;
4136
await ui().logger.log(`$ ${commandString}`);
37+
await executeProcess({
38+
command,
39+
args,
40+
ignoreExitCode: true,
41+
});
4242
}
4343

4444
const initialArtifactPaths = Array.isArray(artifacts.artifactsPaths)

packages/plugin-eslint/src/lib/runner/utils.unit.test.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
import type { ESLint } from 'eslint';
22
import { beforeEach, describe, expect, it, vi } from 'vitest';
3+
import { ui } from '@code-pushup/utils';
34
import * as utilsModule from '@code-pushup/utils';
45
import type { LinterOutput } from './types.js';
56
import { loadArtifacts } from './utils.js';
67

8+
vi.mock('@code-pushup/utils', async () => {
9+
const actual = await vi.importActual('@code-pushup/utils');
10+
return {
11+
...actual,
12+
readJsonFile: vi.fn(),
13+
executeProcess: vi.fn(),
14+
};
15+
});
16+
17+
vi.mock('glob', () => ({
18+
glob: vi.fn((pattern: string) => Promise.resolve([pattern])),
19+
}));
20+
721
describe('loadArtifacts', () => {
822
const readJsonFileSpy = vi.spyOn(utilsModule, 'readJsonFile');
923
const executeProcessSpy = vi.spyOn(utilsModule, 'executeProcess');
1024

11-
// Mock data should be raw ESLint.LintResult[] as that's what ESLint CLI outputs
1225
const mockRawResults1: ESLint.LintResult[] = [
1326
{
1427
filePath: '/test/file1.js',
@@ -47,7 +60,6 @@ describe('loadArtifacts', () => {
4760
},
4861
];
4962

50-
// Expected output after our function wraps raw results in LinterOutput format
5163
const expectedLinterOutput1: LinterOutput = {
5264
results: mockRawResults1,
5365
ruleOptionsPerFile: {},
@@ -60,7 +72,7 @@ describe('loadArtifacts', () => {
6072

6173
const artifactsPaths = ['/path/to/artifact1.json', '/path/to/artifact2.json'];
6274

63-
beforeEach(async () => {
75+
beforeEach(() => {
6476
vi.clearAllMocks();
6577
executeProcessSpy.mockResolvedValue({
6678
stdout: JSON.stringify(mockRawResults1),
@@ -80,6 +92,8 @@ describe('loadArtifacts', () => {
8092
expect(executeProcessSpy).not.toHaveBeenCalled();
8193
expect(readJsonFileSpy).toHaveBeenCalledTimes(1);
8294
expect(readJsonFileSpy).toHaveBeenNthCalledWith(1, artifactsPaths.at(0));
95+
96+
expect(ui()).not.toHaveLogged('log', expect.stringMatching(/^\$ /));
8397
});
8498

8599
it('should load multiple artifacts without generateArtifactsCommand', async () => {
@@ -95,6 +109,8 @@ describe('loadArtifacts', () => {
95109
expect(readJsonFileSpy).toHaveBeenCalledTimes(2);
96110
expect(readJsonFileSpy).toHaveBeenNthCalledWith(1, artifactsPaths.at(0));
97111
expect(readJsonFileSpy).toHaveBeenNthCalledWith(2, artifactsPaths.at(1));
112+
113+
expect(ui()).not.toHaveLogged('log', expect.stringMatching(/^\$ /));
98114
});
99115

100116
it('should load artifacts with generateArtifactsCommand as string', async () => {
@@ -112,6 +128,7 @@ describe('loadArtifacts', () => {
112128
command: generateArtifactsCommand,
113129
ignoreExitCode: true,
114130
});
131+
expect(ui()).toHaveLogged('log', `$ ${generateArtifactsCommand}`);
115132
});
116133

117134
it('should load artifacts with generateArtifactsCommand as object', async () => {
@@ -131,5 +148,9 @@ describe('loadArtifacts', () => {
131148
...generateArtifactsCommand,
132149
ignoreExitCode: true,
133150
});
151+
expect(ui()).toHaveLogged(
152+
'log',
153+
'$ nx run-many -t lint --parallel --max-parallel=5',
154+
);
134155
});
135156
});

0 commit comments

Comments
 (0)