diff --git a/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts b/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts index bc75688cfd33e6..87fcbcd070bd6a 100644 --- a/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts +++ b/packages/nx/src/executors/run-commands/run-commands.impl.spec.ts @@ -36,19 +36,32 @@ describe('Run Commands', () => { expect(readFile(f)).toEqual('123'); }); - it('should not pass --args into underlying command', async () => { - const f = fileSync().name; - const result = await runCommands( - { - command: `echo`, - __unparsed__: ['--args=--key=123'], - args: '--key=123', - unparsedCommandArgs: { args: '--key=123' }, - }, - context - ); - expect(result.terminalOutput.trim()).not.toContain('--args=--key=123'); - }); + it.each([ + { + unparsed: ['test', '--args=--key=123', '--test=1', '--test=2'], + expected: 'test --test=1 --test=2', + }, + { + unparsed: ['test', '--args=--key=123', '--test.a=1', '--test.b=2'], + expected: 'test --test.a=1 --test.b=2', + }, + { unparsed: ['one', '-a=b', `--args=--key=123`], expected: 'one -a=b' }, + ])( + 'should pass command line args $unparsed to the command and ignore --args', + async ({ unparsed: unparsedOptions, expected }) => { + let result = ( + await runCommands( + { + command: `echo`, + __unparsed__: unparsedOptions, + }, + context + ) + ).terminalOutput.trim(); + expect(result).not.toContain('--args=--key=123'); + expect(result).toContain(expected); + } + ); it('should interpolate all unknown args as if they were --args', async () => { const f = fileSync().name; @@ -86,7 +99,7 @@ describe('Run Commands', () => { it('should run commands serially', async () => { const f = fileSync().name; - const result = await runCommands( + let result = await runCommands( { commands: [`sleep 0.2 && echo 1 >> ${f}`, `echo 2 >> ${f}`], parallel: false, @@ -96,6 +109,16 @@ describe('Run Commands', () => { ); expect(result).toEqual(expect.objectContaining({ success: true })); expect(readFile(f)).toEqual('12'); + + result = await runCommands( + { + commands: [`sleep 0.2 && echo 1 >> ${f}`, `echo 2 >> ${f}`], + __unparsed__: ['--no-parallel'], + }, + context + ); + expect(result).toEqual(expect.objectContaining({ success: true })); + expect(readFile(f)).toEqual('1212'); }); it('should run commands in parallel', async () => { @@ -312,6 +335,34 @@ describe('Run Commands', () => { }); }); + it('should not set FORCE_COLOR=true when --no-color is passed', async () => { + const exec = jest.spyOn(require('child_process'), 'exec'); + await runCommands( + { + commands: [`echo 'Hello World'`, `echo 'Hello Universe'`], + parallel: true, + __unparsed__: ['--no-color'], + }, + context + ); + + expect(exec).toHaveBeenCalledTimes(2); + expect(exec).toHaveBeenNthCalledWith(1, `echo 'Hello World'`, { + maxBuffer: LARGE_BUFFER, + env: { + ...process.env, + ...env(), + }, + }); + expect(exec).toHaveBeenNthCalledWith(2, `echo 'Hello Universe'`, { + maxBuffer: LARGE_BUFFER, + env: { + ...process.env, + ...env(), + }, + }); + }); + it('should set FORCE_COLOR=true when running with --color', async () => { const exec = jest.spyOn(require('child_process'), 'exec'); await runCommands( diff --git a/packages/nx/src/executors/run-commands/run-commands.impl.ts b/packages/nx/src/executors/run-commands/run-commands.impl.ts index defcc03542b172..c1c77f36d78801 100644 --- a/packages/nx/src/executors/run-commands/run-commands.impl.ts +++ b/packages/nx/src/executors/run-commands/run-commands.impl.ts @@ -8,7 +8,6 @@ import { getPseudoTerminal, PseudoTerminal, } from '../../tasks-runner/pseudo-terminal'; -import { output } from '../../utils/output'; export const LARGE_BUFFER = 1024 * 1000000; @@ -62,7 +61,9 @@ const propKeys = [ 'command', 'commands', 'color', + 'no-color', 'parallel', + 'no-parallel', 'readyWhen', 'cwd', 'args',