Skip to content

Commit

Permalink
feat: execInteractive takes string or string[] (#637)
Browse files Browse the repository at this point in the history
* feat: execInteractive takes string or string[]

* chore(release): 5.2.4-qa.0 [skip ci]

* fix: restore mutation of cmd

* chore(release): 5.2.4-qa.1 [skip ci]

* feat: throw an error message on commands with quotes to encourage the array form

---------

Co-authored-by: svc-cli-bot <[email protected]>
  • Loading branch information
mshanemc and svc-cli-bot authored Apr 25, 2024
1 parent f738ee3 commit 9819b52
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@salesforce/cli-plugins-testkit",
"description": "Provides test utilities to assist Salesforce CLI plug-in authors with writing non-unit tests (NUT).",
"version": "5.2.3",
"version": "5.2.4-qa.1",
"author": "Salesforce",
"license": "BSD-3-Clause",
"main": "lib/index.js",
Expand Down
23 changes: 17 additions & 6 deletions src/execCmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export type ExecCmdResult<T> = {
* Command execution duration.
*/
execCmdDuration: Duration;
}
};

const buildCmdOptions = (options?: ExecCmdOptions): ExecCmdOptions & { cwd: string } => {
const defaults: ExecCmdOptions = {
Expand All @@ -89,9 +89,12 @@ const hrtimeToMillisDuration = (hrTime: [number, number]) =>
const addJsonOutput = <T>(cmd: string, result: ExecCmdResult<T>, file: string): ExecCmdResult<T> => {
if (cmd.includes('--json')) {
try {
result.jsonOutput = parseJson(stripAnsi(fs.readFileSync(file, 'utf-8'))) as unknown as JsonOutput<T>;
return {
...result,
jsonOutput: parseJson(stripAnsi(fs.readFileSync(file, 'utf-8'))) as unknown as JsonOutput<T>,
};
} catch (parseErr: unknown) {
result.jsonError = parseErr as Error;
return { ...result, jsonError: parseErr as Error };
}
}
return result;
Expand Down Expand Up @@ -363,22 +366,30 @@ export type PromptAnswers = Record<string, Many<string>>;
* { cwd: session.dir, ensureExitCode: 0 }
* );
* ```
*
* If your flag values included spaces (where you'd normally need quotes like `some:cmd --flag "value with spaces"`),
* use an array of strings to represent the command ex: `['some:cmd', '--flag', 'value with spaces']`
*/
export async function execInteractiveCmd(
command: string,
command: string | string[],
answers: PromptAnswers,
options: InteractiveCommandExecutionOptions = {}
): Promise<InteractiveCommandExecutionResult> {
const debug = Debug('testkit:execInteractiveCmd');

return new Promise((resolve, reject) => {
if (typeof command === 'string' && command.includes('"')) {
throw new Error(
'Use an array of strings to represent the command when it includes quotes, ex: ["some:cmd", "--flag", "value with spaces"]'
);
}
const bin = determineExecutable(options?.cli).trim();
const startTime = process.hrtime();
const opts =
process.platform === 'win32'
? { shell: true, cwd: process.cwd(), ...options }
: { cwd: process.cwd(), ...options };
const child = spawn(bin, command.split(' '), opts);
const child = spawn(bin, Array.isArray(command) ? command : command.split(' '), opts);
child.stdin.setDefaultEncoding('utf-8');

const seen = new Set<string>();
Expand Down Expand Up @@ -448,7 +459,7 @@ export async function execInteractiveCmd(

if (isNumber(options.ensureExitCode) && code !== options.ensureExitCode) {
reject(
getExitCodeError(command, options.ensureExitCode, {
getExitCodeError(Array.isArray(command) ? command.join(' ') : command, options.ensureExitCode, {
stdout: result.stdout,
stderr: result.stderr,
code: result.code,
Expand Down

0 comments on commit 9819b52

Please sign in to comment.