Skip to content

Commit 5e7f4b7

Browse files
committed
feat(utils): convert runner args to and from environment variables
1 parent fcb7aa3 commit 5e7f4b7

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

packages/utils/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export {
1616
isCI,
1717
isEnvVarEnabled,
1818
isVerbose,
19+
runnerArgsFromEnv,
20+
runnerArgsToEnv,
1921
} from './lib/env.js';
2022
export { stringifyError } from './lib/errors.js';
2123
export {

packages/utils/src/lib/env.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
import {
2+
DEFAULT_PERSIST_FILENAME,
3+
DEFAULT_PERSIST_FORMAT,
4+
DEFAULT_PERSIST_OUTPUT_DIR,
5+
DEFAULT_PERSIST_SKIP_REPORT,
6+
type RunnerArgs,
7+
formatSchema,
8+
} from '@code-pushup/models';
19
import { ui } from './logging.js';
210

311
export function isCI() {
@@ -51,3 +59,37 @@ export function coerceBooleanValue(value: unknown): boolean | undefined {
5159

5260
return undefined;
5361
}
62+
63+
type RUNNER_ARGS_ENV_VAR =
64+
| 'CP_PERSIST_OUTPUT_DIR'
65+
| 'CP_PERSIST_FILENAME'
66+
| 'CP_PERSIST_FORMAT'
67+
| 'CP_PERSIST_SKIP_REPORTS';
68+
69+
type RunnerEnv = Record<RUNNER_ARGS_ENV_VAR, string>;
70+
71+
const FORMAT_SEP = ',';
72+
73+
export function runnerArgsToEnv(config: RunnerArgs): RunnerEnv {
74+
return {
75+
CP_PERSIST_OUTPUT_DIR: config.persist.outputDir,
76+
CP_PERSIST_FILENAME: config.persist.filename,
77+
CP_PERSIST_FORMAT: config.persist.format.join(FORMAT_SEP),
78+
CP_PERSIST_SKIP_REPORTS: config.persist.skipReports.toString(),
79+
};
80+
}
81+
82+
export function runnerArgsFromEnv(env: Partial<RunnerEnv>): RunnerArgs {
83+
const formats = env.CP_PERSIST_FORMAT?.split(FORMAT_SEP)
84+
.map(item => formatSchema.safeParse(item).data)
85+
.filter(item => item != null);
86+
const skipReports = coerceBooleanValue(env.CP_PERSIST_SKIP_REPORTS);
87+
return {
88+
persist: {
89+
outputDir: env.CP_PERSIST_OUTPUT_DIR || DEFAULT_PERSIST_OUTPUT_DIR,
90+
filename: env.CP_PERSIST_FILENAME || DEFAULT_PERSIST_FILENAME,
91+
format: formats?.length ? formats : DEFAULT_PERSIST_FORMAT,
92+
skipReports: skipReports ?? DEFAULT_PERSIST_SKIP_REPORT,
93+
},
94+
};
95+
}

packages/utils/src/lib/env.unit.test.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
import { coerceBooleanValue, isEnvVarEnabled } from './env.js';
1+
import {
2+
DEFAULT_PERSIST_FILENAME,
3+
DEFAULT_PERSIST_FORMAT,
4+
DEFAULT_PERSIST_SKIP_REPORT,
5+
} from '@code-pushup/models';
6+
import {
7+
coerceBooleanValue,
8+
isEnvVarEnabled,
9+
runnerArgsFromEnv,
10+
runnerArgsToEnv,
11+
} from './env.js';
212
import { ui } from './logging.js';
313

414
describe('isEnvVarEnabled', () => {
@@ -65,3 +75,61 @@ describe('coerceBooleanValue', () => {
6575
expect(coerceBooleanValue(input)).toBe(expected);
6676
});
6777
});
78+
79+
describe('runnerArgsToEnv', () => {
80+
it('should convert runner args object to namespaced environment variables', () => {
81+
expect(
82+
runnerArgsToEnv({
83+
persist: {
84+
outputDir: '.code-pushup',
85+
filename: 'report',
86+
format: ['json', 'md'],
87+
skipReports: false,
88+
},
89+
}),
90+
).toEqual({
91+
CP_PERSIST_OUTPUT_DIR: '.code-pushup',
92+
CP_PERSIST_FILENAME: 'report',
93+
CP_PERSIST_FORMAT: 'json,md',
94+
CP_PERSIST_SKIP_REPORTS: 'false',
95+
});
96+
});
97+
});
98+
99+
describe('runnerArgsFromEnv', () => {
100+
it('should parse environment variables and create runner args object', () => {
101+
expect(
102+
runnerArgsFromEnv({
103+
CP_PERSIST_OUTPUT_DIR: '.code-pushup',
104+
CP_PERSIST_FILENAME: 'report',
105+
CP_PERSIST_FORMAT: 'json,md',
106+
CP_PERSIST_SKIP_REPORTS: 'false',
107+
}),
108+
).toEqual({
109+
persist: {
110+
outputDir: '.code-pushup',
111+
filename: 'report',
112+
format: ['json', 'md'],
113+
skipReports: false,
114+
},
115+
});
116+
});
117+
118+
it('should fallback to defaults instead of empty or invalid values', () => {
119+
expect(
120+
runnerArgsFromEnv({
121+
CP_PERSIST_OUTPUT_DIR: '.code-pushup',
122+
CP_PERSIST_FILENAME: '',
123+
CP_PERSIST_FORMAT: 'html',
124+
CP_PERSIST_SKIP_REPORTS: 'yup',
125+
}),
126+
).toEqual({
127+
persist: {
128+
outputDir: '.code-pushup',
129+
filename: DEFAULT_PERSIST_FILENAME,
130+
format: DEFAULT_PERSIST_FORMAT,
131+
skipReports: DEFAULT_PERSIST_SKIP_REPORT,
132+
},
133+
});
134+
});
135+
});

0 commit comments

Comments
 (0)