Skip to content

Commit 86a0c12

Browse files
committed
Move subprocess helpers from update-release-branch.ts to command.ts
1 parent 20ef42b commit 86a0c12

2 files changed

Lines changed: 83 additions & 80 deletions

File tree

pr-checks/command.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { execFileSync, ExecFileSyncOptions } from "node:child_process";
2+
3+
import { DryRunOption, REPO_ROOT } from "./config";
4+
5+
/** Options for {@link runCommand}. */
6+
export interface RunCommandOptions extends DryRunOption {
7+
/** Options for `execFileSync`. */
8+
execOptions?: ExecFileSyncOptions;
9+
}
10+
11+
/**
12+
* Runs a command, streaming output to the console by default.
13+
*
14+
* @param command The name of the command to run.
15+
* @param args The arguments for the command.
16+
* @throws When the process exits with a non-zero exit code.
17+
* @param options How to run the command.
18+
*/
19+
export function runCommand(
20+
command: string,
21+
args: string[],
22+
options?: RunCommandOptions,
23+
) {
24+
if (!options?.dryRun) {
25+
console.log(`Running \`${command} ${args.join(" ")}\`.`);
26+
return execFileSync(command, args, {
27+
stdio: "inherit",
28+
cwd: REPO_ROOT,
29+
...options?.execOptions,
30+
});
31+
} else {
32+
console.info(
33+
`[DRY RUN] Would have executed '${command} ${args.join(" ")}'`,
34+
);
35+
return "";
36+
}
37+
}
38+
39+
/** Options for {@link runGit}. */
40+
export interface RunGitOptions extends DryRunOption {
41+
/** When true, non-zero exit codes will not throw. */
42+
allowNonZeroExitCode?: boolean;
43+
}
44+
45+
/**
46+
* Runs `git` with the given `args` and returns the stdout.
47+
*
48+
* @param args - Arguments to pass to `git`.
49+
* @param options - Optional settings.
50+
* @throws If `git` does not exit successfully, unless
51+
* `options.allowNonZeroExitCode` is `true`.
52+
* @returns The trimmed stdout output.
53+
*/
54+
export function runGit(args: string[], options?: RunGitOptions): string {
55+
const execOptions: ExecFileSyncOptions = {
56+
encoding: "utf8",
57+
stdio: ["pipe", "pipe", "pipe"],
58+
};
59+
60+
try {
61+
const result = runCommand("git", args, {
62+
dryRun: options?.dryRun,
63+
execOptions,
64+
}) as string;
65+
return result.trimEnd();
66+
} catch (error: unknown) {
67+
if (options?.allowNonZeroExitCode) {
68+
// execFileSync throws an object with `stdout` when the process exits
69+
// with a non-zero code.
70+
const execError = error as { stdout?: Buffer | string };
71+
if (typeof execError.stdout === "string") {
72+
return execError.stdout.trimEnd();
73+
}
74+
if (Buffer.isBuffer(execError.stdout)) {
75+
return execError.stdout.toString("utf8").trimEnd();
76+
}
77+
return "";
78+
}
79+
throw error;
80+
}
81+
}

pr-checks/update-release-branch.ts

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
* [--dry-run]
1919
*/
2020

21-
import { execFileSync, type ExecFileSyncOptions } from "node:child_process";
21+
import { execFileSync } from "node:child_process";
2222
import { parseArgs } from "node:util";
2323

2424
import { type ApiClient, getApiClient } from "./api-client";
2525
import * as changelog from "./changelog";
26-
import { DryRunOption, REPO_ROOT } from "./config";
26+
import { runCommand, runGit } from "./command";
2727
import {
2828
getCurrentVersion,
2929
replaceVersionInPackageJson,
@@ -65,84 +65,6 @@ export function getGitHubToken(): string {
6565
throw new Error("Missing GitHub token. Set GITHUB_TOKEN or GH_TOKEN.");
6666
}
6767

68-
/** Options for {@link runCommand}. */
69-
export interface RunCommandOptions extends DryRunOption {
70-
/** Options for `execFileSync`. */
71-
execOptions?: ExecFileSyncOptions;
72-
}
73-
74-
/**
75-
* Runs a command, streaming output to the console by default.
76-
*
77-
* @param command The name of the command to run.
78-
* @param args The arguments for the command.
79-
* @throws When the process exits with a non-zero exit code.
80-
* @param options How to run the command.
81-
*/
82-
export function runCommand(
83-
command: string,
84-
args: string[],
85-
options?: RunCommandOptions,
86-
) {
87-
if (!options?.dryRun) {
88-
console.log(`Running \`${command} ${args.join(" ")}\`.`);
89-
return execFileSync(command, args, {
90-
stdio: "inherit",
91-
cwd: REPO_ROOT,
92-
...options?.execOptions,
93-
});
94-
} else {
95-
console.info(
96-
`[DRY RUN] Would have executed '${command} ${args.join(" ")}'`,
97-
);
98-
return "";
99-
}
100-
}
101-
102-
/** Options for {@link runGit}. */
103-
export interface RunGitOptions extends DryRunOption {
104-
/** When true, non-zero exit codes will not throw. */
105-
allowNonZeroExitCode?: boolean;
106-
}
107-
108-
/**
109-
* Runs `git` with the given `args` and returns the stdout.
110-
*
111-
* @param args - Arguments to pass to `git`.
112-
* @param options - Optional settings.
113-
* @throws If `git` does not exit successfully, unless
114-
* `options.allowNonZeroExitCode` is `true`.
115-
* @returns The trimmed stdout output.
116-
*/
117-
export function runGit(args: string[], options?: RunGitOptions): string {
118-
const execOptions: ExecFileSyncOptions = {
119-
encoding: "utf8",
120-
stdio: ["pipe", "pipe", "pipe"],
121-
};
122-
123-
try {
124-
const result = runCommand("git", args, {
125-
dryRun: options?.dryRun,
126-
execOptions,
127-
}) as string;
128-
return result.trimEnd();
129-
} catch (error: unknown) {
130-
if (options?.allowNonZeroExitCode) {
131-
// execFileSync throws an object with `stdout` when the process exits
132-
// with a non-zero code.
133-
const execError = error as { stdout?: Buffer | string };
134-
if (typeof execError.stdout === "string") {
135-
return execError.stdout.trimEnd();
136-
}
137-
if (Buffer.isBuffer(execError.stdout)) {
138-
return execError.stdout.toString("utf8").trimEnd();
139-
}
140-
return "";
141-
}
142-
throw error;
143-
}
144-
}
145-
14668
/** Returns true if the given branch exists on the origin remote. */
14769
export function branchExistsOnRemote(branchName: string): boolean {
14870
const result = runGit(["ls-remote", "--heads", ORIGIN, branchName]);

0 commit comments

Comments
 (0)