diff --git a/docs/generated/cli/print-affected.md b/docs/generated/cli/print-affected.md index ef68341af5..f28d2cf84d 100644 --- a/docs/generated/cli/print-affected.md +++ b/docs/generated/cli/print-affected.md @@ -129,6 +129,12 @@ Default: `false` Rerun the tasks even when the results are available in the cache +### target + +Type: `string` + +Task to run for affected projects + ### type Type: `string` diff --git a/docs/generated/packages/nx.json b/docs/generated/packages/nx.json index e91393e200..1255c0cbff 100644 --- a/docs/generated/packages/nx.json +++ b/docs/generated/packages/nx.json @@ -81,7 +81,7 @@ "name": "print-affected", "id": "print-affected", "file": "generated/cli/print-affected", - "content": "---\ntitle: 'print-affected - CLI command'\ndescription: 'Prints information about the projects and targets affected by changes'\n---\n\n# print-affected\n\nPrints information about the projects and targets affected by changes\n\n## Usage\n\n```terminal\nnx print-affected\n```\n\nInstall `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.\n\n### Examples\n\nPrint information about affected projects and the project graph:\n\n```terminal\n nx print-affected\n```\n\nPrint information about the projects affected by the changes between main and HEAD (e.g,. PR):\n\n```terminal\n nx print-affected --base=main --head=HEAD\n```\n\nPrints information about the affected projects and a list of tasks to test them:\n\n```terminal\n nx print-affected --target=test\n```\n\nPrints the projects property from the print-affected output:\n\n```terminal\n nx print-affected --target=build --select=projects\n```\n\nPrints the tasks.target.project property from the print-affected output:\n\n```terminal\n nx print-affected --target=build --select=tasks.target.project\n```\n\n## Options\n\n### all\n\nType: `boolean`\n\nAll projects\n\n### base\n\nType: `string`\n\nBase of the current branch (usually main)\n\n### configuration\n\nType: `string`\n\nThis is the configuration to use when performing tasks on projects\n\n### exclude\n\nType: `array`\n\nDefault: `[]`\n\nExclude certain projects from being processed\n\n### files\n\nType: `array`\n\nChange the way Nx is calculating the affected command by providing directly changed files, list of files delimited by commas\n\n### head\n\nType: `string`\n\nLatest commit of the current branch (usually HEAD)\n\n### help\n\nType: `boolean`\n\nShow help\n\n### nx-bail\n\nType: `boolean`\n\nDefault: `false`\n\nStop command execution after the first failed task\n\n### nx-ignore-cycles\n\nType: `boolean`\n\nDefault: `false`\n\nIgnore cycles in the task graph\n\n### runner\n\nType: `string`\n\nThis is the name of the tasks runner configured in nx.json\n\n### select\n\nType: `string`\n\nSelect the subset of the returned json document (e.g., --select=projects)\n\n### skip-nx-cache\n\nType: `boolean`\n\nDefault: `false`\n\nRerun the tasks even when the results are available in the cache\n\n### type\n\nType: `string`\n\nChoices: [app, lib]\n\nSelect the type of projects to be returned (e.g., --type=app)\n\n### uncommitted\n\nType: `boolean`\n\nUncommitted changes\n\n### untracked\n\nType: `boolean`\n\nUntracked changes\n\n### verbose\n\nType: `boolean`\n\nDefault: `false`\n\nPrints additional information about the commands (e.g., stack traces)\n\n### version\n\nType: `boolean`\n\nShow version number\n" + "content": "---\ntitle: 'print-affected - CLI command'\ndescription: 'Prints information about the projects and targets affected by changes'\n---\n\n# print-affected\n\nPrints information about the projects and targets affected by changes\n\n## Usage\n\n```terminal\nnx print-affected\n```\n\nInstall `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.\n\n### Examples\n\nPrint information about affected projects and the project graph:\n\n```terminal\n nx print-affected\n```\n\nPrint information about the projects affected by the changes between main and HEAD (e.g,. PR):\n\n```terminal\n nx print-affected --base=main --head=HEAD\n```\n\nPrints information about the affected projects and a list of tasks to test them:\n\n```terminal\n nx print-affected --target=test\n```\n\nPrints the projects property from the print-affected output:\n\n```terminal\n nx print-affected --target=build --select=projects\n```\n\nPrints the tasks.target.project property from the print-affected output:\n\n```terminal\n nx print-affected --target=build --select=tasks.target.project\n```\n\n## Options\n\n### all\n\nType: `boolean`\n\nAll projects\n\n### base\n\nType: `string`\n\nBase of the current branch (usually main)\n\n### configuration\n\nType: `string`\n\nThis is the configuration to use when performing tasks on projects\n\n### exclude\n\nType: `array`\n\nDefault: `[]`\n\nExclude certain projects from being processed\n\n### files\n\nType: `array`\n\nChange the way Nx is calculating the affected command by providing directly changed files, list of files delimited by commas\n\n### head\n\nType: `string`\n\nLatest commit of the current branch (usually HEAD)\n\n### help\n\nType: `boolean`\n\nShow help\n\n### nx-bail\n\nType: `boolean`\n\nDefault: `false`\n\nStop command execution after the first failed task\n\n### nx-ignore-cycles\n\nType: `boolean`\n\nDefault: `false`\n\nIgnore cycles in the task graph\n\n### runner\n\nType: `string`\n\nThis is the name of the tasks runner configured in nx.json\n\n### select\n\nType: `string`\n\nSelect the subset of the returned json document (e.g., --select=projects)\n\n### skip-nx-cache\n\nType: `boolean`\n\nDefault: `false`\n\nRerun the tasks even when the results are available in the cache\n\n### target\n\nType: `string`\n\nTask to run for affected projects\n\n### type\n\nType: `string`\n\nChoices: [app, lib]\n\nSelect the type of projects to be returned (e.g., --type=app)\n\n### uncommitted\n\nType: `boolean`\n\nUncommitted changes\n\n### untracked\n\nType: `boolean`\n\nUntracked changes\n\n### verbose\n\nType: `boolean`\n\nDefault: `false`\n\nPrints additional information about the commands (e.g., stack traces)\n\n### version\n\nType: `boolean`\n\nShow version number\n" }, { "name": "format:check", diff --git a/e2e/angular-core/src/ng-add.test.ts b/e2e/angular-core/src/ng-add.test.ts index 4c25c0a3f3..3ac5fae806 100644 --- a/e2e/angular-core/src/ng-add.test.ts +++ b/e2e/angular-core/src/ng-add.test.ts @@ -581,7 +581,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { // check building project let output = runCLI(`build ${project} --outputHashing none`); expect(output).toContain( - `> nx run ${project}:build:production --outputHashing=none` + `> nx run ${project}:build:production --outputHashing none` ); expect(output).toContain( `Successfully ran target build for project ${project}` @@ -590,7 +590,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { output = runCLI(`build ${project} --outputHashing none`); expect(output).toContain( - `> nx run ${project}:build:production --outputHashing=none [local cache]` + `> nx run ${project}:build:production --outputHashing none [local cache]` ); expect(output).toContain( `Successfully ran target build for project ${project}` @@ -599,7 +599,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { // check building app1 output = runCLI(`build ${app1} --outputHashing none`); expect(output).toContain( - `> nx run ${app1}:build:production --outputHashing=none` + `> nx run ${app1}:build:production --outputHashing none` ); expect(output).toContain( `Successfully ran target build for project ${app1}` @@ -608,7 +608,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { output = runCLI(`build ${app1} --outputHashing none`); expect(output).toContain( - `> nx run ${app1}:build:production --outputHashing=none [local cache]` + `> nx run ${app1}:build:production --outputHashing none [local cache]` ); expect(output).toContain( `Successfully ran target build for project ${app1}` @@ -638,7 +638,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { // check building an app let output = runCLI(`build ${project} --outputHashing none`); expect(output).toContain( - `> nx run ${project}:build:production --outputHashing=none` + `> nx run ${project}:build:production --outputHashing none` ); expect(output).toContain( `Successfully ran target build for project ${project}` @@ -647,7 +647,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => { output = runCLI(`build ${project} --outputHashing none`); expect(output).toContain( - `> nx run ${project}:build:production --outputHashing=none [local cache]` + `> nx run ${project}:build:production --outputHashing none [local cache]` ); expect(output).toContain( `Successfully ran target build for project ${project}` diff --git a/e2e/nx-run/src/run.test.ts b/e2e/nx-run/src/run.test.ts index 158bb616bc..5cb02ffe0d 100644 --- a/e2e/nx-run/src/run.test.ts +++ b/e2e/nx-run/src/run.test.ts @@ -21,6 +21,37 @@ describe('Nx Running Tests', () => { afterAll(() => cleanupProject()); describe('running targets', () => { + describe('(forwarding params)', () => { + let proj = uniq('proj'); + beforeAll(() => { + runCLI(`generate @nrwl/workspace:lib ${proj}`); + updateProjectConfig(proj, (c) => { + c.targets['echo'] = { + executor: 'nx:run-commands', + options: { + command: 'echo ECHO:', + }, + }; + return c; + }); + }); + + it.each([ + '--watch false', + '--watch=false', + '--arr=a,b,c', + '--arr=a --arr=b --arr=c', + 'a', + '--a.b=1', + '--a.b 1', + '-- a b c --a --a.b=1', + '--ignored -- a b c --a --a.b=1', + ])('should forward %s properly', (args) => { + const output = runCLI(`echo ${proj} ${args}`); + expect(output).toContain(`ECHO: ${args.replace(/^.*-- /, '')}`); + }); + }); + it('should execute long running tasks', async () => { const myapp = uniq('myapp'); runCLI(`generate @nrwl/web:app ${myapp}`); diff --git a/packages/nx/src/command-line/nx-commands.ts b/packages/nx/src/command-line/nx-commands.ts index b8158d9b8d..04c88d457f 100644 --- a/packages/nx/src/command-line/nx-commands.ts +++ b/packages/nx/src/command-line/nx-commands.ts @@ -191,7 +191,9 @@ export const commandsObject = yargs 'Prints information about the projects and targets affected by changes', builder: (yargs) => linkToNxDevAndExamples( - withAffectedOptions(withPrintAffectedOptions(yargs)), + withAffectedOptions( + withTargetOption(withPrintAffectedOptions(yargs), false) + ), 'print-affected' ), handler: async (args) => { @@ -406,9 +408,9 @@ function withPlainOption(yargs: yargs.Argv): yargs.Argv { function withAffectedOptions(yargs: yargs.Argv): yargs.Argv { return yargs .parserConfiguration({ - 'camel-case-expansion': false, - // allow parsing --env.SOME_ARG for cypress cli env args - 'dot-notation': true, + 'strip-dashed': true, + 'unknown-options-as-args': true, + 'populate--': true, }) .option('files', { describe: @@ -473,6 +475,12 @@ function withAffectedOptions(yargs: yargs.Argv): yargs.Argv { 'This is the configuration to use when performing tasks on projects', type: 'string', }) + .option('prod', { + describe: 'Use the production configuration', + type: 'boolean', + default: false, + hidden: true, + }) .option('verbose', { type: 'boolean', describe: @@ -494,15 +502,32 @@ function withAffectedOptions(yargs: yargs.Argv): yargs.Argv { untracked: ['uncommitted', 'files', 'base', 'head', 'all'], uncommitted: ['files', 'untracked', 'base', 'head', 'all'], all: ['files', 'untracked', 'uncommitted', 'base', 'head'], + }) + .check((nxArgs) => { + if ( + !nxArgs.files && + !nxArgs.uncommitted && + !nxArgs.untracked && + !nxArgs.base && + !nxArgs.head && + !nxArgs.all && + nxArgs._ && + nxArgs._.length >= 3 + ) { + throw new Error( + `Nx no longer supports using positional arguments for base and head. Please use --base and --head instead.` + ); + } + return true; }); } function withRunManyOptions(yargs: yargs.Argv): yargs.Argv { return yargs .parserConfiguration({ - 'camel-case-expansion': false, - // allow parsing --env.SOME_ARG for cypress cli env args - 'dot-notation': true, + 'strip-dashed': true, + 'unknown-options-as-args': true, + 'populate--': true, }) .option('projects', { describe: 'Projects to run (comma delimited)', @@ -513,6 +538,12 @@ function withRunManyOptions(yargs: yargs.Argv): yargs.Argv { type: 'boolean', default: true, }) + .option('prod', { + describe: 'Use the production configuration', + type: 'boolean', + default: false, + hidden: true, + }) .options('runner', { describe: 'Override the tasks runner in `nx.json`', type: 'string', @@ -596,16 +627,12 @@ function withDepGraphOptions(yargs: yargs.Argv): yargs.Argv { } function withOverrides(args: any): any { - const split = process.argv.indexOf('--'); - if (split > -1) { - const overrides = process.argv.slice(split + 1); - delete args._; - return { ...args, __overrides__: overrides }; - } else { - args['__positional_overrides__'] = args._.slice(1); - delete args._; - return args; - } + args.__overrides_unparsed__ = (args['--'] ?? args._.slice(1)).map((v) => + v.toString() + ); + delete args['--']; + delete args._; + return args; } function withParallelOption(yargs: yargs.Argv): yargs.Argv { @@ -623,12 +650,12 @@ function withOutputStyleOption(yargs: yargs.Argv): yargs.Argv { }); } -function withTargetOption(yargs: yargs.Argv): yargs.Argv { +function withTargetOption(yargs: yargs.Argv, demandOption = true): yargs.Argv { return yargs.option('target', { describe: 'Task to run for affected projects', type: 'string', requiresArg: true, - demandOption: true, + demandOption, global: false, }); } @@ -687,11 +714,11 @@ function withRunOneOptions(yargs: yargs.Argv) { const executorShouldShowHelp = !( process.argv[2] === 'run' && process.argv[3] === '--help' ); - const res = yargs + const res = withOutputStyleOption(yargs) .parserConfiguration({ - 'camel-case-expansion': false, - // allow parsing --env.SOME_ARG for cypress cli env args - 'dot-notation': true, + 'strip-dashed': true, + 'unknown-options-as-args': true, + 'populate--': true, }) .option('prod', { describe: 'Use the production configuration', diff --git a/packages/nx/src/utils/command-line-utils.spec.ts b/packages/nx/src/utils/command-line-utils.spec.ts index e5ba498587..c68058a47f 100644 --- a/packages/nx/src/utils/command-line-utils.spec.ts +++ b/packages/nx/src/utils/command-line-utils.spec.ts @@ -9,8 +9,7 @@ describe('splitArgs', () => { { base: 'sha1', head: 'sha2', - notNxArg: true, - override: true, + __overrides_unparsed__: ['--notNxArg', '--override'], $0: '', }, 'affected', @@ -27,24 +26,22 @@ describe('splitArgs', () => { it('should put every command start with nx to nxArgs', () => { const nxArgs = splitArgsIntoNxArgsAndOverrides( { - 'nx-key': 'some-value', - nxKey: 'some-value', - _: ['--override'], + nxBail: 'some-value', + __overrides_unparsed__: ['--override'], $0: '', }, 'affected', {} as any, {} as any ).nxArgs; - expect(nxArgs['nxKey']).toEqual('some-value'); + expect(nxArgs['nxBail']).toEqual('some-value'); }); it('should default to having a base of main', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['--override'], + __overrides_unparsed__: ['--notNxArg', '--override'], $0: '', }, 'affected', @@ -61,8 +58,7 @@ describe('splitArgs', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['--override'], + __overrides_unparsed__: ['--notNxArg', '--override'], $0: '', }, 'affected', @@ -79,8 +75,7 @@ describe('splitArgs', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['affecteda', '--override'], + __overrides_unparsed__: ['--notNxArg', 'affecteda', '--override'], $0: '', }, 'affected', @@ -98,8 +93,7 @@ describe('splitArgs', () => { splitArgsIntoNxArgsAndOverrides( { files: [''], - notNxArg: true, - __positional_overrides__: [], + __overrides_unparsed__: ['--notNxArg'], $0: '', }, 'affected', @@ -117,8 +111,7 @@ describe('splitArgs', () => { splitArgsIntoNxArgsAndOverrides( { files: [''], - notNxArg: true, - __positional_overrides__: ['positional'], + __overrides_unparsed__: ['positional', '--notNxArg'], $0: '', }, 'affected', @@ -137,8 +130,7 @@ describe('splitArgs', () => { splitArgsIntoNxArgsAndOverrides( { files: [''], - notNxArg: true, - _: ['explicit'], + __overrides_unparsed__: ['explicit'], $0: '', }, 'affected', @@ -151,19 +143,22 @@ describe('splitArgs', () => { }); }); - it('should throw when base and head are set as positional args', () => { - expect(() => + it('should be able to parse arguments in __overrides__', () => { + expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - __positional_overrides__: ['sha1', 'sha2'], + files: [''], + __overrides__: ['explicit'], $0: '', }, 'affected', {} as any, {} as any - ) - ).toThrow(); + ).overrides + ).toEqual({ + __overrides_unparsed__: ['explicit'], + _: ['explicit'], + }); }); it('should set base and head based on environment variables in affected mode, if they are not provided directly on the command', () => { @@ -175,8 +170,7 @@ describe('splitArgs', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['--override'], + __overrides_unparsed__: ['--notNxArg', 'true', '--override'], $0: '', }, 'affected', @@ -192,8 +186,7 @@ describe('splitArgs', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['--override'], + __overrides_unparsed__: ['--notNxArg', 'true', '--override'], $0: '', head: 'directlyOnCommandSha1', // higher priority than $NX_HEAD }, @@ -210,8 +203,7 @@ describe('splitArgs', () => { expect( splitArgsIntoNxArgsAndOverrides( { - notNxArg: true, - _: ['--override'], + __overrides_unparsed__: ['--notNxArg', 'true', '--override'], $0: '', base: 'directlyOnCommandSha2', // higher priority than $NX_BASE }, @@ -234,8 +226,8 @@ describe('splitArgs', () => { it('should be a number', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: '5', }, 'affected', @@ -249,8 +241,8 @@ describe('splitArgs', () => { it('should default to 3', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: '', }, 'affected', @@ -264,8 +256,8 @@ describe('splitArgs', () => { it('should be 3 when set to true', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: 'true', }, 'affected', @@ -279,8 +271,8 @@ describe('splitArgs', () => { it('should be 1 when set to false', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: 'false', }, 'affected', @@ -294,8 +286,8 @@ describe('splitArgs', () => { it('should use the maxParallel option when given', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: '', maxParallel: 5, }, @@ -310,8 +302,8 @@ describe('splitArgs', () => { it('should use the maxParallel option when given', () => { const parallel = splitArgsIntoNxArgsAndOverrides( { - _: [], $0: '', + __overrides_unparsed__: [], parallel: '', maxParallel: 5, }, diff --git a/packages/nx/src/utils/command-line-utils.ts b/packages/nx/src/utils/command-line-utils.ts index a15ded3c03..ea6f71d587 100644 --- a/packages/nx/src/utils/command-line-utils.ts +++ b/packages/nx/src/utils/command-line-utils.ts @@ -1,104 +1,11 @@ import * as yargsParser from 'yargs-parser'; -import * as yargs from 'yargs'; +import type { Arguments } from 'yargs'; import { TEN_MEGABYTES } from '../project-graph/file-utils'; import { output } from './output'; import { NxJsonConfiguration } from '../config/nx-json'; import { execSync } from 'child_process'; -import { serializeOverridesIntoCommandLine } from './serialize-overrides-into-command-line'; import { ProjectGraph } from '../config/project-graph'; -export function names(name: string): { - name: string; - className: string; - propertyName: string; - constantName: string; - fileName: string; -} { - return { - name, - className: toClassName(name), - propertyName: toPropertyName(name), - constantName: toConstantName(name), - fileName: toFileName(name), - }; -} - -/** - * Hyphenated to UpperCamelCase - */ -function toClassName(str: string): string { - return toCapitalCase(toPropertyName(str)); -} - -/** - * Hyphenated to lowerCamelCase - */ -function toPropertyName(s: string): string { - return s - .replace(/([^a-zA-Z0-9])+(.)?/g, (_, __, chr) => - chr ? chr.toUpperCase() : '' - ) - .replace(/[^a-zA-Z\d]/g, '') - .replace(/^([A-Z])/, (m) => m.toLowerCase()); -} - -/** - * Hyphenated to CONSTANT_CASE - */ -function toConstantName(s: string): string { - return s.replace(/([^a-zA-Z0-9])/g, '_').toUpperCase(); -} - -/** - * Upper camelCase to lowercase, hyphenated - */ -function toFileName(s: string): string { - return s - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .toLowerCase() - .replace(/[ _]/g, '-'); -} - -/** - * Capitalizes the first letter of a string - */ -function toCapitalCase(s: string): string { - return s.charAt(0).toUpperCase() + s.slice(1); -} - -const runOne: string[] = [ - 'target', - 'configuration', - 'prod', - 'runner', - 'parallel', - 'maxParallel', - 'exclude', - 'help', - 'skipNxCache', - 'outputStyle', - 'nxBail', - 'nxIgnoreCycles', - 'verbose', - 'cloud', - 'dte', -]; - -const runMany: string[] = [...runOne, 'projects', 'all']; - -const runAffected: string[] = [ - ...runOne, - 'untracked', - 'uncommitted', - 'all', - 'base', - 'head', - 'files', - 'plain', - 'select', - 'type', -]; - export interface RawNxArgs extends NxArgs { prod?: boolean; } @@ -128,79 +35,40 @@ export interface NxArgs { type?: string; } -const ignoreArgs = ['$0', '_']; - export function splitArgsIntoNxArgsAndOverrides( args: { [k: string]: any }, mode: 'run-one' | 'run-many' | 'affected' | 'print-affected', options = { printWarnings: true }, nxJson: NxJsonConfiguration -): { nxArgs: NxArgs; overrides: yargs.Arguments } { - if (!args.__overrides__ && args._) { +): { nxArgs: NxArgs; overrides: Arguments } { + if (!args.__overrides_unparsed__ && args._) { // required for backwards compatibility - args.__overrides__ = args._; + args.__overrides_unparsed__ = args._; + delete args._; + } + // This handles the way Lerna passes in overrides + if (!args.__overrides_unparsed__ && args.__overrides__) { + // required for backwards compatibility + args.__overrides_unparsed__ = args.__overrides__; delete args._; } - const nxSpecific = - mode === 'run-one' ? runOne : mode === 'run-many' ? runMany : runAffected; - - let explicitOverrides; - if (args.__overrides__) { - explicitOverrides = yargsParser(args.__overrides__ as string[], { - configuration: { - 'camel-case-expansion': false, - 'dot-notation': false, - }, - }); - if (!explicitOverrides._ || explicitOverrides._.length === 0) { - delete explicitOverrides._; - } - } - const overridesFromMainArgs = {} as any; - if ( - args['__positional_overrides__'] && - args['__positional_overrides__'].length > 0 - ) { - overridesFromMainArgs['_'] = args['__positional_overrides__']; - } - const nxArgs: RawNxArgs = {}; - Object.entries(args).forEach(([key, value]) => { - const camelCased = names(key).propertyName; - if (nxSpecific.includes(camelCased) || camelCased.startsWith('nx')) { - if (value !== undefined) nxArgs[camelCased] = value; - } else if ( - !ignoreArgs.includes(key) && - key !== '__positional_overrides__' && - key !== '__overrides__' - ) { - overridesFromMainArgs[key] = value; - } + const nxArgs: RawNxArgs = args; + let overrides = yargsParser(args.__overrides_unparsed__ as string[], { + configuration: { + 'camel-case-expansion': false, + 'dot-notation': true, + }, }); - let overrides; - if (explicitOverrides) { - overrides = explicitOverrides; - overrides['__overrides_unparsed__'] = args.__overrides__; - if ( - Object.keys(overridesFromMainArgs).length > 0 && - options.printWarnings - ) { - const s = Object.keys(overridesFromMainArgs).join(', '); - output.warn({ - title: `Nx didn't recognize the following args: ${s}`, - bodyLines: [ - "When using '--' all executor args have to be defined after '--'.", - ], - }); - } - } else { - overrides = overridesFromMainArgs; - overrides['__overrides_unparsed__'] = serializeOverridesIntoCommandLine( - overridesFromMainArgs - ); + if (!overrides._ || overrides._.length === 0) { + delete overrides._; } + overrides.__overrides_unparsed__ = args.__overrides_unparsed__; + delete (nxArgs as any).$0; + delete (nxArgs as any).__overrides_unparsed__; + if (mode === 'run-many') { if (!nxArgs.projects) { nxArgs.projects = []; @@ -232,21 +100,6 @@ export function splitArgsIntoNxArgsAndOverrides( }); } - if ( - !nxArgs.files && - !nxArgs.uncommitted && - !nxArgs.untracked && - !nxArgs.base && - !nxArgs.head && - !nxArgs.all && - overridesFromMainArgs._ && - overridesFromMainArgs._.length >= 2 - ) { - throw new Error( - `Nx no longer supports using positional arguments for base and head. Please use --base and --head instead.` - ); - } - // Allow setting base and head via environment variables (lower priority then direct command arguments) if (!nxArgs.base && process.env.NX_BASE) { nxArgs.base = process.env.NX_BASE; diff --git a/scripts/documentation/utils.ts b/scripts/documentation/utils.ts index 93873c72da..19750bbab6 100644 --- a/scripts/documentation/utils.ts +++ b/scripts/documentation/utils.ts @@ -183,6 +183,7 @@ export async function parseCommand( type: builderOptionTypes[key], choices: builderOptionsChoices[key], deprecated: builderDeprecatedOptions[key], + hidden: builderOptions.hiddenOptions.includes(key), })) || null, }; } @@ -194,6 +195,7 @@ export function generateOptionsMarkdown(command): string { command.options .sort((a, b) => sortAlphabeticallyFunction(a.name, b.name)) + .filter(({ hidden }) => !hidden) .forEach((option) => { response += `\n### ${ option.deprecated ? `~~${option.name}~~` : option.name