Skip to content

Commit f23715d

Browse files
authored
Merge 7264e6b into c677fa2
2 parents c677fa2 + 7264e6b commit f23715d

File tree

10 files changed

+543
-172
lines changed

10 files changed

+543
-172
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import { type Tree, writeJson } from '@nx/devkit';
2+
import path from 'node:path';
3+
import { readProjectConfiguration } from 'nx/src/generators/utils/project-configuration';
4+
import { afterEach, expect } from 'vitest';
5+
import { generateCodePushupConfig } from '@code-pushup/nx-plugin';
6+
import {
7+
generateProject,
8+
generateWorkspaceAndProject,
9+
materializeTree,
10+
nxShowProjectJson,
11+
nxTargetProject,
12+
registerPluginInWorkspace,
13+
} from '@code-pushup/test-nx-utils';
14+
import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR } from '@code-pushup/test-utils';
15+
16+
describe('nx-plugin-derived-config', () => {
17+
let root: string;
18+
let tree: Tree;
19+
const projectName = 'pkg';
20+
const testFileDir = path.join(
21+
E2E_ENVIRONMENTS_DIR,
22+
nxTargetProject(),
23+
TEST_OUTPUT_DIR,
24+
'plugin-create-nodes',
25+
);
26+
27+
beforeEach(async () => {
28+
tree = await generateWorkspaceAndProject();
29+
registerPluginInWorkspace(tree, '@code-pushup/nx-plugin');
30+
await generateProject(tree, projectName);
31+
root = readProjectConfiguration(tree, projectName).root;
32+
generateCodePushupConfig(tree, root);
33+
});
34+
35+
afterEach(async () => {
36+
// await teardownTestFolder(testFileDir);
37+
});
38+
39+
it('should derive config from project.json', async () => {
40+
const cwd = path.join(testFileDir, 'project-config');
41+
const projectJsonPath = path.join('libs', projectName, 'project.json');
42+
const packageJsonPath = path.join('libs', projectName, 'package.json');
43+
tree.delete(projectJsonPath);
44+
tree.delete(packageJsonPath);
45+
writeJson(tree, projectJsonPath, {
46+
root,
47+
name: projectName,
48+
targets: {
49+
'code-pushup': {
50+
executor: `@code-pushup/nx-plugin:cli`,
51+
options: {
52+
'persist.filename': 'my-report',
53+
},
54+
},
55+
},
56+
});
57+
await materializeTree(tree, cwd);
58+
59+
const { code, projectJson } = await nxShowProjectJson(cwd, projectName);
60+
expect(code).toBe(0);
61+
62+
expect(projectJson.targets).toStrictEqual(
63+
expect.objectContaining({
64+
'code-pushup': {
65+
configurations: {},
66+
executor: `@code-pushup/nx-plugin:cli`,
67+
options: {
68+
'persist.filename': 'my-report',
69+
},
70+
parallelism: true,
71+
},
72+
}),
73+
);
74+
});
75+
76+
it('should derive config from package.json', async () => {
77+
const cwd = path.join(testFileDir, 'package-config');
78+
const projectJsonPath = path.join('libs', projectName, 'project.json');
79+
const packageJsonPath = path.join('libs', projectName, 'package.json');
80+
tree.delete(projectJsonPath);
81+
tree.delete(packageJsonPath);
82+
writeJson(tree, packageJsonPath, {
83+
name: `@code-pushup/${projectName}`,
84+
nx: {
85+
root,
86+
name: projectName,
87+
targets: {
88+
'code-pushup': {
89+
executor: `@code-pushup/nx-plugin:cli`,
90+
options: {
91+
'persist.filename': 'my-report',
92+
},
93+
},
94+
},
95+
},
96+
});
97+
await materializeTree(tree, cwd);
98+
99+
const { code, projectJson } = await nxShowProjectJson(cwd, projectName);
100+
expect(code).toBe(0);
101+
102+
expect(projectJson.targets).toStrictEqual(
103+
expect.objectContaining({
104+
'code-pushup': {
105+
configurations: {},
106+
executor: `@code-pushup/nx-plugin:cli`,
107+
options: {
108+
'persist.filename': 'my-report',
109+
},
110+
parallelism: true,
111+
},
112+
}),
113+
);
114+
});
115+
116+
it('should derive config from mixed', async () => {
117+
const cwd = path.join(testFileDir, 'mixed-config');
118+
const projectJsonPath = path.join('libs', projectName, 'project.json');
119+
const packageJsonPath = path.join('libs', projectName, 'package.json');
120+
121+
writeJson(tree, projectJsonPath, {
122+
root,
123+
name: projectName,
124+
targets: {
125+
'code-pushup': {
126+
executor: `@code-pushup/nx-plugin:cli`,
127+
options: {
128+
'persist.filename': 'my-report',
129+
},
130+
},
131+
},
132+
});
133+
writeJson(tree, packageJsonPath, {
134+
name: `@code-pushup/${projectName}`,
135+
nx: {
136+
root,
137+
name: projectName,
138+
targets: {
139+
'code-pushup': {
140+
executor: `@code-pushup/nx-plugin:cli`,
141+
options: {
142+
'persist.outputPath': 'my-dir',
143+
},
144+
},
145+
},
146+
},
147+
});
148+
await materializeTree(tree, cwd);
149+
150+
const { code, projectJson } = await nxShowProjectJson(cwd, projectName);
151+
expect(code).toBe(0);
152+
153+
expect(projectJson.targets).toStrictEqual(
154+
expect.objectContaining({
155+
'code-pushup': {
156+
configurations: {},
157+
executor: `@code-pushup/nx-plugin:cli`,
158+
options: {
159+
'persist.filename': 'my-report',
160+
'persist.outputPath': 'my-dir',
161+
},
162+
parallelism: true,
163+
},
164+
}),
165+
);
166+
});
167+
});

