Skip to content

Commit d82c68d

Browse files
committed
feat(core): convert all issue file paths after executing plugin
1 parent b12df6d commit d82c68d

File tree

9 files changed

+90
-31
lines changed

9 files changed

+90
-31
lines changed

e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap

+20-20
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
469469
"message": "'loading' is assigned a value but never used.",
470470
"severity": "warning",
471471
"source": {
472-
"file": "src/App.jsx",
472+
"file": "examples/react-todos-app/src/App.jsx",
473473
"position": {
474474
"endColumn": 18,
475475
"endLine": 8,
@@ -519,7 +519,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
519519
"message": "Unexpected block statement surrounding arrow body; move the returned value immediately after the \`=>\`.",
520520
"severity": "warning",
521521
"source": {
522-
"file": "src/components/TodoFilter.jsx",
522+
"file": "examples/react-todos-app/src/components/TodoFilter.jsx",
523523
"position": {
524524
"endColumn": 2,
525525
"endLine": 25,
@@ -569,7 +569,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
569569
"message": "Expected '===' and instead saw '=='.",
570570
"severity": "warning",
571571
"source": {
572-
"file": "src/hooks/useTodos.js",
572+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
573573
"position": {
574574
"endColumn": 43,
575575
"endLine": 41,
@@ -595,7 +595,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
595595
"message": "Arrow function has too many lines (71). Maximum allowed is 50.",
596596
"severity": "warning",
597597
"source": {
598-
"file": "src/hooks/useTodos.js",
598+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
599599
"position": {
600600
"endColumn": 2,
601601
"endLine": 73,
@@ -633,7 +633,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
633633
"message": "'data' is already declared in the upper scope on line 5 column 10.",
634634
"severity": "warning",
635635
"source": {
636-
"file": "src/hooks/useTodos.js",
636+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
637637
"position": {
638638
"endColumn": 17,
639639
"endLine": 11,
@@ -646,7 +646,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
646646
"message": "'data' is already declared in the upper scope on line 5 column 10.",
647647
"severity": "warning",
648648
"source": {
649-
"file": "src/hooks/useTodos.js",
649+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
650650
"position": {
651651
"endColumn": 21,
652652
"endLine": 29,
@@ -659,7 +659,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
659659
"message": "'data' is already declared in the upper scope on line 5 column 10.",
660660
"severity": "warning",
661661
"source": {
662-
"file": "src/hooks/useTodos.js",
662+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
663663
"position": {
664664
"endColumn": 17,
665665
"endLine": 41,
@@ -697,7 +697,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
697697
"message": "Expected property shorthand.",
698698
"severity": "warning",
699699
"source": {
700-
"file": "src/hooks/useTodos.js",
700+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
701701
"position": {
702702
"endColumn": 19,
703703
"endLine": 19,
@@ -710,7 +710,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
710710
"message": "Expected property shorthand.",
711711
"severity": "warning",
712712
"source": {
713-
"file": "src/hooks/useTodos.js",
713+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
714714
"position": {
715715
"endColumn": 19,
716716
"endLine": 32,
@@ -723,7 +723,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
723723
"message": "Expected property shorthand.",
724724
"severity": "warning",
725725
"source": {
726-
"file": "src/hooks/useTodos.js",
726+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
727727
"position": {
728728
"endColumn": 25,
729729
"endLine": 33,
@@ -761,7 +761,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
761761
"message": "'root' is never reassigned. Use 'const' instead.",
762762
"severity": "warning",
763763
"source": {
764-
"file": "src/index.jsx",
764+
"file": "examples/react-todos-app/src/index.jsx",
765765
"position": {
766766
"endColumn": 9,
767767
"endLine": 5,
@@ -811,7 +811,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
811811
"message": "Missing \\"key\\" prop for element in iterator",
812812
"severity": "warning",
813813
"source": {
814-
"file": "src/components/TodoList.jsx",
814+
"file": "examples/react-todos-app/src/components/TodoList.jsx",
815815
"position": {
816816
"endColumn": 12,
817817
"endLine": 28,
@@ -837,7 +837,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
837837
"message": "'onCreate' is missing in props validation",
838838
"severity": "warning",
839839
"source": {
840-
"file": "src/components/CreateTodo.jsx",
840+
"file": "examples/react-todos-app/src/components/CreateTodo.jsx",
841841
"position": {
842842
"endColumn": 23,
843843
"endLine": 15,
@@ -850,7 +850,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
850850
"message": "'setQuery' is missing in props validation",
851851
"severity": "warning",
852852
"source": {
853-
"file": "src/components/TodoFilter.jsx",
853+
"file": "examples/react-todos-app/src/components/TodoFilter.jsx",
854854
"position": {
855855
"endColumn": 25,
856856
"endLine": 10,
@@ -863,7 +863,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
863863
"message": "'setHideComplete' is missing in props validation",
864864
"severity": "warning",
865865
"source": {
866-
"file": "src/components/TodoFilter.jsx",
866+
"file": "examples/react-todos-app/src/components/TodoFilter.jsx",
867867
"position": {
868868
"endColumn": 34,
869869
"endLine": 18,
@@ -876,7 +876,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
876876
"message": "'todos' is missing in props validation",
877877
"severity": "warning",
878878
"source": {
879-
"file": "src/components/TodoList.jsx",
879+
"file": "examples/react-todos-app/src/components/TodoList.jsx",
880880
"position": {
881881
"endColumn": 17,
882882
"endLine": 6,
@@ -889,7 +889,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
889889
"message": "'todos.map' is missing in props validation",
890890
"severity": "warning",
891891
"source": {
892-
"file": "src/components/TodoList.jsx",
892+
"file": "examples/react-todos-app/src/components/TodoList.jsx",
893893
"position": {
894894
"endColumn": 21,
895895
"endLine": 6,
@@ -902,7 +902,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
902902
"message": "'onEdit' is missing in props validation",
903903
"severity": "warning",
904904
"source": {
905-
"file": "src/components/TodoList.jsx",
905+
"file": "examples/react-todos-app/src/components/TodoList.jsx",
906906
"position": {
907907
"endColumn": 27,
908908
"endLine": 13,
@@ -952,7 +952,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
952952
"message": "React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?",
953953
"severity": "warning",
954954
"source": {
955-
"file": "src/hooks/useTodos.js",
955+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
956956
"position": {
957957
"endColumn": 31,
958958
"endLine": 17,
@@ -965,7 +965,7 @@ exports[`CLI collect > should run ESLint plugin and create report.json 1`] = `
965965
"message": "React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?",
966966
"severity": "warning",
967967
"source": {
968-
"file": "src/hooks/useTodos.js",
968+
"file": "examples/react-todos-app/src/hooks/useTodos.js",
969969
"position": {
970970
"endColumn": 29,
971971
"endLine": 40,

examples/plugins/vite.config.integration.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default defineConfig({
1818
globalSetup: ['global-setup.ts'],
1919
setupFiles: [
2020
'../../testing-utils/src/lib/setup/fs.mock.ts',
21+
'../../testing-utils/src/lib/setup/git.mock.ts',
2122
'../../testing-utils/src/lib/setup/console.mock.ts',
2223
'../../testing-utils/src/lib/setup/reset.mocks.ts',
2324
],

examples/plugins/vite.config.unit.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default defineConfig({
1818
globalSetup: ['global-setup.ts'],
1919
setupFiles: [
2020
'../../testing-utils/src/lib/setup/fs.mock.ts',
21+
'../../testing-utils/src/lib/setup/git.mock.ts',
2122
'../../testing-utils/src/lib/setup/console.mock.ts',
2223
'../../testing-utils/src/lib/setup/reset.mocks.ts',
2324
],

packages/cli/docs/custom-plugins.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ We will extend the `fileSizeAuditOutput` with `details` show which files exceed
495495
// file-size.plugin.ts
496496
// ...
497497
import { basename } from 'path';
498-
import { formatBytes, toUnixPath } from '@code-pushup/utils';
498+
import { formatBytes } from '@code-pushup/utils';
499499
import { AuditOutput } from './plugin-process-output';
500500

501501
async function runnerFunction(options: Options): Promise<AuditOutputs> {
@@ -521,8 +521,7 @@ async function runnerFunction(options: Options): Promise<AuditOutputs> {
521521
export function assertFileSize(file: string, size: number, budget?: number): Issue {
522522
const auditOutputBase = {
523523
source: {
524-
// format path to be in scope of the repository
525-
file: toUnixPath(file, { toRelative: true }),
524+
file,
526525
},
527526
} satisfies AuditOutput['source'];
528527

packages/cli/vite.config.unit.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default defineConfig({
1818
globalSetup: ['global-setup.ts'],
1919
setupFiles: [
2020
'../../testing-utils/src/lib/setup/fs.mock.ts',
21+
'../../testing-utils/src/lib/setup/git.mock.ts',
2122
'../../testing-utils/src/lib/setup/console.mock.ts',
2223
'../../testing-utils/src/lib/setup/portal-client.mock.ts',
2324
'../../testing-utils/src/lib/setup/reset.mocks.ts',

packages/core/src/lib/implementation/execute-plugin.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
groupByStatus,
1515
logMultipleResults,
1616
} from '@code-pushup/utils';
17+
import { normalizeAuditOutputs } from '../normalize';
1718
import { executeRunnerConfig, executeRunnerFunction } from './runner';
1819

1920
/**
@@ -71,8 +72,10 @@ export async function executePlugin(
7172
const auditOutputs = auditOutputsSchema.parse(unvalidatedAuditOutputs);
7273
auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits);
7374

75+
const normalizedAuditOutputs = await normalizeAuditOutputs(auditOutputs);
76+
7477
// enrich `AuditOutputs` to `AuditReport`
75-
const auditReports: AuditReport[] = auditOutputs.map(
78+
const auditReports: AuditReport[] = normalizedAuditOutputs.map(
7679
(auditOutput: AuditOutput) => ({
7780
...auditOutput,
7881
...(pluginConfigAudits.find(

packages/core/src/lib/normalize.ts

+43-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,51 @@
11
import {
2+
type AuditOutputs,
23
PERSIST_FILENAME,
34
PERSIST_FORMAT,
45
PERSIST_OUTPUT_DIR,
56
PersistConfig,
67
} from '@code-pushup/models';
8+
import { formatGitPath, getGitRoot } from '@code-pushup/utils';
79

8-
export const normalizePersistConfig = (
10+
export function normalizePersistConfig(
911
cfg?: Partial<PersistConfig>,
10-
): Required<PersistConfig> => ({
11-
outputDir: PERSIST_OUTPUT_DIR,
12-
filename: PERSIST_FILENAME,
13-
format: PERSIST_FORMAT,
14-
...cfg,
15-
});
12+
): Required<PersistConfig> {
13+
return {
14+
outputDir: PERSIST_OUTPUT_DIR,
15+
filename: PERSIST_FILENAME,
16+
format: PERSIST_FORMAT,
17+
...cfg,
18+
};
19+
}
20+
21+
export async function normalizeAuditOutputs(
22+
audits: AuditOutputs,
23+
): Promise<AuditOutputs> {
24+
const gitRoot = await getGitRoot();
25+
26+
return audits.map(audit => {
27+
if (
28+
audit.details?.issues == null ||
29+
audit.details.issues.every(issue => issue.source == null)
30+
) {
31+
return audit;
32+
}
33+
return {
34+
...audit,
35+
details: {
36+
...audit.details,
37+
issues: audit.details.issues.map(issue =>
38+
issue.source == null
39+
? issue
40+
: {
41+
...issue,
42+
source: {
43+
...issue.source,
44+
file: formatGitPath(issue.source.file, gitRoot),
45+
},
46+
},
47+
),
48+
},
49+
};
50+
});
51+
}

packages/core/vite.config.unit.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default defineConfig({
1818
globalSetup: ['global-setup.ts'],
1919
setupFiles: [
2020
'../../testing-utils/src/lib/setup/fs.mock.ts',
21+
'../../testing-utils/src/lib/setup/git.mock.ts',
2122
'../../testing-utils/src/lib/setup/console.mock.ts',
2223
'../../testing-utils/src/lib/setup/reset.mocks.ts',
2324
'../../testing-utils/src/lib/setup/portal-client.mock.ts',
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { vi } from 'vitest';
2+
import { MEMFS_VOLUME } from '../constants';
3+
4+
vi.mock('simple-git', () => ({
5+
simpleGit: () => ({
6+
revparse: () => Promise.resolve(MEMFS_VOLUME),
7+
log: () =>
8+
Promise.resolve({
9+
latest: {
10+
hash: '0123456789abcdef0123456789abcdef01234567',
11+
message: 'Minor fixes',
12+
author: 'John Doe',
13+
date: 'Wed Feb 14 16:00:00 2024 +0100',
14+
},
15+
}),
16+
}),
17+
}));

0 commit comments

Comments
 (0)