cli-common: polish API surface for run

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-11-29 17:11:50 +01:00
parent 7fbac5cfac
commit ab13a89744
8 changed files with 37 additions and 42 deletions
+3 -3
View File
@@ -53,13 +53,13 @@ export interface RunChildProcess extends ChildProcess {
}
// @public
export type RunLogFunc = (data: Buffer) => void;
export type RunOnOutput = (data: Buffer) => void;
// @public
export type RunOptions = Omit<SpawnOptions, 'env'> & {
env?: Partial<NodeJS.ProcessEnv>;
stdoutLogFunc?: RunLogFunc;
stderrLogFunc?: RunLogFunc;
onStdout?: RunOnOutput;
onStderr?: RunOnOutput;
stdio?: SpawnOptions['stdio'];
};
+1 -1
View File
@@ -30,6 +30,6 @@ export {
runCheck,
type RunChildProcess,
type RunOptions,
type RunLogFunc,
type RunOnOutput,
} from './run';
export { ExitCodeError } from './errors';
+14 -19
View File
@@ -24,7 +24,7 @@ import { assertError } from '@backstage/errors';
*
* @public
*/
export type RunLogFunc = (data: Buffer) => void;
export type RunOnOutput = (data: Buffer) => void;
/**
* Options for running a child process with {@link run} or related functions.
@@ -33,8 +33,8 @@ export type RunLogFunc = (data: Buffer) => void;
*/
export type RunOptions = Omit<SpawnOptions, 'env'> & {
env?: Partial<NodeJS.ProcessEnv>;
stdoutLogFunc?: RunLogFunc;
stderrLogFunc?: RunLogFunc;
onStdout?: RunOnOutput;
onStderr?: RunOnOutput;
stdio?: SpawnOptions['stdio'];
};
@@ -69,12 +69,7 @@ export function run(args: string[], options: RunOptions = {}): RunChildProcess {
const [name, ...cmdArgs] = args;
const {
stdoutLogFunc,
stderrLogFunc,
stdio: customStdio,
...spawnOptions
} = options;
const { onStdout, onStderr, stdio: customStdio, ...spawnOptions } = options;
const env: NodeJS.ProcessEnv = {
...process.env,
FORCE_COLOR: 'true',
@@ -85,8 +80,8 @@ export function run(args: string[], options: RunOptions = {}): RunChildProcess {
customStdio ??
([
'inherit',
stdoutLogFunc ? 'pipe' : 'inherit',
stderrLogFunc ? 'pipe' : 'inherit',
onStdout ? 'pipe' : 'inherit',
onStderr ? 'pipe' : 'inherit',
] as ('inherit' | 'pipe')[]);
const child = spawn(name, cmdArgs, {
@@ -95,11 +90,11 @@ export function run(args: string[], options: RunOptions = {}): RunChildProcess {
env,
}) as RunChildProcess;
if (stdoutLogFunc && child.stdout) {
child.stdout.on('data', stdoutLogFunc);
if (onStdout && child.stdout) {
child.stdout.on('data', onStdout);
}
if (stderrLogFunc && child.stderr) {
child.stderr.on('data', stderrLogFunc);
if (onStderr && child.stderr) {
child.stderr.on('data', onStderr);
}
const commandName = args.join(' ');
@@ -175,13 +170,13 @@ export async function runOutput(
try {
await run(args, {
...options,
stdoutLogFunc: data => {
onStdout: data => {
stdoutChunks.push(data);
options?.stdoutLogFunc?.(data);
options?.onStdout?.(data);
},
stderrLogFunc: data => {
onStderr: data => {
stderrChunks.push(data);
options?.stderrLogFunc?.(data);
options?.onStderr?.(data);
},
}).waitForExit();
@@ -230,8 +230,8 @@ export async function createDistWorkspace(
worker: async ({ name, dir, args }) => {
await run(['yarn', 'run', 'build', ...(args || [])], {
cwd: dir,
stdoutLogFunc: prefixLogFunc(`${name}: `, 'stdout'),
stderrLogFunc: prefixLogFunc(`${name}: `, 'stderr'),
onStdout: prefixLogFunc(`${name}: `, 'stdout'),
onStderr: prefixLogFunc(`${name}: `, 'stderr'),
}).waitForExit();
},
});
@@ -39,8 +39,8 @@ export async function runYarnInstall() {
),
),
},
stdoutLogFunc: data => installOutput.push(data),
stderrLogFunc: data => installOutput.push(data),
onStdout: data => installOutput.push(data),
onStderr: data => installOutput.push(data),
}).waitForExit();
spinner.succeed();
} catch (error) {
@@ -18,7 +18,7 @@ import { OptionValues } from 'commander';
import openBrowser from 'react-dev-utils/openBrowser';
import { createLogger } from '../../lib/utility';
import { runMkdocsServer } from '../../lib/mkdocsServer';
import { RunLogFunc } from '@backstage/cli-common';
import { RunOnOutput } from '@backstage/cli-common';
import { getMkdocsYml } from '@backstage/plugin-techdocs-node';
import fs from 'fs-extra';
import { checkIfDockerIsOperational } from './utils';
@@ -45,7 +45,7 @@ export default async function serveMkdocs(opts: OptionValues) {
// We want to open browser only once based on a log.
let boolOpenBrowserTriggered = false;
const logFunc: RunLogFunc = data => {
const logFunc: RunOnOutput = data => {
// Sometimes the lines contain an unnecessary extra new line in between
const logLines = data.toString().split('\n');
const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]';
@@ -80,8 +80,8 @@ export default async function serveMkdocs(opts: OptionValues) {
dockerEntrypoint: opts.dockerEntrypoint,
dockerOptions: opts.dockerOption,
useDocker: opts.docker,
stdoutLogFunc: logFunc,
stderrLogFunc: logFunc,
onStdout: logFunc,
onStderr: logFunc,
});
// Keep waiting for user to cancel the process
@@ -17,7 +17,7 @@
import { OptionValues } from 'commander';
import path from 'path';
import openBrowser from 'react-dev-utils/openBrowser';
import { findPaths, RunLogFunc } from '@backstage/cli-common';
import { findPaths, RunOnOutput } from '@backstage/cli-common';
import HTTPServer from '../../lib/httpServer';
import { runMkdocsServer } from '../../lib/mkdocsServer';
import { createLogger } from '../../lib/utility';
@@ -82,7 +82,7 @@ export default async function serve(opts: OptionValues) {
}
let mkdocsServerHasStarted = false;
const mkdocsLogFunc: RunLogFunc = data => {
const mkdocsLogFunc: RunOnOutput = data => {
// Sometimes the lines contain an unnecessary extra new line
const logLines = data.toString().split('\n');
const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]';
@@ -112,8 +112,8 @@ export default async function serve(opts: OptionValues) {
dockerEntrypoint: opts.dockerEntrypoint,
dockerOptions: opts.dockerOption,
useDocker: opts.docker,
stdoutLogFunc: mkdocsLogFunc,
stderrLogFunc: mkdocsLogFunc,
onStdout: mkdocsLogFunc,
onStderr: mkdocsLogFunc,
mkdocsConfigFileName: mkdocsYmlPath,
mkdocsParameterClean: opts.mkdocsParameterClean,
mkdocsParameterDirtyReload: opts.mkdocsParameterDirtyreload,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { run, RunChildProcess, RunLogFunc } from '@backstage/cli-common';
import { run, RunChildProcess, RunOnOutput } from '@backstage/cli-common';
export const runMkdocsServer = (options: {
port?: string;
@@ -22,8 +22,8 @@ export const runMkdocsServer = (options: {
dockerImage?: string;
dockerEntrypoint?: string;
dockerOptions?: string[];
stdoutLogFunc?: RunLogFunc;
stderrLogFunc?: RunLogFunc;
onStdout?: RunOnOutput;
onStderr?: RunOnOutput;
mkdocsConfigFileName?: string;
mkdocsParameterClean?: boolean;
mkdocsParameterDirtyReload?: boolean;
@@ -62,8 +62,8 @@ export const runMkdocsServer = (options: {
...(options.mkdocsParameterStrict ? ['--strict'] : []),
],
{
stdoutLogFunc: options.stdoutLogFunc,
stderrLogFunc: options.stderrLogFunc,
onStdout: options.onStdout,
onStderr: options.onStderr,
},
);
}
@@ -82,8 +82,8 @@ export const runMkdocsServer = (options: {
...(options.mkdocsParameterStrict ? ['--strict'] : []),
],
{
stdoutLogFunc: options.stdoutLogFunc,
stderrLogFunc: options.stderrLogFunc,
onStdout: options.onStdout,
onStderr: options.onStderr,
},
);
};