packages/nx-plugin/src/plugin/plugin.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import type {
2-
CreateNodes,
3-
CreateNodesContext,
4-
CreateNodesResult,
1+
import {
2+
type CreateNodes,
3+
type CreateNodesContext,
4+
type CreateNodesResult,
5+
type CreateNodesV2,
6+
createNodesFromFiles,
57
} from '@nx/devkit';
68
import { PROJECT_JSON_FILE_NAME } from '../internal/constants.js';
79
import { createTargets } from './target/targets.js';
810
import type { CreateNodesOptions } from './types.js';
911
import { normalizedCreateNodesContext } from './utils.js';
1012

11-
// name has to be "createNodes" to get picked up by Nx
13+
/** Create the nodes for a V1 Plugin. The name `createNodes` is required by Nx in order to be picked up as a plugin. */
1214
export const createNodes: CreateNodes = [
1315
`**/${PROJECT_JSON_FILE_NAME}`,
1416
async (
@@ -32,3 +34,31 @@ export const createNodes: CreateNodes = [
3234
};
3335
},
3436
];
37+
38+
/** Create the nodes for a V2 Plugin. The name `createNodesV2` is required by Nx in order to be picked up as a plugin. */
39+
export const createNodesV2: CreateNodesV2 = [
40+
`**/${PROJECT_JSON_FILE_NAME}`,
41+
async (configFiles, options, context) =>
42+
createNodesFromFiles(
43+
async (globMatchingFile, internalOptions) => {
44+
const parsedCreateNodesOptions = internalOptions as CreateNodesOptions;
45+
46+
const normalizedContext = await normalizedCreateNodesContext(
47+
context,
48+
globMatchingFile,
49+
parsedCreateNodesOptions,
50+
);
51+
52+
return {
53+
projects: {
54+
[normalizedContext.projectRoot]: {
55+
targets: await createTargets(normalizedContext),
56+
},
57+
},
58+
};
59+
},
60+
configFiles,
61+
options,
62+
context,
63+
),
64+
];

0 commit comments

Comments
 (0)