Skip to content

Commit 1407b37

Browse files
committed
refactor(nx-plugin): replace duplicated executeProcess with dynamic import
1 parent eb04da8 commit 1407b37

File tree

5 files changed

+8
-281
lines changed

5 files changed

+8
-281
lines changed

packages/nx-plugin/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
"@code-pushup/models": "0.84.0",
3636
"@code-pushup/utils": "0.84.0",
3737
"@nx/devkit": ">=17.0.0",
38-
"ansis": "^3.3.0",
3938
"nx": ">=17.0.0"
4039
},
4140
"files": [

packages/nx-plugin/src/executors/internal/cli.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { logger } from '@nx/devkit';
2-
import type { ProcessConfig } from '../../internal/execute-process.js';
32

43
export function createCliCommandString(options?: {
54
args?: Record<string, unknown>;
@@ -16,7 +15,7 @@ export function createCliCommandObject(options?: {
1615
args?: Record<string, unknown>;
1716
command?: string;
1817
bin?: string;
19-
}): ProcessConfig {
18+
}): import('@code-pushup/utils').ProcessConfig {
2019
const { bin = '@code-pushup/cli', command, args } = options ?? {};
2120
return {
2221
command: 'npx',

packages/nx-plugin/src/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,5 @@ export { configurationGenerator } from './generators/configuration/generator.js'
1717
export type { ConfigurationGeneratorOptions } from './generators/configuration/schema.js';
1818
export { initGenerator, initSchematic } from './generators/init/generator.js';
1919
export { type InitGeneratorSchema } from './generators/init/schema.js';
20-
export {
21-
executeProcess,
22-
type ProcessConfig,
23-
} from './internal/execute-process.js';
2420
export * from './internal/versions.js';
2521
export { createNodes, createNodesV2 } from './plugin/index.js';
Lines changed: 7 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -1,186 +1,11 @@
1-
import { gray } from 'ansis';
2-
import { spawn } from 'node:child_process';
3-
import { ui } from '@code-pushup/utils';
4-
5-
export function calcDuration(start: number, stop?: number): number {
6-
return Math.round((stop ?? performance.now()) - start);
7-
}
8-
9-
/**
10-
* Represents the process result.
11-
* @category Types
12-
* @public
13-
* @property {string} stdout - The stdout of the process.
14-
* @property {string} stderr - The stderr of the process.
15-
* @property {number | null} code - The exit code of the process.
16-
*/
17-
export type ProcessResult = {
18-
stdout: string;
19-
stderr: string;
20-
code: number | null;
21-
date: string;
22-
duration: number;
23-
};
24-
25-
/**
26-
* Error class for process errors.
27-
* Contains additional information about the process result.
28-
* @category Error
29-
* @public
30-
* @class
31-
* @extends Error
32-
* @example
33-
* const result = await executeProcess({})
34-
* .catch((error) => {
35-
* if (error instanceof ProcessError) {
36-
* console.error(error.code);
37-
* console.error(error.stderr);
38-
* console.error(error.stdout);
39-
* }
40-
* });
41-
*
42-
*/
43-
export class ProcessError extends Error {
44-
code: number | null;
45-
stderr: string;
46-
stdout: string;
47-
48-
constructor(result: ProcessResult) {
49-
super(result.stderr);
50-
this.code = result.code;
51-
this.stderr = result.stderr;
52-
this.stdout = result.stdout;
53-
}
54-
}
55-
56-
/**
57-
* Process config object. Contains the command, args and observer.
58-
* @param cfg - process config object with command, args and observer (optional)
59-
* @category Types
60-
* @public
61-
* @property {string} command - The command to execute.
62-
* @property {string[]} args - The arguments for the command.
63-
* @property {ProcessObserver} observer - The observer for the process.
64-
*
65-
* @example
66-
*
67-
* // bash command
68-
* const cfg = {
69-
* command: 'bash',
70-
* args: ['-c', 'echo "hello world"']
71-
* };
72-
*
73-
* // node command
74-
* const cfg = {
75-
* command: 'node',
76-
* args: ['--version']
77-
* };
78-
*
79-
* // npx command
80-
* const cfg = {
81-
* command: 'npx',
82-
* args: ['--version']
83-
*
84-
*/
85-
export type ProcessConfig = {
86-
command: string;
87-
args?: string[];
88-
cwd?: string;
89-
observer?: ProcessObserver;
90-
ignoreExitCode?: boolean;
91-
};
92-
93-
/**
94-
* Process observer object. Contains the onStdout, error and complete function.
95-
* @category Types
96-
* @public
97-
* @property {function} onStdout - The onStdout function of the observer (optional).
98-
* @property {function} onError - The error function of the observer (optional).
99-
* @property {function} onComplete - The complete function of the observer (optional).
100-
*
101-
* @example
102-
* const observer = {
103-
* onStdout: (stdout) => console.info(stdout)
104-
* }
105-
*/
106-
export type ProcessObserver = {
107-
onStdout?: (stdout: string) => void;
108-
onError?: (error: ProcessError) => void;
109-
onComplete?: () => void;
110-
};
111-
1121
/**
113-
* Executes a process and returns a promise with the result as `ProcessResult`.
114-
*
115-
* @example
116-
*
117-
* // sync process execution
118-
* const result = await executeProcess({
119-
* command: 'node',
120-
* args: ['--version']
121-
* });
122-
*
123-
* console.info(result);
124-
*
125-
* // async process execution
126-
* const result = await executeProcess({
127-
* command: 'node',
128-
* args: ['download-data'],
129-
* observer: {
130-
* onStdout: updateProgress,
131-
* error: handleError,
132-
* complete: cleanLogs,
133-
* }
134-
* });
135-
*
136-
* console.info(result);
2+
* Dynamically imports and executes function from utils.
1373
*
138-
* @param cfg - see {@link ProcessConfig}
4+
* This is a workaround for Nx only supporting plugins in CommonJS format.
1395
*/
140-
export function executeProcess(cfg: ProcessConfig): Promise<ProcessResult> {
141-
const { observer, cwd, command, args, ignoreExitCode = false } = cfg;
142-
const { onStdout, onError, onComplete } = observer ?? {};
143-
const date = new Date().toISOString();
144-
const start = performance.now();
145-
146-
const logCommand = [command, ...(args || [])].join(' ');
147-
ui().logger.log(
148-
gray(
149-
`Executing command:\n${logCommand}\nIn working directory:\n${cfg.cwd ?? process.cwd()}`,
150-
),
151-
);
152-
153-
return new Promise((resolve, reject) => {
154-
// shell:true tells Windows to use shell command for spawning a child process
155-
const process = spawn(command, args, { cwd, shell: true });
156-
// eslint-disable-next-line functional/no-let
157-
let stdout = '';
158-
// eslint-disable-next-line functional/no-let
159-
let stderr = '';
160-
161-
process.stdout.on('data', data => {
162-
stdout += String(data);
163-
onStdout?.(String(data));
164-
});
165-
166-
process.stderr.on('data', data => {
167-
stderr += String(data);
168-
});
169-
170-
process.on('error', err => {
171-
stderr += err.toString();
172-
});
173-
174-
process.on('close', code => {
175-
const timings = { date, duration: calcDuration(start) };
176-
if (code === 0 || ignoreExitCode) {
177-
onComplete?.();
178-
resolve({ code, stdout, stderr, ...timings });
179-
} else {
180-
const errorMsg = new ProcessError({ code, stdout, stderr, ...timings });
181-
onError?.(errorMsg);
182-
reject(errorMsg);
183-
}
184-
});
185-
});
6+
export async function executeProcess(
7+
cfg: import('@code-pushup/utils').ProcessConfig,
8+
): Promise<import('@code-pushup/utils').ProcessResult> {
9+
const { executeProcess } = await import('@code-pushup/utils');
10+
return executeProcess(cfg);
18611
}

packages/nx-plugin/src/internal/execute-process.unit.test.ts

Lines changed: 0 additions & 92 deletions
This file was deleted.

0 commit comments

Comments
 (0)