microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3e669c74c1e16a47afe2b98706bdcf8dad4434af

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/internal-build-utils/src/common.ts

94lines · modecode

1import { ChildProcess, spawn, SpawnOptions } from "child_process";
2
3export class CommandFailedError extends Error {
4 constructor(msg: string, public proc: ChildProcess) {
5 super(msg);
6 }
7}
8
9/**
10 * Return the correct executable name if on unix or windows(with .cmd extension)
11 * @param cmd to run
12 * @returns
13 */
14export function xplatCmd(cmd: string) {
15 return process.platform === "win32" ? `${cmd}.cmd` : cmd;
16}
17
18export interface RunOptions extends SpawnOptions {
19 silent?: boolean;
20 encoding?: string;
21 ignoreCommandNotFound?: boolean;
22 throwOnNonZeroExit?: boolean;
23}
24
25export async function run(command: string, args: string[], options?: RunOptions) {
26 if (!options?.silent) {
27 // eslint-disable-next-line no-console
28 console.log();
29 // eslint-disable-next-line no-console
30 console.log(`> ${command} ${args.join(" ")}`);
31 }
32
33 options = {
34 stdio: "inherit",
35 throwOnNonZeroExit: true,
36 ...options,
37 };
38
39 try {
40 const result = await execAsync(command, args, options);
41 if (options.throwOnNonZeroExit && result.exitCode !== undefined && result.exitCode !== 0) {
42 throw new CommandFailedError(
43 `Command \`${command} ${args.join(" ")}\` failed with exit code ${result.exitCode}`,
44 result.proc
45 );
46 }
47 return result;
48 } catch (e: any) {
49 if (options.ignoreCommandNotFound && e.code === "ENOENT") {
50 // eslint-disable-next-line no-console
51 console.log(`Skipped: Command \`${command}\` not found.`);
52 return { exitCode: 0, stdout: "", stderr: "" };
53 } else {
54 throw e;
55 }
56 }
57}
58
59export async function execAsync(
60 command: string,
61 args: string[],
62 options: SpawnOptions
63): Promise<{ exitCode: number; stdout: string; stderr: string; proc: ChildProcess }> {
64 const child = spawn(command, args, options);
65
66 return new Promise((resolve, reject) => {
67 child.on("error", (error) => {
68 reject(error);
69 });
70 const stdout: Buffer[] = [];
71 const stderr: Buffer[] = [];
72 child.stdout?.on("data", (data) => stdout.push(data));
73 child.stderr?.on("data", (data) => stderr.push(data));
74
75 child.on("exit", (exitCode) => {
76 resolve({
77 exitCode: exitCode ?? -1,
78 stdout: Buffer.concat(stdout).toString(),
79 stderr: Buffer.concat(stderr).toString(),
80 proc: child,
81 });
82 });
83 });
84}
85
86export function clearScreen() {
87 process.stdout.write("\x1bc");
88}
89
90export function logWithTime(msg: string) {
91 const time = new Date().toLocaleTimeString();
92 // eslint-disable-next-line no-console
93 console.log(`[${time}] ${msg}`);
94}
95