Skip to content

Commit 4c7fd04

Browse files
committed
fix(ng-dev): properly pass input to stdin of child processes
This is a small regression introduced via: 933dcd4
1 parent c403b10 commit 4c7fd04

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

ng-dev/utils/child-process.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ import {
1414
SpawnSyncOptions as _SpawnSyncOptions,
1515
ExecOptions as _ExecOptions,
1616
exec as _exec,
17+
ChildProcess as _ChildProcess,
1718
} from 'child_process';
1819
import {Log} from './logging.js';
20+
import assert from 'assert';
1921

2022
export interface CommonCmdOpts {
23+
// Stdin text to provide to the process. The raw text will be written to `stdin` and then
24+
// the stream is closed. This is equivalent to the `input` option from `SpawnSyncOption`.
25+
input?: string;
2126
/** Console output mode. Defaults to "enabled". */
2227
mode?: 'enabled' | 'silent' | 'on-error';
2328
/** Whether to prevent exit codes being treated as failures. */
@@ -27,14 +32,10 @@ export interface CommonCmdOpts {
2732
/** Interface describing the options for spawning a process synchronously. */
2833
export interface SpawnSyncOptions
2934
extends CommonCmdOpts,
30-
Omit<_SpawnSyncOptions, 'shell' | 'stdio'> {}
35+
Omit<_SpawnSyncOptions, 'shell' | 'stdio' | 'input'> {}
3136

3237
/** Interface describing the options for spawning a process. */
33-
export interface SpawnOptions extends CommonCmdOpts, Omit<_SpawnOptions, 'shell' | 'stdio'> {
34-
// Stdin text to provide to the process. The raw text will be written to `stdin` and then
35-
// the stream is closed. This is equivalent to the `input` option from `SpawnSyncOption`.
36-
input?: string;
37-
}
38+
export interface SpawnOptions extends CommonCmdOpts, Omit<_SpawnOptions, 'shell' | 'stdio'> {}
3839

3940
/** Interface describing the options for exec-ing a process. */
4041
export interface ExecOptions extends CommonCmdOpts, Omit<_ExecOptions, 'shell' | 'stdio'> {}
@@ -172,28 +173,28 @@ function getEnvironmentForNonInteractiveCommand(
172173
/**
173174
* Process the ChildProcess object created by an async command.
174175
*/
175-
function processAsyncCmd(
176-
cmd: string,
177-
opts: CommonCmdOpts,
178-
childProcess: ReturnType<typeof _exec>,
179-
): Promise<ExecResult>;
180-
function processAsyncCmd(
181-
cmd: string,
182-
opts: CommonCmdOpts,
183-
childProcess: ReturnType<typeof _spawn>,
184-
): Promise<SpawnResult>;
185176
function processAsyncCmd(
186177
command: string,
187178
options: CommonCmdOpts,
188-
childProcess: ReturnType<typeof _exec | typeof _spawn>,
189-
) {
179+
childProcess: _ChildProcess,
180+
): Promise<SpawnResult> {
190181
return new Promise((resolve, reject) => {
191182
let logOutput = '';
192183
let stdout = '';
193184
let stderr = '';
194185

195186
Log.debug(`Executing command: ${command}`);
196187

188+
// If provided, write `input` text to the process `stdin`.
189+
if (options.input !== undefined) {
190+
assert(
191+
childProcess.stdin,
192+
'Cannot write process `input` if there is no pipe `stdin` channel.',
193+
);
194+
childProcess.stdin.write(options.input);
195+
childProcess.stdin.end();
196+
}
197+
197198
// Capture the stdout separately so that it can be passed as resolve value.
198199
// This is useful if commands return parsable stdout.
199200
childProcess.stderr?.on('data', (message) => {

0 commit comments

Comments
 (0)