Skip to content

Commit

Permalink
fix(core): nx build --graph file.json should work in subdirectories
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed Oct 31, 2023
1 parent 8ec589d commit 630ce89
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 46 deletions.
38 changes: 1 addition & 37 deletions packages/nx/bin/init-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ export function initLocal(workspace: WorkspaceTypeAndRoot) {
commandsObject.parse(newArgs);
}
} else {
const newArgs = rewritePositionalArguments(process.argv);
commandsObject.parse(newArgs);
commandsObject.parse(process.argv.slice(2));
}
} catch (e) {
console.error(e.message);
Expand Down Expand Up @@ -83,41 +82,6 @@ export function rewriteTargetsAndProjects(args: string[]) {
return newArgs;
}

function rewritePositionalArguments(args: string[]) {
const relevantPositionalArgs = [];
const rest = [];
for (let i = 2; i < args.length; i++) {
if (args[i] === '--') {
rest.push(...args.slice(i + 1));
break;
} else if (!args[i].startsWith('-')) {
relevantPositionalArgs.push(args[i]);
if (relevantPositionalArgs.length === 2) {
rest.push(...args.slice(i + 1));
break;
}
} else {
rest.push(args[i]);
}
}

if (relevantPositionalArgs.length === 1) {
return [
'run',
`${wrapIntoQuotesIfNeeded(relevantPositionalArgs[0])}`,
...rest,
];
}

return [
'run',
`${relevantPositionalArgs[1]}:${wrapIntoQuotesIfNeeded(
relevantPositionalArgs[0]
)}`,
...rest,
];
}

function wrapIntoQuotesIfNeeded(arg: string) {
return arg.indexOf(':') > -1 ? `"${arg}"` : arg;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nx/src/command-line/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,5 @@ function setupDotNxInstallation(version: string) {
}
generateDotNxSetup(version);
// invokes the wrapper, thus invoking the initial installation process
runNxSync('');
runNxSync('--version');
}
14 changes: 12 additions & 2 deletions packages/nx/src/command-line/nx-commands.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { commandsObject } from './nx-commands';

import * as yargsParser from 'yargs-parser';

describe('nx-commands', () => {
it('should parse dot notion cli args', () => {
const actual = commandsObject.parse(
'nx e2e project-e2e --env.NX_API_URL=http://localhost:4200 --abc.123.xyx=false --a.b=3'
const actual = yargsParser(
[
'nx',
'e2e',
'project-e2e',
'--env.NX_API_URL=http://localhost:4200',
'--abc.123.xyx=false',
'--a.b=3',
],
commandsObject.parserConfiguration
);

expect(actual).toEqual(
Expand Down
3 changes: 2 additions & 1 deletion packages/nx/src/command-line/nx-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
import { yargsNewCommand } from './new/command-object';
import { yargsRepairCommand } from './repair/command-object';
import { yargsReportCommand } from './report/command-object';
import { yargsRunCommand } from './run/command-object';
import { yargsNxInfixCommand, yargsRunCommand } from './run/command-object';
import { yargsRunManyCommand } from './run-many/command-object';
import { yargsShowCommand } from './show/command-object';
import { yargsWatchCommand } from './watch/command-object';
Expand Down Expand Up @@ -84,6 +84,7 @@ export const commandsObject = yargs
.command(yargsShowCommand)
.command(yargsViewLogsCommand)
.command(yargsWatchCommand)
.command(yargsNxInfixCommand)
.scriptName('nx')
.help()
// NOTE: we handle --version in nx.ts, this just tells yargs that the option exists
Expand Down
112 changes: 112 additions & 0 deletions packages/nx/src/command-line/run/command-object.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import yargs = require('yargs');
import { withOverrides } from '../yargs-utils/shared-options';
import { yargsNxInfixCommand, yargsRunCommand } from './command-object';

describe('run-one command setup', () => {
it('should parse simple infix and `run` notation equivalently', () => {
const infixOptions = getParsedInfixArgs(['serve', 'myapp']);
const runOptions = getParsedRunArgs(['run', 'myapp:serve']);

compareArgs(infixOptions, runOptions);
});

it.each(['--array=1,2,3', '--array=1 2 3', '--array=1 --array=2 --array=3'])(
'should read arrays (%s)',
(args) => {
const infixArgs = getParsedInfixArgs([
'serve',
'myapp',
...args.split(' '),
]);
const runArgs = getParsedRunArgs([
'run',
'myapp:serve',
...args.split(' '),
]);

compareArgs(infixArgs, runArgs);
}
);

describe('infix notation', () => {
it('should handle flags passed after project', () => {
const parsed = getParsedInfixArgs([
'serve',
'myapp',
'--prod',
'--configuration=production',
]);

expect(parsed.target).toEqual('serve');
expect(parsed.project).toEqual('myapp');
expect(parsed.configuration).toEqual('production');
expect(parsed.prod).toEqual(true);
});

it('should handle flags passed before project', () => {
const parsed = getParsedInfixArgs([
'serve',
'--prod',
'--configuration=production',
'myapp',
]);

expect(parsed.target).toEqual('serve');
expect(parsed.project).toEqual('myapp');
expect(parsed.configuration).toEqual('production');
expect(parsed.prod).toEqual(true);
});

it('should parse with missing project', () => {
const parsed = getParsedArgs(['serve', '--prod'], yargsNxInfixCommand);

expect(parsed.target).toEqual('serve');
expect(parsed.project).toEqual(undefined);
expect(parsed.configuration).toEqual(undefined);
expect(parsed.prod).toEqual(true);
});
});
});

function compareArgs(a: any, b: any) {
delete a['_'];
delete b['_'];
// delete a['__overrides_unparsed__'];
// delete b['__overrides_unparsed__'];
if (a['target'] && a['project']) {
a['project:target:configuration'] = `${a['project']}:${a['target']}`;
delete a['project'];
delete a['target'];
}
if (b['target'] && b['project']) {
b['project:target:configuration'] = `${b['project']}:${b['target']}`;
delete b['project'];
delete b['target'];
}
expect(a).toEqual(b);
}

function getParsedInfixArgs(args: string[]) {
return getParsedArgs(args, yargsNxInfixCommand, 0);
}

function getParsedRunArgs(args: string[]) {
return getParsedArgs(args, yargsRunCommand);
}

function getParsedArgs(
args: string[],
command: yargs.CommandModule,
withOverridesLevel = 1
) {
let parsedArgs: any;
yargs(args)
.command({
...command,
handler: (args) => {
parsedArgs = withOverrides({ ...args }, withOverridesLevel);
},
})
.parse();
return parsedArgs;
}
11 changes: 11 additions & 0 deletions packages/nx/src/command-line/run/command-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ export const yargsRunCommand: CommandModule = {
handler: async (args) =>
(await import('./run-one')).runOne(process.cwd(), withOverrides(args)),
};

/**
* Handles the infix notation for running a target.
*/
export const yargsNxInfixCommand: CommandModule = {
...yargsRunCommand,
command: '$0 <target> [project] [_..]',
describe: 'Run a target for a project',
handler: async (args) =>
(await import('./run-one')).runOne(process.cwd(), withOverrides(args, 0)),
};
5 changes: 3 additions & 2 deletions packages/nx/src/command-line/run/run-one.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export async function runOne(
{ printWarnings: args.graph !== 'stdout' },
nxJson
);

if (nxArgs.verbose) {
process.env.NX_VERBOSE_LOGGING = 'true';
}
Expand Down Expand Up @@ -135,7 +136,7 @@ function parseRunOneOptions(
let target;
let configuration;

if (parsedArgs['project:target:configuration'].indexOf(':') > -1) {
if (parsedArgs['project:target:configuration']?.indexOf(':') > -1) {
// run case
[project, target, configuration] = splitTarget(
parsedArgs['project:target:configuration'],
Expand All @@ -147,7 +148,7 @@ function parseRunOneOptions(
project = defaultProjectName;
}
} else {
target = parsedArgs['project:target:configuration'];
target = parsedArgs.target ?? parsedArgs['project:target:configuration'];
}
if (parsedArgs.project) {
project = parsedArgs.project;
Expand Down
5 changes: 4 additions & 1 deletion packages/nx/src/command-line/yargs-utils/shared-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,10 @@ export function parseCSV(args: string[] | string): string[] {
return [];
}
if (Array.isArray(args)) {
return args;
// If parseCSV is used on `type: 'array'`, the first option may be something like ['a,b,c'].
return args.length === 1 && args[0].includes(',')
? parseCSV(args[0])
: args;
}
const items = args.split(',');
return items.map((i) =>
Expand Down
9 changes: 7 additions & 2 deletions scripts/documentation/generators/generate-cli-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
const importFresh = require('import-fresh');

const sharedCommands = ['generate', 'run'];
const hiddenCommands = ['$0'];

export async function generateCliDocumentation(
commandsOutputDirectory: string
Expand Down Expand Up @@ -94,8 +95,12 @@ description: "${command.description}"
const nxCommands = getCommands(commandsObject);
await Promise.all(
Object.keys(nxCommands)
.filter((name) => !sharedCommands.includes(name))
.filter((name) => nxCommands[name].description)
.filter(
(name) =>
!sharedCommands.includes(name) &&
!hiddenCommands.includes(name) &&
nxCommands[name].description
)
.map((name) => parseCommand(name, nxCommands[name]))
.map(async (command) => generateMarkdown(await command))
.map(async (templateObject) =>
Expand Down

0 comments on commit 630ce89

Please sign in to comment.