fix(core): add quotes around string to command (#23056)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
- nx run will not have quotes, but underlying command will have

<!-- This is the behavior we should expect with the changes in this PR
-->
<img width="524" alt="Screenshot 2024-05-23 at 2 07 20 PM"
src="https://github.com/nrwl/nx/assets/16211801/7c96f884-3c11-4f56-b6b4-b3fd41ac2187">
<img width="471" alt="Screenshot 2024-05-23 at 2 07 03 PM"
src="https://github.com/nrwl/nx/assets/16211801/b6746a25-ebfc-4cb2-ad1d-4f8600782037">



## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
This commit is contained in:
Emily Xiong 2024-06-05 17:02:48 -04:00 committed by GitHub
parent 58041e893c
commit bccb2c5018
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 98 additions and 5 deletions

View File

@ -60,6 +60,32 @@ describe('Nx Running Tests', () => {
const output = runCLI(`echo ${proj} ${args}`);
expect(output).toContain(`ECHO: ${args.replace(/^.*-- /, '')}`);
});
it.each([
{
args: '--test="hello world" "abc def"',
result: '--test="hello world" "abc def"',
},
{
args: `--test="hello world" 'abc def'`,
result: '--test="hello world" "abc def"',
},
{
args: `--test="hello world" 'abcdef'`,
result: '--test="hello world" abcdef',
},
{
args: `--test='hello world' 'abcdef'`,
result: '--test="hello world" abcdef',
},
{
args: `"--test='hello world' 'abcdef'"`,
result: `--test='hello world' 'abcdef'`,
},
])('should forward %args properly with quotes', ({ args, result }) => {
const output = runCLI(`echo ${proj} ${args}`);
expect(output).toContain(`ECHO: ${result}`);
});
});
it('should execute long running tasks', () => {

View File

@ -81,10 +81,6 @@ export function rewriteTargetsAndProjects(args: string[]) {
return newArgs;
}
function wrapIntoQuotesIfNeeded(arg: string) {
return arg.indexOf(':') > -1 ? `"${arg}"` : arg;
}
function isKnownCommand(command: string) {
const commands = [
...Object.keys(

View File

@ -323,6 +323,56 @@ describe('Run Commands', () => {
)
).toEqual('echo "hello world"');
});
it('should interpolate provided values with spaces', () => {
expect(
interpolateArgsIntoCommand(
'echo',
{
unknownOptions: { hello: 'test 123' },
parsedArgs: { hello: 'test 123' },
} as any,
true
)
).toEqual('echo --hello="test 123"'); // should wrap in quotes
expect(
interpolateArgsIntoCommand(
'echo',
{
unknownOptions: { hello: '"test 123"' },
parsedArgs: { hello: '"test 123"' },
} as any,
true
)
).toEqual('echo --hello="test 123"'); // should leave double quotes
expect(
interpolateArgsIntoCommand(
'echo',
{
unknownOptions: { hello: "'test 123'" },
parsedArgs: { hello: "'test 123'" },
} as any,
true
)
).toEqual("echo --hello='test 123'"); // should leave single quote
expect(
interpolateArgsIntoCommand(
'echo',
{
__unparsed__: [
'--hello=test 123',
'hello world',
'"random config"',
'456',
],
} as any,
true
)
).toEqual(`echo --hello="test 123" "hello world" "random config" 456`); // should wrap aroound __unparsed__ args with key value
});
});
describe('--color', () => {

View File

@ -494,6 +494,7 @@ export function interpolateArgsIntoCommand(
opts.parsedArgs[k] === opts.unknownOptions[k]
)
.map((k) => `--${k}=${opts.unknownOptions[k]}`)
.map(wrapArgIntoQuotesIfNeeded)
.join(' ');
}
if (opts.args) {
@ -505,7 +506,9 @@ export function interpolateArgsIntoCommand(
opts.unparsedCommandArgs
);
if (filterdParsedOptions.length > 0) {
args += ` ${filterdParsedOptions.join(' ')}`;
args += ` ${filterdParsedOptions
.map(wrapArgIntoQuotesIfNeeded)
.join(' ')}`;
}
}
return `${command}${args}`;
@ -627,3 +630,21 @@ function registerProcessListener() {
// will store results to the cache and will terminate this process
});
}
function wrapArgIntoQuotesIfNeeded(arg: string): string {
if (arg.includes('=')) {
const [key, value] = arg.split('=');
if (
key.startsWith('--') &&
value.includes(' ') &&
!(value[0] === "'" || value[0] === '"')
) {
return `${key}="${value}"`;
}
return arg;
} else if (arg.includes(' ') && !(arg[0] === "'" || arg[0] === '"')) {
return `"${arg}"`;
} else {
return arg;
}
}