Skip to content

Commit fd79217

Browse files
committed
fix(core): use env vars instead of cli args for runner config
1 parent 5e7f4b7 commit fd79217

File tree

2 files changed

+88
-45
lines changed

2 files changed

+88
-45
lines changed

packages/core/src/lib/implementation/runner.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import {
1515
executeProcess,
1616
fileExists,
1717
isVerbose,
18-
objectToCliArgs,
1918
readJsonFile,
2019
removeDirectoryIfExists,
20+
runnerArgsToEnv,
2121
ui,
2222
} from '@code-pushup/utils';
2323
import { normalizeAuditOutputs } from '../normalize.js';
@@ -40,7 +40,7 @@ export async function executeRunnerConfig(
4040

4141
const { duration, date } = await executeProcess({
4242
command: config.command,
43-
args: [...(config.args ?? []), ...objectToCliArgs(args)],
43+
args: config.args,
4444
observer: {
4545
onStdout: stdout => {
4646
if (isVerbose()) {
@@ -49,6 +49,7 @@ export async function executeRunnerConfig(
4949
},
5050
onStderr: stderr => ui().logger.error(stderr),
5151
},
52+
env: { ...process.env, ...runnerArgsToEnv(args) },
5253
});
5354

5455
// read process output from the file system and parse it

packages/core/src/lib/implementation/runner.unit.test.ts

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import { vol } from 'memfs';
2-
import { type AuditOutputs, auditOutputsSchema } from '@code-pushup/models';
2+
import {
3+
type AuditOutputs,
4+
DEFAULT_PERSIST_CONFIG,
5+
DEFAULT_PERSIST_FILENAME,
6+
DEFAULT_PERSIST_FORMAT,
7+
DEFAULT_PERSIST_OUTPUT_DIR,
8+
DEFAULT_PERSIST_SKIP_REPORT,
9+
auditOutputsSchema,
10+
} from '@code-pushup/models';
311
import {
412
ISO_STRING_REGEXP,
513
MEMFS_VOLUME,
@@ -8,6 +16,7 @@ import {
816
MINIMAL_RUNNER_FUNCTION_MOCK,
917
osAgnosticPath,
1018
} from '@code-pushup/test-utils';
19+
import * as utils from '@code-pushup/utils';
1120
import {
1221
type RunnerResult,
1322
executePluginRunner,
@@ -38,10 +47,14 @@ describe('executeRunnerConfig', () => {
3847
},
3948
MEMFS_VOLUME,
4049
);
50+
51+
vi.spyOn(utils, 'executeProcess');
4152
});
4253

4354
it('should execute valid runner config', async () => {
44-
const runnerResult = await executeRunnerConfig(MINIMAL_RUNNER_CONFIG_MOCK);
55+
const runnerResult = await executeRunnerConfig(MINIMAL_RUNNER_CONFIG_MOCK, {
56+
persist: DEFAULT_PERSIST_CONFIG,
57+
});
4558

4659
// data sanity
4760
expect((runnerResult.audits as AuditOutputs)[0]?.slug).toBe('node-version');
@@ -50,23 +63,42 @@ describe('executeRunnerConfig', () => {
5063

5164
// schema validation
5265
expect(() => auditOutputsSchema.parse(runnerResult.audits)).not.toThrow();
53-
});
5466

55-
it('should use outputTransform when provided', async () => {
56-
const runnerResult = await executeRunnerConfig({
67+
// executed process configuration
68+
expect(utils.executeProcess).toHaveBeenCalledWith<[utils.ProcessConfig]>({
5769
command: 'node',
5870
args: ['-v'],
59-
outputFile: 'output.json',
60-
outputTransform: (outputs: unknown): Promise<AuditOutputs> =>
61-
Promise.resolve([
62-
{
63-
slug: (outputs as AuditOutputs)[0]!.slug,
64-
score: 0.3,
65-
value: 16,
66-
displayValue: '16.0.0',
67-
},
68-
]),
71+
env: expect.objectContaining({
72+
CP_PERSIST_OUTPUT_DIR: DEFAULT_PERSIST_OUTPUT_DIR,
73+
CP_PERSIST_FILENAME: DEFAULT_PERSIST_FILENAME,
74+
CP_PERSIST_FORMAT: DEFAULT_PERSIST_FORMAT.join(','),
75+
CP_PERSIST_SKIP_REPORTS: `${DEFAULT_PERSIST_SKIP_REPORT}`,
76+
}),
77+
observer: {
78+
onStdout: expect.any(Function),
79+
onStderr: expect.any(Function),
80+
},
6981
});
82+
});
83+
84+
it('should use outputTransform when provided', async () => {
85+
const runnerResult = await executeRunnerConfig(
86+
{
87+
command: 'node',
88+
args: ['-v'],
89+
outputFile: 'output.json',
90+
outputTransform: (outputs: unknown): Promise<AuditOutputs> =>
91+
Promise.resolve([
92+
{
93+
slug: (outputs as AuditOutputs)[0]!.slug,
94+
score: 0.3,
95+
value: 16,
96+
displayValue: '16.0.0',
97+
},
98+
]),
99+
},
100+
{ persist: DEFAULT_PERSIST_CONFIG },
101+
);
70102
const auditOutputs = runnerResult.audits as AuditOutputs;
71103

72104
expect(auditOutputs[0]?.slug).toBe('node-version');
@@ -75,13 +107,16 @@ describe('executeRunnerConfig', () => {
75107

76108
it('should throw if outputTransform throws', async () => {
77109
await expect(
78-
executeRunnerConfig({
79-
command: 'node',
80-
args: ['-v'],
81-
outputFile: 'output.json',
82-
outputTransform: () =>
83-
Promise.reject(new Error('Error: outputTransform has failed.')),
84-
}),
110+
executeRunnerConfig(
111+
{
112+
command: 'node',
113+
args: ['-v'],
114+
outputFile: 'output.json',
115+
outputTransform: () =>
116+
Promise.reject(new Error('Error: outputTransform has failed.')),
117+
},
118+
{ persist: DEFAULT_PERSIST_CONFIG },
119+
),
85120
).rejects.toThrow('Error: outputTransform has failed.');
86121
});
87122
});
@@ -90,6 +125,7 @@ describe('executeRunnerFunction', () => {
90125
it('should execute a valid runner function', async () => {
91126
const runnerResult: RunnerResult = await executeRunnerFunction(
92127
MINIMAL_RUNNER_FUNCTION_MOCK,
128+
{ persist: DEFAULT_PERSIST_CONFIG },
93129
);
94130
const auditOutputs = runnerResult.audits as AuditOutputs;
95131

@@ -102,14 +138,12 @@ describe('executeRunnerFunction', () => {
102138
});
103139

104140
it('should throw if the runner function throws', async () => {
105-
const nextSpy = vi.fn();
106141
await expect(
107142
executeRunnerFunction(
108143
() => Promise.reject(new Error('Error: Runner has failed.')),
109-
nextSpy,
144+
{ persist: DEFAULT_PERSIST_CONFIG },
110145
),
111146
).rejects.toThrow('Error: Runner has failed.');
112-
expect(nextSpy).not.toHaveBeenCalled();
113147
});
114148

115149
it('should throw with an invalid runner type', async () => {
@@ -122,7 +156,9 @@ describe('executeRunnerFunction', () => {
122156

123157
describe('executePluginRunner', () => {
124158
it('should execute a valid plugin config', async () => {
125-
const pluginResult = await executePluginRunner(MINIMAL_PLUGIN_CONFIG_MOCK);
159+
const pluginResult = await executePluginRunner(MINIMAL_PLUGIN_CONFIG_MOCK, {
160+
persist: DEFAULT_PERSIST_CONFIG,
161+
});
126162
expect(pluginResult.audits[0]?.slug).toBe('node-version');
127163
});
128164

@@ -141,14 +177,17 @@ describe('executePluginRunner', () => {
141177
);
142178

143179
await expect(
144-
executePluginRunner({
145-
...MINIMAL_PLUGIN_CONFIG_MOCK,
146-
runner: {
147-
command: 'node',
148-
args: ['-v'],
149-
outputFile: 'output.json',
180+
executePluginRunner(
181+
{
182+
...MINIMAL_PLUGIN_CONFIG_MOCK,
183+
runner: {
184+
command: 'node',
185+
args: ['-v'],
186+
outputFile: 'output.json',
187+
},
150188
},
151-
}),
189+
{ persist: DEFAULT_PERSIST_CONFIG },
190+
),
152191
).resolves.toStrictEqual({
153192
duration: expect.any(Number),
154193
date: expect.any(String),
@@ -164,16 +203,19 @@ describe('executePluginRunner', () => {
164203

165204
it('should yield audit outputs for a valid runner function', async () => {
166205
await expect(
167-
executePluginRunner({
168-
...MINIMAL_PLUGIN_CONFIG_MOCK,
169-
runner: () => [
170-
{
171-
slug: 'node-version',
172-
score: 0.3,
173-
value: 16,
174-
},
175-
],
176-
}),
206+
executePluginRunner(
207+
{
208+
...MINIMAL_PLUGIN_CONFIG_MOCK,
209+
runner: () => [
210+
{
211+
slug: 'node-version',
212+
score: 0.3,
213+
value: 16,
214+
},
215+
],
216+
},
217+
{ persist: DEFAULT_PERSIST_CONFIG },
218+
),
177219
).resolves.toStrictEqual({
178220
duration: expect.any(Number),
179221
date: expect.any(String),

0 commit comments

Comments
 (0)