@@ -64,7 +64,7 @@ export type ExecCmdResult<T> = {
64
64
* Command execution duration.
65
65
*/
66
66
execCmdDuration : Duration ;
67
- }
67
+ } ;
68
68
69
69
const buildCmdOptions = ( options ?: ExecCmdOptions ) : ExecCmdOptions & { cwd : string } => {
70
70
const defaults : ExecCmdOptions = {
@@ -89,9 +89,12 @@ const hrtimeToMillisDuration = (hrTime: [number, number]) =>
89
89
const addJsonOutput = < T > ( cmd : string , result : ExecCmdResult < T > , file : string ) : ExecCmdResult < T > => {
90
90
if ( cmd . includes ( '--json' ) ) {
91
91
try {
92
- result . jsonOutput = parseJson ( stripAnsi ( fs . readFileSync ( file , 'utf-8' ) ) ) as unknown as JsonOutput < T > ;
92
+ return {
93
+ ...result ,
94
+ jsonOutput : parseJson ( stripAnsi ( fs . readFileSync ( file , 'utf-8' ) ) ) as unknown as JsonOutput < T > ,
95
+ } ;
93
96
} catch ( parseErr : unknown ) {
94
- result . jsonError = parseErr as Error ;
97
+ return { ... result , jsonError : parseErr as Error } ;
95
98
}
96
99
}
97
100
return result ;
@@ -363,22 +366,30 @@ export type PromptAnswers = Record<string, Many<string>>;
363
366
* { cwd: session.dir, ensureExitCode: 0 }
364
367
* );
365
368
* ```
369
+ *
370
+ * If your flag values included spaces (where you'd normally need quotes like `some:cmd --flag "value with spaces"`),
371
+ * use an array of strings to represent the command ex: `['some:cmd', '--flag', 'value with spaces']`
366
372
*/
367
373
export async function execInteractiveCmd (
368
- command : string ,
374
+ command : string | string [ ] ,
369
375
answers : PromptAnswers ,
370
376
options : InteractiveCommandExecutionOptions = { }
371
377
) : Promise < InteractiveCommandExecutionResult > {
372
378
const debug = Debug ( 'testkit:execInteractiveCmd' ) ;
373
379
374
380
return new Promise ( ( resolve , reject ) => {
381
+ if ( typeof command === 'string' && command . includes ( '"' ) ) {
382
+ throw new Error (
383
+ 'Use an array of strings to represent the command when it includes quotes, ex: ["some:cmd", "--flag", "value with spaces"]'
384
+ ) ;
385
+ }
375
386
const bin = determineExecutable ( options ?. cli ) . trim ( ) ;
376
387
const startTime = process . hrtime ( ) ;
377
388
const opts =
378
389
process . platform === 'win32'
379
390
? { shell : true , cwd : process . cwd ( ) , ...options }
380
391
: { cwd : process . cwd ( ) , ...options } ;
381
- const child = spawn ( bin , command . split ( ' ' ) , opts ) ;
392
+ const child = spawn ( bin , Array . isArray ( command ) ? command : command . split ( ' ' ) , opts ) ;
382
393
child . stdin . setDefaultEncoding ( 'utf-8' ) ;
383
394
384
395
const seen = new Set < string > ( ) ;
@@ -448,7 +459,7 @@ export async function execInteractiveCmd(
448
459
449
460
if ( isNumber ( options . ensureExitCode ) && code !== options . ensureExitCode ) {
450
461
reject (
451
- getExitCodeError ( command , options . ensureExitCode , {
462
+ getExitCodeError ( Array . isArray ( command ) ? command . join ( ' ' ) : command , options . ensureExitCode , {
452
463
stdout : result . stdout ,
453
464
stderr : result . stderr ,
454
465
code : result . code ,
0 commit comments