chore(core): reorganize nx-commands and cli implementation

This commit is contained in:
AgentEnder 2023-04-21 10:56:30 -04:00 committed by Craigory Coppola
parent 258b6df8b6
commit 6c00f922ae
86 changed files with 1576 additions and 1371 deletions

View File

@ -137,9 +137,9 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry
/packages/nx/src/adapter @AgentEnder @leosvelperez
/packages/nx/src/native @vsavkin @FrozenPandaz @Cammisuli
/packages/nx/src/lock-file @meeroslav @FrozenPandaz
/packages/nx/src/nx-init/angular/** @Coly010 @leosvelperez @FrozenPandaz
/packages/nx/src/command-line/init/implementation/angular/** @Coly010 @leosvelperez @FrozenPandaz
/e2e/nx-init/src/nx-init-angular.test.ts @Coly010 @leosvelperez
/packages/nx/src/nx-init/react/** @jaysoo @xiongemi @mandarini
/packages/nx/src/command-line/init/implementation/react/** @jaysoo @xiongemi @mandarini
/e2e/nx-init/src/nx-init-react.test.ts @jaysoo @xiongemi @mandarini @ndcunningham
/e2e/nx-init/src/files/cra/** @jaysoo @xiongemi @mandarini @ndcunningham
/e2e/nx*/** @FrozenPandaz @AgentEnder @vsavkin

View File

@ -107,7 +107,7 @@ Exclude migrations that should have been applied on previous updates. To be used
Type: `string`
Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@12.0.0,@nx/js@12.0.0")
Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@16.0.0,@nx/js@16.0.0")
### help
@ -135,7 +135,7 @@ Enable prompts to confirm whether to collect optional package updates and migrat
Type: `string`
The target package and version (e.g, @nx/workspace@13.0.0)
The target package and version (e.g, @nx/workspace@16.0.0)
### runMigrations
@ -147,7 +147,7 @@ Execute migrations from a file (when the file isn't provided, execute migrations
Type: `string`
Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@12.0.0,@nx/js@12.0.0")
Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@16.0.0,@nx/js@16.0.0")
### version

View File

@ -107,7 +107,7 @@ Exclude migrations that should have been applied on previous updates. To be used
Type: `string`
Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@12.0.0,@nx/js@12.0.0")
Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@16.0.0,@nx/js@16.0.0")
### help
@ -135,7 +135,7 @@ Enable prompts to confirm whether to collect optional package updates and migrat
Type: `string`
The target package and version (e.g, @nx/workspace@13.0.0)
The target package and version (e.g, @nx/workspace@16.0.0)
### runMigrations
@ -147,7 +147,7 @@ Execute migrations from a file (when the file isn't provided, execute migrations
Type: `string`
Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@12.0.0,@nx/js@12.0.0")
Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@16.0.0,@nx/js@16.0.0")
### version

View File

@ -336,13 +336,15 @@ describe('migrate', () => {
})
);
updateFile('./node_modules/nx/src/command-line/migrate.js', (content) => {
const start = content.indexOf('// testing-fetch-start');
const end = content.indexOf('// testing-fetch-end');
updateFile(
'./node_modules/nx/src/command-line/migrate/migrate.js',
(content) => {
const start = content.indexOf('// testing-fetch-start');
const end = content.indexOf('// testing-fetch-end');
const before = content.substring(0, start);
const after = content.substring(end);
const newFetch = `
const before = content.substring(0, start);
const after = content.substring(end);
const newFetch = `
function createFetcher(logger) {
return function fetch(packageName) {
if (packageName === 'migrate-parent-package') {
@ -374,8 +376,9 @@ describe('migrate', () => {
}
`;
return `${before}${newFetch}${after}`;
});
return `${before}${newFetch}${after}`;
}
);
});
it('should run migrations', () => {

View File

@ -145,7 +145,7 @@ describe('nx wrapper / .nx installation', () => {
* Patches migration fetcher to load in migrations that we are using to test.
*/
updateFile(
'.nx/installation/node_modules/nx/src/command-line/migrate.js',
'.nx/installation/node_modules/nx/src/command-line/migrate/migrate.js',
(content) => {
const start = content.indexOf('// testing-fetch-start');
const end = content.indexOf('// testing-fetch-end');

View File

@ -1,4 +1,4 @@
import type { Target } from 'nx/src/command-line/run';
import type { Target } from 'nx/src/command-line/run/run';
import type { ProjectGraph } from 'nx/src/config/project-graph';
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { splitTarget } from 'nx/src/utils/split-target';

View File

@ -1,4 +1,4 @@
import type { Target } from 'nx/src/command-line/run';
import type { Target } from 'nx/src/command-line/run/run';
import type { ExecutorContext } from 'nx/src/config/misc-interfaces';
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { combineOptionsForExecutor } from 'nx/src/utils/params';

View File

@ -1,5 +1,5 @@
import { appendFileSync, openSync, writeFileSync } from 'fs';
import { run } from '../src/command-line/run';
import { run } from '../src/command-line/run/run';
if (process.env.NX_TERMINAL_OUTPUT_PATH) {
setUpOutputWatching(

View File

@ -24,7 +24,7 @@ import { dirname, extname, join, resolve } from 'path';
import { concat, from, Observable, of, zip } from 'rxjs';
import { catchError, concatMap, map, tap } from 'rxjs/operators';
import { GenerateOptions } from '../command-line/generate';
import type { GenerateOptions } from '../command-line/generate/generate';
import { NxJsonConfiguration } from '../config/nx-json';
import { ProjectConfiguration } from '../config/workspace-json-project-json';
import { FsTree, Tree } from '../generators/tree';

View File

@ -1,23 +1,26 @@
import { calculateFileChanges } from '../project-graph/file-utils';
import { runCommand } from '../tasks-runner/run-command';
import { output } from '../utils/output';
import { generateGraph } from './dep-graph';
import { calculateFileChanges } from '../../project-graph/file-utils';
import { runCommand } from '../../tasks-runner/run-command';
import { output } from '../../utils/output';
import { generateGraph } from '../graph/graph';
import { printAffected } from './print-affected';
import { connectToNxCloudIfExplicitlyAsked } from './connect';
import type { NxArgs } from '../utils/command-line-utils';
import { connectToNxCloudIfExplicitlyAsked } from '../connect/connect-to-nx-cloud';
import type { NxArgs } from '../../utils/command-line-utils';
import {
parseFiles,
splitArgsIntoNxArgsAndOverrides,
} from '../utils/command-line-utils';
} from '../../utils/command-line-utils';
import { performance } from 'perf_hooks';
import { createProjectGraphAsync } from '../project-graph/project-graph';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { projectHasTarget } from '../utils/project-graph-utils';
import { filterAffected } from '../project-graph/affected/affected-project-graph';
import { TargetDependencyConfig } from '../config/workspace-json-project-json';
import { readNxJson } from '../config/configuration';
import { workspaceConfigurationCheck } from '../utils/workspace-configuration-check';
import { findMatchingProjects } from '../utils/find-matching-projects';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import {
ProjectGraph,
ProjectGraphProjectNode,
} from '../../config/project-graph';
import { projectHasTarget } from '../../utils/project-graph-utils';
import { filterAffected } from '../../project-graph/affected/affected-project-graph';
import { TargetDependencyConfig } from '../../config/workspace-json-project-json';
import { readNxJson } from '../../config/configuration';
import { workspaceConfigurationCheck } from '../../utils/workspace-configuration-check';
import { findMatchingProjects } from '../../utils/find-matching-projects';
export async function affected(
command: 'graph' | 'print-affected' | 'affected',

View File

@ -0,0 +1,140 @@
import { CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import {
withAffectedOptions,
withConfiguration,
withDepGraphOptions,
withOutputStyleOption,
withOverrides,
withRunOptions,
withTargetAndConfigurationOption,
} from '../yargs-utils/shared-options';
export const yargsAffectedCommand: CommandModule = {
command: 'affected',
describe: 'Run target for affected projects',
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(
withRunOptions(
withOutputStyleOption(withTargetAndConfigurationOption(yargs))
)
),
'affected'
),
handler: async (args) =>
(await import('./affected')).affected('affected', withOverrides(args)),
};
export const yargsAffectedTestCommand: CommandModule = {
command: 'affected:test',
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(
withRunOptions(withOutputStyleOption(withConfiguration(yargs)))
),
'affected'
),
handler: async (args) =>
(await import('./affected')).affected('affected', {
...withOverrides(args),
target: 'test',
}),
};
export const yargsAffectedBuildCommand: CommandModule = {
command: 'affected:build',
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(
withRunOptions(withOutputStyleOption(withConfiguration(yargs)))
),
'affected'
),
handler: async (args) =>
(await import('./affected')).affected('affected', {
...withOverrides(args),
target: 'build',
}),
};
export const yargsAffectedLintCommand: CommandModule = {
command: 'affected:lint',
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(
withRunOptions(withOutputStyleOption(withConfiguration(yargs)))
),
'affected'
),
handler: async (args) =>
(await import('./affected')).affected('affected', {
...withOverrides(args),
target: 'lint',
}),
};
export const yargsAffectedE2ECommand: CommandModule = {
command: 'affected:e2e',
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(
withRunOptions(withOutputStyleOption(withConfiguration(yargs)))
),
'affected'
),
handler: async (args) =>
(await import('./affected')).affected('affected', {
...withOverrides(args),
target: 'e2e',
}),
};
export const yargsAffectedGraphCommand: CommandModule = {
command: 'affected:graph',
describe: 'Graph dependencies affected by changes',
aliases: ['affected:dep-graph'],
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withDepGraphOptions(yargs)),
'affected:graph'
),
handler: async (args) =>
await (
await import('./affected')
).affected('graph', {
...args,
}),
};
export const yargsPrintAffectedCommand: CommandModule = {
command: 'print-affected',
describe:
'Prints information about the projects and targets affected by changes',
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withTargetAndConfigurationOption(yargs, false)),
'print-affected'
)
.option('select', {
type: 'string',
describe:
'Select the subset of the returned json document (e.g., --select=projects)',
})
.option('type', {
type: 'string',
choices: ['app', 'lib'],
describe:
'Select the type of projects to be returned (e.g., --type=app)',
}),
handler: async (args) => {
await (
await import('./affected')
).affected('print-affected', withOverrides(args));
process.exit(0);
},
};

View File

@ -1,15 +1,17 @@
import { getCommandAsString, getOutputs } from '../tasks-runner/utils';
import { getCommandAsString, getOutputs } from '../../tasks-runner/utils';
import * as yargs from 'yargs';
import type { NxArgs } from '../utils/command-line-utils';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { Task } from '../config/task-graph';
import { ProcessTasks } from '../tasks-runner/create-task-graph';
import { NxJsonConfiguration } from '../config/nx-json';
import { Workspaces } from '../config/workspaces';
import { Hasher } from '../hasher/hasher';
import { hashTask } from '../hasher/hash-task';
import { workspaceRoot } from '../utils/workspace-root';
import { getPackageManagerCommand } from '../utils/package-manager';
import type { NxArgs } from '../../utils/command-line-utils';
import {
ProjectGraph,
ProjectGraphProjectNode,
} from '../../config/project-graph';
import { ProcessTasks } from '../../tasks-runner/create-task-graph';
import { NxJsonConfiguration } from '../../config/nx-json';
import { Workspaces } from '../../config/workspaces';
import { Hasher } from '../../hasher/hasher';
import { hashTask } from '../../hasher/hash-task';
import { workspaceRoot } from '../../utils/workspace-root';
import { getPackageManagerCommand } from '../../utils/package-manager';
export async function printAffected(
affectedProjects: ProjectGraphProjectNode[],

View File

@ -0,0 +1,21 @@
import { CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
export const yargsConnectCommand: CommandModule = {
command: 'connect',
aliases: ['connect-to-nx-cloud'],
describe: `Connect workspace to Nx Cloud`,
builder: (yargs) => linkToNxDevAndExamples(yargs, 'connect-to-nx-cloud'),
handler: async () => {
await (await import('./connect-to-nx-cloud')).connectToNxCloudCommand();
process.exit(0);
},
};
export const yargsViewLogsCommand: CommandModule = {
command: 'view-logs',
describe:
'Enables you to view and interact with the logs via the advanced analytic UI from Nx Cloud to help you debug your issue. To do this, Nx needs to connect your workspace to Nx Cloud and upload the most recent run details. Only the metrics are uploaded, not the artefacts.',
handler: async () =>
process.exit(await (await import('./view-logs')).viewLogs()),
};

View File

@ -1,16 +1,13 @@
import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager';
import { output } from '../../utils/output';
import { getPackageManagerCommand } from '../../utils/package-manager';
import { execSync } from 'child_process';
import { readNxJson } from '../config/configuration';
import { readNxJson } from '../../config/configuration';
import {
getNxCloudToken,
getNxCloudUrl,
isNxCloudUsed,
} from '../utils/nx-cloud-utils';
import { existsSync } from 'fs';
import { join } from 'path';
import { workspaceRoot } from '../utils/workspace-root';
import { runNxSync } from '../utils/child-process';
} from '../../utils/nx-cloud-utils';
import { runNxSync } from '../../utils/child-process';
export async function connectToNxCloudIfExplicitlyAsked(opts: {
[k: string]: any;

View File

@ -1,8 +1,8 @@
import { getPackageManagerCommand } from '../utils/package-manager';
import { getPackageManagerCommand } from '../../utils/package-manager';
import { execSync } from 'child_process';
import { isNxCloudUsed } from '../utils/nx-cloud-utils';
import { output } from '../utils/output';
import { runNxSync } from '../utils/child-process';
import { isNxCloudUsed } from '../../utils/nx-cloud-utils';
import { output } from '../../utils/output';
import { runNxSync } from '../../utils/child-process';
export async function viewLogs(): Promise<number> {
const pmc = getPackageManagerCommand();

View File

@ -0,0 +1,23 @@
import { CommandModule, Argv } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
export const yargsDaemonCommand: CommandModule = {
command: 'daemon',
describe:
'Prints information about the Nx Daemon process or starts a daemon process',
builder: (yargs) =>
linkToNxDevAndExamples(withDaemonOptions(yargs), 'daemon'),
handler: async (args) => (await import('./daemon')).daemonHandler(args),
};
function withDaemonOptions(yargs: Argv): Argv {
return yargs
.option('start', {
type: 'boolean',
default: false,
})
.option('stop', {
type: 'boolean',
default: false,
});
}

View File

@ -1,11 +1,11 @@
import type { Arguments } from 'yargs';
import { DAEMON_OUTPUT_LOG_FILE } from '../daemon/tmp-dir';
import { output } from '../utils/output';
import { generateDaemonHelpOutput } from '../daemon/client/generate-help-output';
import { DAEMON_OUTPUT_LOG_FILE } from '../../daemon/tmp-dir';
import { output } from '../../utils/output';
import { generateDaemonHelpOutput } from '../../daemon/client/generate-help-output';
export async function daemonHandler(args: Arguments) {
if (args.start) {
const { daemonClient } = await import('../daemon/client/client');
const { daemonClient } = await import('../../daemon/client/client');
const pid = await daemonClient.startInBackground();
output.log({
title: `Daemon Server - Started in a background process...`,
@ -16,7 +16,7 @@ export async function daemonHandler(args: Arguments) {
],
});
} else if (args.stop) {
const { daemonClient } = await import('../daemon/client/client');
const { daemonClient } = await import('../../daemon/client/client');
await daemonClient.stop();
output.log({ title: 'Daemon Server - Stopped' });
} else {

View File

@ -0,0 +1,19 @@
import { CommandModule } from 'yargs';
import {
withRunOneOptions,
withOverrides,
} from '../yargs-utils/shared-options';
export const yargsExecCommand: CommandModule = {
command: 'exec',
describe: 'Executes any command as if it was a target on the project',
builder: (yargs) => withRunOneOptions(yargs),
handler: async (args) => {
try {
await (await import('./exec')).nxExecCommand(withOverrides(args));
process.exit(0);
} catch (e) {
process.exit(1);
}
},
};

View File

@ -3,19 +3,22 @@ import { join } from 'path';
import { exit } from 'process';
import * as yargs from 'yargs-parser';
import { readNxJson } from '../config/configuration';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { readNxJson } from '../../config/configuration';
import {
ProjectGraph,
ProjectGraphProjectNode,
} from '../../config/project-graph';
import {
createProjectGraphAsync,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
import { splitArgsIntoNxArgsAndOverrides } from '../utils/command-line-utils';
import { readJsonFile } from '../utils/fileutils';
import { output } from '../utils/output';
import { PackageJson } from '../utils/package-json';
import { getPackageManagerCommand } from '../utils/package-manager';
import { workspaceRoot } from '../utils/workspace-root';
import { calculateDefaultProjectName } from './run-one';
} from '../../project-graph/project-graph';
import { splitArgsIntoNxArgsAndOverrides } from '../../utils/command-line-utils';
import { readJsonFile } from '../../utils/fileutils';
import { output } from '../../utils/output';
import { PackageJson } from '../../utils/package-json';
import { getPackageManagerCommand } from '../../utils/package-manager';
import { workspaceRoot } from '../../utils/workspace-root';
import { calculateDefaultProjectName } from '../run/run-one';
export async function nxExecCommand(
args: Record<string, string[]>

View File

@ -0,0 +1,45 @@
import { CommandModule, Argv } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import { parseCSV, withAffectedOptions } from '../yargs-utils/shared-options';
export const yargsFormatCheckCommand: CommandModule = {
command: 'format:check',
describe: 'Check for un-formatted files',
builder: (yargs) =>
linkToNxDevAndExamples(withFormatOptions(yargs), 'format:check'),
handler: async (args) => {
await (await import('./format')).format('check', args);
process.exit(0);
},
};
export const yargsFormatWriteCommand: CommandModule = {
command: 'format:write',
describe: 'Overwrite un-formatted files',
aliases: ['format'],
builder: (yargs) =>
linkToNxDevAndExamples(withFormatOptions(yargs), 'format:write'),
handler: async (args) => {
await (await import('./format')).format('write', args);
process.exit(0);
},
};
function withFormatOptions(yargs: Argv): Argv {
return withAffectedOptions(yargs)
.parserConfiguration({
'camel-case-expansion': true,
})
.option('libs-and-apps', {
describe: 'Format only libraries and applications files.',
type: 'boolean',
})
.option('projects', {
describe: 'Projects to format (comma/space delimited)',
type: 'string',
coerce: parseCSV,
})
.conflicts({
all: 'projects',
});
}

View File

@ -5,22 +5,22 @@ import {
NxArgs,
parseFiles,
splitArgsIntoNxArgsAndOverrides,
} from '../utils/command-line-utils';
import { fileExists, readJsonFile, writeJsonFile } from '../utils/fileutils';
import { calculateFileChanges, FileData } from '../project-graph/file-utils';
} from '../../utils/command-line-utils';
import { fileExists, readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { calculateFileChanges, FileData } from '../../project-graph/file-utils';
import * as yargs from 'yargs';
import * as prettier from 'prettier';
import { sortObjectByKeys } from '../utils/object-sort';
import { sortObjectByKeys } from '../../utils/object-sort';
import {
getRootTsConfigFileName,
getRootTsConfigPath,
} from '../plugins/js/utils/typescript';
import { createProjectGraphAsync } from '../project-graph/project-graph';
import { filterAffected } from '../project-graph/affected/affected-project-graph';
import { readNxJson } from '../config/configuration';
import { ProjectGraph } from '../config/project-graph';
import { chunkify } from '../utils/chunkify';
} from '../../plugins/js/utils/typescript';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { filterAffected } from '../../project-graph/affected/affected-project-graph';
import { readNxJson } from '../../config/configuration';
import { ProjectGraph } from '../../config/project-graph';
import { chunkify } from '../../utils/chunkify';
const PRETTIER_PATH = require.resolve('prettier/bin-prettier');

View File

@ -0,0 +1,92 @@
import { CommandModule, Argv } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
export const yargsGenerateCommand: CommandModule = {
command: 'generate <generator> [_..]',
describe:
'Generate or update source code (e.g., nx generate @nx/js:lib mylib).',
aliases: ['g'],
builder: (yargs) => withGenerateOptions(yargs),
handler: async (args) => {
// Remove the command from the args
args._ = args._.slice(1);
process.exit(
await (await import('./generate')).generate(process.cwd(), args)
);
},
};
/**
* @deprecated(v17): Remove `workspace-generator in v17. Use local plugins.
*/
export const yargsWorkspaceGeneratorCommand: CommandModule = {
command: 'workspace-generator [generator]',
describe: 'Runs a workspace generator from the tools/generators directory',
deprecated:
'Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators',
aliases: ['workspace-schematic [schematic]'],
builder: async (yargs) =>
linkToNxDevAndExamples(withGenerateOptions(yargs), 'workspace-generator'),
handler: async (args) => {
await (await import('./generate')).workspaceGenerators(args);
process.exit(0);
},
};
function withGenerateOptions(yargs: Argv) {
const generatorWillShowHelp =
process.argv[3] && !process.argv[3].startsWith('-');
const res = yargs
.positional('generator', {
describe: 'Name of the generator (e.g., @nx/js:library, library)',
type: 'string',
required: true,
})
.option('dryRun', {
describe: 'Preview the changes without updating files',
alias: 'd',
type: 'boolean',
default: false,
})
.option('interactive', {
describe: 'When false disables interactive input prompts for options',
type: 'boolean',
default: true,
})
.option('verbose', {
describe:
'Prints additional information about the commands (e.g., stack traces)',
type: 'boolean',
})
.option('quiet', {
describe: 'Hides logs from tree operations (e.g. `CREATE package.json`)',
type: 'boolean',
conflicts: ['verbose'],
})
.middleware((args) => {
if (process.env.NX_INTERACTIVE === 'false') {
args.interactive = false;
} else {
process.env.NX_INTERACTIVE = `${args.interactive}`;
}
if (process.env.NX_DRY_RUN === 'true') {
args.dryRun = true;
} else {
process.env.NX_DRY_RUN = `${args.dryRun}`;
}
if (process.env.NX_GENERATE_QUIET === 'true') {
args.quiet = true;
} else {
process.env.NX_GENERATE_QUIET = `${args.quiet}`;
}
});
if (generatorWillShowHelp) {
return res.help(false);
} else {
return res.epilog(
`Run "nx g collection:generator --help" to see information about the generator's schema.`
);
}
}

View File

@ -1,26 +1,28 @@
import * as chalk from 'chalk';
import { prompt } from 'enquirer';
import { readNxJson } from '../config/configuration';
import { ProjectsConfigurations } from '../config/workspace-json-project-json';
import { Workspaces } from '../config/workspaces';
import { FileChange, flushChanges, FsTree } from '../generators/tree';
import { readNxJson } from '../../config/configuration';
import { ProjectsConfigurations } from '../../config/workspace-json-project-json';
import { Workspaces } from '../../config/workspaces';
import { FileChange, flushChanges, FsTree } from '../../generators/tree';
import {
createProjectGraphAsync,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
import { logger, NX_PREFIX } from '../utils/logger';
} from '../../project-graph/project-graph';
import { logger, NX_PREFIX } from '../../utils/logger';
import {
combineOptionsForGenerator,
handleErrors,
Options,
Schema,
} from '../utils/params';
import { getLocalWorkspacePlugins } from '../utils/plugins/local-plugins';
import { printHelp } from '../utils/print-help';
import { workspaceRoot } from '../utils/workspace-root';
import { NxJsonConfiguration } from '../config/nx-json';
import { findInstalledPlugins } from '../utils/plugins/installed-plugins';
} from '../../utils/params';
import { getLocalWorkspacePlugins } from '../../utils/plugins/local-plugins';
import { printHelp } from '../../utils/print-help';
import { workspaceRoot } from '../../utils/workspace-root';
import { NxJsonConfiguration } from '../../config/nx-json';
import { findInstalledPlugins } from '../../utils/plugins/installed-plugins';
import type { Arguments } from 'yargs';
import { output } from '../../utils/output';
export interface GenerateOptions {
collectionName: string;
@ -389,7 +391,7 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
}
} else {
require('../adapter/compat');
return (await import('../adapter/ngcli-adapter')).generate(
return (await import('../../adapter/ngcli-adapter')).generate(
workspaceRoot,
{
...opts,
@ -400,3 +402,33 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
}
});
}
/**
* Wraps `workspace-generator` to invoke `generate`.
*
* @deprecated(v17): Remove `workspace-generator in v17. Use local plugins.
*/
export async function workspaceGenerators(args: Arguments) {
const generator = process.argv.slice(3);
output.warn({
title: `Workspace Generators are no longer supported`,
bodyLines: [
'Instead, Nx now supports executing generators or executors from ',
'local plugins. To run a generator from a local plugin, ',
'use `nx generate` like you would with any other generator.',
'',
'For more information, see: https://nx.dev/deprecated/workspace-generators',
],
});
const nxJson: NxJsonConfiguration = readNxJson();
const collection = nxJson.npmScope
? `@${nxJson.npmScope}/workspace-plugin`
: 'workspace-plugin';
args._ = args._.slice(1);
args.generator = `${collection}:${generator}`;
return generate(process.cwd(), args);
}

View File

@ -0,0 +1,13 @@
import { CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import { withDepGraphOptions } from '../yargs-utils/shared-options';
export const yargsDepGraphCommand: CommandModule = {
command: 'graph',
describe: 'Graph dependencies within workspace',
aliases: ['dep-graph'],
builder: (yargs) =>
linkToNxDevAndExamples(withDepGraphOptions(yargs), 'dep-graph'),
handler: async (args) =>
await (await import('./graph')).generateGraph(args as any, []),
};

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../utils/workspace-root';
import { workspaceRoot } from '../../utils/workspace-root';
import { createHash } from 'crypto';
import { existsSync, readFileSync, statSync, writeFileSync } from 'fs';
import { copySync, ensureDirSync } from 'fs-extra';
@ -7,21 +7,21 @@ import * as open from 'open';
import { basename, dirname, extname, isAbsolute, join, parse } from 'path';
import { performance } from 'perf_hooks';
import { URL } from 'url';
import { readNxJson, workspaceLayout } from '../config/configuration';
import { defaultFileHasher } from '../hasher/file-hasher';
import { output } from '../utils/output';
import { writeJsonFile } from '../utils/fileutils';
import { readNxJson, workspaceLayout } from '../../config/configuration';
import { defaultFileHasher } from '../../hasher/file-hasher';
import { output } from '../../utils/output';
import { writeJsonFile } from '../../utils/fileutils';
import {
ProjectGraph,
ProjectGraphDependency,
ProjectGraphProjectNode,
} from '../config/project-graph';
import { pruneExternalNodes } from '../project-graph/operators';
import { createProjectGraphAsync } from '../project-graph/project-graph';
import { createTaskGraph } from '../tasks-runner/create-task-graph';
import { TargetDefaults, TargetDependencies } from '../config/nx-json';
import { TaskGraph } from '../config/task-graph';
import { daemonClient } from '../daemon/client/client';
} from '../../config/project-graph';
import { pruneExternalNodes } from '../../project-graph/operators';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { createTaskGraph } from '../../tasks-runner/create-task-graph';
import { TargetDefaults, TargetDependencies } from '../../config/nx-json';
import { TaskGraph } from '../../config/task-graph';
import { daemonClient } from '../../daemon/client/client';
import { Server } from 'net';
export interface ProjectGraphClientResponse {
@ -238,7 +238,10 @@ export async function generateGraph(
}
}
let html = readFileSync(join(__dirname, '../core/graph/index.html'), 'utf-8');
let html = readFileSync(
join(__dirname, '../../core/graph/index.html'),
'utf-8'
);
graph = filterGraph(graph, args.focus || null, args.exclude || []);
@ -253,7 +256,7 @@ export async function generateGraph(
if (ext === '.html') {
const assetsFolder = join(fileFolderPath, 'static');
const assets: string[] = [];
copySync(join(__dirname, '../core/graph'), assetsFolder, {
copySync(join(__dirname, '../../core/graph'), assetsFolder, {
filter: (_src, dest) => {
const isntHtml = !/index\.html/.test(dest);
if (isntHtml && dest.includes('.')) {
@ -420,7 +423,7 @@ async function startServer(
return;
}
let pathname = join(__dirname, '../core/graph/', sanitizePath);
let pathname = join(__dirname, '../../core/graph/', sanitizePath);
// if the file is not found or is a directory, return index.html
if (!existsSync(pathname) || statSync(pathname).isDirectory()) {

View File

@ -0,0 +1,56 @@
import { CommandModule, Argv } from 'yargs';
import { parseCSV } from '../yargs-utils/shared-options';
export const yargsInitCommand: CommandModule = {
command: 'init',
describe:
'Adds Nx to any type of workspace. It installs nx, creates an nx.json configuration file and optionally sets up distributed caching. For more info, check https://nx.dev/recipes/adopting-nx.',
builder: (yargs) => withInitOptions(yargs),
handler: async (args: any) => {
await (await import('./init')).initHandler(args);
process.exit(0);
},
};
function withInitOptions(yargs: Argv) {
return yargs
.options('nxCloud', {
type: 'boolean',
description: 'Set up distributed caching with Nx Cloud.',
})
.option('interactive', {
describe: 'When false disables interactive input prompts for options.',
type: 'boolean',
default: true,
})
.option('integrated', {
type: 'boolean',
description:
'Migrate to an Nx integrated layout workspace. Only for Angular CLI workspaces and CRA projects.',
default: false,
})
.option('addE2e', {
describe:
'Set up Cypress E2E tests in integrated workspaces. Only for CRA projects.',
type: 'boolean',
default: false,
})
.option('force', {
describe:
'Force the migration to continue and ignore custom webpack setup or uncommitted changes. Only for CRA projects.',
type: 'boolean',
default: false,
})
.options('vite', {
type: 'boolean',
description: 'Use Vite as the bundler. Only for CRA projects.',
default: true,
})
.options('cacheable', {
type: 'string',
description:
'Comma-separated list of cacheable operations. Only used for internal testing.',
coerce: parseCSV,
hidden: true,
});
}

View File

@ -2,10 +2,10 @@ import { prompt } from 'enquirer';
import { readdirSync, readFileSync, statSync } from 'fs';
import ignore from 'ignore';
import { join, relative } from 'path';
import { InitArgs } from '../command-line/init';
import { readJsonFile } from '../utils/fileutils';
import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager';
import { InitArgs } from '../init';
import { readJsonFile } from '../../../utils/fileutils';
import { output } from '../../../utils/output';
import { getPackageManagerCommand } from '../../../utils/package-manager';
import {
addDepsToPackageJson,
askAboutNxCloud,

View File

@ -1,13 +1,20 @@
import * as enquirer from 'enquirer';
import { unlinkSync, writeFileSync } from 'fs-extra';
import { join } from 'path';
import { InitArgs } from '../command-line/init';
import { NrwlJsPluginConfig, NxJsonConfiguration } from '../config/nx-json';
import { ProjectConfiguration } from '../config/workspace-json-project-json';
import { fileExists, readJsonFile, writeJsonFile } from '../utils/fileutils';
import { output } from '../utils/output';
import { PackageJson } from '../utils/package-json';
import { getPackageManagerCommand } from '../utils/package-manager';
import { InitArgs } from '../init';
import {
NrwlJsPluginConfig,
NxJsonConfiguration,
} from '../../../config/nx-json';
import { ProjectConfiguration } from '../../../config/workspace-json-project-json';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../utils/fileutils';
import { output } from '../../../utils/output';
import { PackageJson } from '../../../utils/package-json';
import { getPackageManagerCommand } from '../../../utils/package-manager';
import {
addDepsToPackageJson,
askAboutNxCloud,
@ -17,6 +24,7 @@ import {
printFinalMessage,
runInstall,
} from './utils';
import { nxVersion } from '../../../utils/versions';
type Options = Pick<InitArgs, 'nxCloud' | 'interactive' | 'cacheable'>;
type NestCLIConfiguration = any;
@ -141,8 +149,8 @@ export async function addNxToNest(options: Options, packageJson: PackageJson) {
function addNestPluginToPackageJson(repoRoot: string) {
const path = join(repoRoot, `package.json`);
const json: PackageJson = readJsonFile(path);
json.devDependencies['@nx/nest'] = require('../../package.json').version;
json.devDependencies['@nx/jest'] = require('../../package.json').version;
json.devDependencies['@nx/nest'] = nxVersion;
json.devDependencies['@nx/jest'] = nxVersion;
writeJsonFile(path, json);
}

View File

@ -1,8 +1,8 @@
import * as enquirer from 'enquirer';
import { InitArgs } from '../command-line/init';
import { readJsonFile } from '../utils/fileutils';
import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager';
import { InitArgs } from '../init';
import { readJsonFile } from '../../../utils/fileutils';
import { output } from '../../../utils/output';
import { getPackageManagerCommand } from '../../../utils/package-manager';
import {
addDepsToPackageJson,
askAboutNxCloud,

View File

@ -1,9 +1,10 @@
import { prompt } from 'enquirer';
import { join } from 'path';
import { readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { sortObjectByKeys } from '../../utils/object-sort';
import { output } from '../../utils/output';
import type { PackageJson } from '../../utils/package-json';
import { readJsonFile, writeJsonFile } from '../../../../utils/fileutils';
import { nxVersion } from '../../../../utils/versions';
import { sortObjectByKeys } from '../../../../utils/object-sort';
import { output } from '../../../../utils/output';
import type { PackageJson } from '../../../../utils/package-json';
import {
addDepsToPackageJson,
askAboutNxCloud,
@ -115,7 +116,6 @@ function installDependencies(useNxCloud: boolean): void {
function addPluginDependencies(): void {
const packageJsonPath = join(repoRoot, 'package.json');
const packageJson = readJsonFile<PackageJson>(packageJsonPath);
const nxVersion = require('../../../package.json').version;
packageJson.devDependencies ??= {};
packageJson.devDependencies['@nx/angular'] = nxVersion;

View File

@ -1,5 +1,5 @@
import { execSync } from 'child_process';
import { getPackageManagerCommand } from '../../utils/package-manager';
import { getPackageManagerCommand } from '../../../../utils/package-manager';
export function setupIntegratedWorkspace(): void {
const pmc = getPackageManagerCommand();

View File

@ -1,16 +1,16 @@
import { execSync } from 'child_process';
import { join } from 'path';
import { gte, major } from 'semver';
import { readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { sortObjectByKeys } from '../../utils/object-sort';
import { output } from '../../utils/output';
import { readModulePackageJson } from '../../utils/package-json';
import { readJsonFile, writeJsonFile } from '../../../../utils/fileutils';
import { sortObjectByKeys } from '../../../../utils/object-sort';
import { output } from '../../../../utils/output';
import { readModulePackageJson } from '../../../../utils/package-json';
import {
getPackageManagerCommand,
PackageManagerCommands,
resolvePackageVersionUsingInstallation,
resolvePackageVersionUsingRegistry,
} from '../../utils/package-manager';
} from '../../../../utils/package-manager';
import { askAboutNxCloud, initCloud, printFinalMessage } from '../utils';
import type { Options } from './types';

View File

@ -1,11 +1,15 @@
import { unlinkSync } from 'fs';
import { dirname, join, relative, resolve } from 'path';
import { toNewFormat } from '../../adapter/angular-json';
import type { NxJsonConfiguration } from '../../config/nx-json';
import type { ProjectConfiguration } from '../../config/workspace-json-project-json';
import { fileExists, readJsonFile, writeJsonFile } from '../../utils/fileutils';
import type { PackageJson } from '../../utils/package-json';
import { normalizePath } from '../../utils/path';
import { toNewFormat } from '../../../../adapter/angular-json';
import type { NxJsonConfiguration } from '../../../../config/nx-json';
import type { ProjectConfiguration } from '../../../../config/workspace-json-project-json';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../../utils/fileutils';
import type { PackageJson } from '../../../../utils/package-json';
import { normalizePath } from '../../../../utils/path';
import { addVsCodeRecommendedExtensions, createNxJsonFile } from '../utils';
import type {
AngularJsonConfig,

View File

@ -1,5 +1,5 @@
import { InitArgs } from '../../command-line/init';
import type { TargetConfiguration } from '../../config/workspace-json-project-json';
import { InitArgs } from '../../init';
import type { TargetConfiguration } from '../../../../config/workspace-json-project-json';
export type Options = Pick<
InitArgs,

View File

@ -2,14 +2,14 @@ import { execSync } from 'child_process';
import { readFileSync, constants as FsConstants } from 'fs';
import * as path from 'path';
import { valid } from 'semver';
import { NxJsonConfiguration } from '../../config/nx-json';
import { NxJsonConfiguration } from '../../../../config/nx-json';
import {
flushChanges,
FsTree,
printChanges,
Tree,
} from '../../generators/tree';
import { writeJson } from '../../generators/utils/json';
} from '../../../../generators/tree';
import { writeJson } from '../../../../generators/utils/json';
export const nxWrapperPath = (p: typeof import('path') = path) =>
p.join('.nx', 'nxw.js');

View File

@ -4,14 +4,15 @@
//
//# The contents of this file are executed before packages are installed.
//# As such, we should not import anything from nx, other @nrwl packages,
//# or any other npm packages. Only import node builtins.
//# or any other npm packages. Only import node builtins. Type Imports are
//# fine, since they are removed by the typescript compiler.
const fs: typeof import('fs') = require('fs');
const path: typeof import('path') = require('path');
const cp: typeof import('child_process') = require('child_process');
import type { NxJsonConfiguration } from '../../config/nx-json';
import type { PackageJson } from '../../utils/package-json';
import type { NxJsonConfiguration } from '../../../../config/nx-json';
import type { PackageJson } from '../../../../utils/package-json';
const installationPath = path.join(__dirname, 'installation', 'package.json');

View File

@ -1,4 +1,4 @@
import { readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { readJsonFile, writeJsonFile } from '../../../../utils/fileutils';
export function addCracoCommandsToPackageScripts(
appName: string,

View File

@ -1,4 +1,4 @@
import { readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { readJsonFile, writeJsonFile } from '../../../../utils/fileutils';
export function addViteCommandsToPackageScripts(
appName: string,

View File

@ -1,4 +1,4 @@
import { readJsonFile } from '../../utils/fileutils';
import { readJsonFile } from '../../../../utils/fileutils';
export function checkForCustomWebpackSetup() {
const packageJson = readJsonFile('package.json');

View File

@ -1,5 +1,5 @@
import { removeSync } from 'fs-extra';
import { readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { readJsonFile, writeJsonFile } from '../../../../utils/fileutils';
export function cleanUpFiles(appName: string, isStandalone: boolean) {
// Delete targets from project since we delegate to npm scripts.

View File

@ -1,15 +1,19 @@
import { execSync } from 'child_process';
import { copySync, moveSync, readdirSync, removeSync } from 'fs-extra';
import { join } from 'path';
import { InitArgs } from '../../command-line/init';
import { fileExists, readJsonFile, writeJsonFile } from '../../utils/fileutils';
import { output } from '../../utils/output';
import { InitArgs } from '../../init';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../../utils/fileutils';
import { output } from '../../../../utils/output';
import {
detectPackageManager,
getPackageManagerCommand,
PackageManagerCommands,
} from '../../utils/package-manager';
import { PackageJson } from '../../utils/package-json';
} from '../../../../utils/package-manager';
import { PackageJson } from '../../../../utils/package-json';
import { askAboutNxCloud, printFinalMessage } from '../utils';
import { checkForCustomWebpackSetup } from './check-for-custom-webpack-setup';
import { checkForUncommittedChanges } from './check-for-uncommitted-changes';

View File

@ -1,4 +1,4 @@
import { fileExists, readJsonFile } from '../../utils/fileutils';
import { fileExists, readJsonFile } from '../../../../utils/fileutils';
export function readNameFromPackageJson(): string {
let appName = 'webapp';

View File

@ -1,5 +1,9 @@
import { writeFileSync } from 'fs';
import { fileExists, readJsonFile, writeJsonFile } from '../../utils/fileutils';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../../utils/fileutils';
export function setupE2eProject(appName: string) {
const json = readJsonFile(`apps/${appName}-e2e/project.json`);

View File

@ -1,5 +1,9 @@
import { join } from 'path';
import { fileExists, readJsonFile, writeJsonFile } from '../../utils/fileutils';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../../utils/fileutils';
const defaultTsConfig = (relativePathToRoot: string) => ({
extends: relativePathToRoot

View File

@ -1,15 +1,20 @@
import { execSync } from 'child_process';
import * as enquirer from 'enquirer';
import { join } from 'path';
import { runNxSync } from '../utils/child-process';
import { fileExists, readJsonFile, writeJsonFile } from '../utils/fileutils';
import { output } from '../utils/output';
import { PackageJson } from '../utils/package-json';
import { nxVersion } from '../../../utils/versions';
import { runNxSync } from '../../../utils/child-process';
import {
fileExists,
readJsonFile,
writeJsonFile,
} from '../../../utils/fileutils';
import { output } from '../../../utils/output';
import { PackageJson } from '../../../utils/package-json';
import {
getPackageManagerCommand,
PackageManagerCommands,
} from '../utils/package-manager';
import { joinPathFragments } from '../utils/path';
} from '../../../utils/package-manager';
import { joinPathFragments } from '../../../utils/path';
export async function askAboutNxCloud(): Promise<boolean> {
return await enquirer
@ -109,7 +114,7 @@ export function addDepsToPackageJson(repoRoot: string, useCloud: boolean) {
const path = joinPathFragments(repoRoot, `package.json`);
const json = readJsonFile(path);
if (!json.devDependencies) json.devDependencies = {};
json.devDependencies['nx'] = require('../../package.json').version;
json.devDependencies['nx'] = nxVersion;
if (useCloud) {
json.devDependencies['nx-cloud'] = 'latest';
}

View File

@ -3,15 +3,16 @@ import { prompt } from 'enquirer';
import { existsSync } from 'fs';
import { prerelease } from 'semver';
import * as parser from 'yargs-parser';
import { addNxToMonorepo } from '../nx-init/add-nx-to-monorepo';
import { addNxToNest } from '../nx-init/add-nx-to-nest';
import { addNxToNpmRepo } from '../nx-init/add-nx-to-npm-repo';
import { addNxToAngularCliRepo } from '../nx-init/angular';
import { generateDotNxSetup } from '../nx-init/dot-nx/add-nx-scripts';
import { addNxToCraRepo } from '../nx-init/react';
import { runNxSync } from '../utils/child-process';
import { directoryExists, readJsonFile } from '../utils/fileutils';
import { PackageJson } from '../utils/package-json';
import { addNxToMonorepo } from './implementation/add-nx-to-monorepo';
import { addNxToNest } from './implementation/add-nx-to-nest';
import { addNxToNpmRepo } from './implementation/add-nx-to-npm-repo';
import { addNxToAngularCliRepo } from './implementation/angular';
import { generateDotNxSetup } from './implementation/dot-nx/add-nx-scripts';
import { addNxToCraRepo } from './implementation/react';
import { runNxSync } from '../../utils/child-process';
import { directoryExists, readJsonFile } from '../../utils/fileutils';
import { PackageJson } from '../../utils/package-json';
import { nxVersion } from '../../utils/versions';
export interface InitArgs {
addE2e: boolean;
@ -36,8 +37,7 @@ export async function initHandler(options: InitArgs) {
}) as any as { useDotNxInstallation: boolean };
const version =
process.env.NX_VERSION ??
(prerelease(require('../../package.json').version) ? 'next' : 'latest');
process.env.NX_VERSION ?? (prerelease(nxVersion) ? 'next' : 'latest');
if (process.env.NX_VERSION) {
console.log(`Using version ${process.env.NX_VERSION}`);
}

View File

@ -0,0 +1,16 @@
import { CommandModule } from 'yargs';
export const yargsListCommand: CommandModule = {
command: 'list [plugin]',
describe:
'Lists installed plugins, capabilities of installed plugins and other available plugins.',
builder: (yargs) =>
yargs.positional('plugin', {
type: 'string',
description: 'The name of an installed plugin to query',
}),
handler: async (args: any) => {
await (await import('./list')).listHandler(args);
process.exit(0);
},
};

View File

@ -1,20 +1,20 @@
import { workspaceRoot } from '../utils/workspace-root';
import { output } from '../utils/output';
import { workspaceRoot } from '../../utils/workspace-root';
import { output } from '../../utils/output';
import {
fetchCorePlugins,
getInstalledPluginsAndCapabilities,
listCorePlugins,
listInstalledPlugins,
listPluginCapabilities,
} from '../utils/plugins';
} from '../../utils/plugins';
import {
getLocalWorkspacePlugins,
listLocalWorkspacePlugins,
} from '../utils/plugins/local-plugins';
} from '../../utils/plugins/local-plugins';
import {
createProjectGraphAsync,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
} from '../../project-graph/project-graph';
export interface ListArgs {
/** The name of an installed plugin to query */

View File

@ -0,0 +1,173 @@
import { Argv, CommandModule } from 'yargs';
import * as path from 'path';
import { runNxSync } from '../../utils/child-process';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import { execSync } from 'child_process';
import { getPackageManagerCommand } from '../../utils/package-manager';
import { writeJsonFile } from '../../utils/fileutils';
import { workspaceRoot } from '../../utils/workspace-root';
export const yargsMigrateCommand: CommandModule = {
command: 'migrate [packageAndVersion]',
describe: `Creates a migrations file or runs migrations from the migrations file.
- Migrate packages and create migrations.json (e.g., nx migrate @nx/workspace@latest)
- Run migrations (e.g., nx migrate --run-migrations=migrations.json). Use flag --if-exists to run migrations only if the migrations file exists.`,
builder: (yargs) =>
linkToNxDevAndExamples(withMigrationOptions(yargs), 'migrate'),
handler: () => {
runMigration();
process.exit(0);
},
};
export const yargsInternalMigrateCommand: CommandModule = {
command: '_migrate [packageAndVersion]',
describe: false,
builder: (yargs) => withMigrationOptions(yargs),
handler: async (args) =>
process.exit(
await (
await import('./migrate')
).migrate(process.cwd(), args, process.argv.slice(3))
),
};
function withMigrationOptions(yargs: Argv) {
const defaultCommitPrefix = 'chore: [nx migration] ';
return yargs
.positional('packageAndVersion', {
describe: `The target package and version (e.g, @nx/workspace@16.0.0)`,
type: 'string',
})
.option('runMigrations', {
describe: `Execute migrations from a file (when the file isn't provided, execute migrations from migrations.json)`,
type: 'string',
})
.option('ifExists', {
describe: `Run migrations only if the migrations file exists, if not continues successfully`,
type: 'boolean',
default: false,
})
.option('from', {
describe:
'Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@16.0.0,@nx/js@16.0.0")',
type: 'string',
})
.option('to', {
describe:
'Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@16.0.0,@nx/js@16.0.0")',
type: 'string',
})
.option('createCommits', {
describe: 'Automatically create a git commit after each migration runs',
type: 'boolean',
alias: ['C'],
default: false,
})
.option('commitPrefix', {
describe:
'Commit prefix to apply to the commit for each migration, when --create-commits is enabled',
type: 'string',
default: defaultCommitPrefix,
})
.option('interactive', {
describe:
'Enable prompts to confirm whether to collect optional package updates and migrations',
type: 'boolean',
default: false,
})
.option('excludeAppliedMigrations', {
describe:
'Exclude migrations that should have been applied on previous updates. To be used with --from',
type: 'boolean',
default: false,
})
.check(
({ createCommits, commitPrefix, from, excludeAppliedMigrations }) => {
if (!createCommits && commitPrefix !== defaultCommitPrefix) {
throw new Error(
'Error: Providing a custom commit prefix requires --create-commits to be enabled'
);
}
if (excludeAppliedMigrations && !from) {
throw new Error(
'Error: Excluding migrations that should have been previously applied requires --from to be set'
);
}
return true;
}
);
}
function runMigration() {
const runLocalMigrate = () => {
runNxSync(`_migrate ${process.argv.slice(3).join(' ')}`, {
stdio: ['inherit', 'inherit', 'inherit'],
});
};
if (process.env.NX_MIGRATE_USE_LOCAL === undefined) {
const p = nxCliPath();
if (p === null) {
runLocalMigrate();
} else {
execSync(`${p} _migrate ${process.argv.slice(3).join(' ')}`, {
stdio: ['inherit', 'inherit', 'inherit'],
});
}
} else {
runLocalMigrate();
}
}
function nxCliPath() {
try {
const packageManager = getPackageManagerCommand();
const { dirSync } = require('tmp');
const tmpDir = dirSync().name;
const version =
process.env.NX_MIGRATE_USE_NEXT === 'true' ? 'next' : 'latest';
writeJsonFile(path.join(tmpDir, 'package.json'), {
dependencies: {
nx: version,
},
license: 'MIT',
});
execSync(packageManager.install, {
cwd: tmpDir,
stdio: ['ignore', 'ignore', 'ignore'],
});
// Set NODE_PATH so that these modules can be used for module resolution
addToNodePath(path.join(tmpDir, 'node_modules'));
addToNodePath(path.join(workspaceRoot, 'node_modules'));
return path.join(tmpDir, `node_modules`, '.bin', 'nx');
} catch (e) {
console.error(
'Failed to install the latest version of the migration script. Using the current version.'
);
if (process.env.NX_VERBOSE_LOGGING) {
console.error(e);
}
return null;
}
}
function addToNodePath(dir: string) {
// NODE_PATH is a delimited list of paths.
// The delimiter is different for windows.
const delimiter = require('os').platform() === 'win32' ? ';' : ':';
const paths = process.env.NODE_PATH
? process.env.NODE_PATH.split(delimiter)
: [];
// Add the tmp path
paths.push(dir);
// Update the env variable.
process.env.NODE_PATH = paths.join(delimiter);
}

View File

@ -1,6 +1,6 @@
import * as enquirer from 'enquirer';
import { PackageJson } from '../utils/package-json';
import * as packageMgrUtils from '../utils/package-manager';
import { PackageJson } from '../../utils/package-json';
import * as packageMgrUtils from '../../utils/package-manager';
import {
Migrator,

View File

@ -20,24 +20,24 @@ import {
MigrationsJsonEntry,
PackageJsonUpdateForPackage as PackageUpdate,
PackageJsonUpdates,
} from '../config/misc-interfaces';
import { NxJsonConfiguration } from '../config/nx-json';
import { flushChanges, FsTree, printChanges } from '../generators/tree';
} from '../../config/misc-interfaces';
import { NxJsonConfiguration } from '../../config/nx-json';
import { flushChanges, FsTree, printChanges } from '../../generators/tree';
import {
extractFileFromTarball,
fileExists,
JsonReadOptions,
readJsonFile,
writeJsonFile,
} from '../utils/fileutils';
import { logger } from '../utils/logger';
} from '../../utils/fileutils';
import { logger } from '../../utils/logger';
import {
ArrayPackageGroup,
NxMigrationsConfiguration,
PackageJson,
readModulePackageJson,
readNxMigrateConfig,
} from '../utils/package-json';
} from '../../utils/package-json';
import {
createTempNpmDirectory,
detectPackageManager,
@ -45,20 +45,20 @@ import {
packageRegistryPack,
packageRegistryView,
resolvePackageVersionUsingRegistry,
} from '../utils/package-manager';
import { handleErrors } from '../utils/params';
import { connectToNxCloudCommand } from './connect';
import { output } from '../utils/output';
import { messages, recordStat } from '../utils/ab-testing';
import { nxVersion } from '../utils/versions';
} from '../../utils/package-manager';
import { handleErrors } from '../../utils/params';
import { connectToNxCloudCommand } from '../connect/connect-to-nx-cloud';
import { output } from '../../utils/output';
import { messages, recordStat } from '../../utils/ab-testing';
import { nxVersion } from '../../utils/versions';
import { existsSync, readFileSync } from 'fs';
import { workspaceRoot } from '../utils/workspace-root';
import { isCI } from '../utils/is-ci';
import { getNxRequirePaths } from '../utils/installation-directory';
import { readNxJson } from '../config/configuration';
import { runNxSync } from '../utils/child-process';
import { daemonClient } from '../daemon/client/client';
import { isNxCloudUsed } from '../utils/nx-cloud-utils';
import { workspaceRoot } from '../../utils/workspace-root';
import { isCI } from '../../utils/is-ci';
import { getNxRequirePaths } from '../../utils/installation-directory';
import { readNxJson } from '../../config/configuration';
import { runNxSync } from '../../utils/child-process';
import { daemonClient } from '../../daemon/client/client';
import { isNxCloudUsed } from '../../utils/nx-cloud-utils';
export interface ResolvedMigrationConfiguration extends MigrationsJson {
packageGroup?: ArrayPackageGroup;
@ -1705,11 +1705,11 @@ function isAngularMigration(
}
const getNgCompatLayer = (() => {
let _ngCliAdapter: typeof import('../adapter/ngcli-adapter');
let _ngCliAdapter: typeof import('../../adapter/ngcli-adapter');
return async function getNgCompatLayer() {
if (!_ngCliAdapter) {
_ngCliAdapter = await import('../adapter/ngcli-adapter');
require('../adapter/compat');
_ngCliAdapter = await import('../../adapter/ngcli-adapter');
require('../../adapter/compat');
}
return _ngCliAdapter;
};

View File

@ -0,0 +1,29 @@
import { Argv, CommandModule } from 'yargs';
export const yargsNewCommand: CommandModule = {
command: 'new [_..]',
describe: false,
builder: (yargs) => withNewOptions(yargs),
handler: async (args) => {
args._ = args._.slice(1);
process.exit(
await (
await import('./new')
).newWorkspace(args['nxWorkspaceRoot'] as string, args)
);
},
};
function withNewOptions(yargs: Argv) {
return yargs
.option('nxWorkspaceRoot', {
describe: 'The folder where the new workspace is going to be created',
type: 'string',
required: true,
})
.option('interactive', {
describe: 'When false disables interactive input prompts for options',
type: 'boolean',
default: true,
});
}

View File

@ -1,6 +1,6 @@
import { Workspaces } from '../config/workspaces';
import { flushChanges, FsTree } from '../generators/tree';
import { combineOptionsForGenerator, handleErrors } from '../utils/params';
import { Workspaces } from '../../config/workspaces';
import { flushChanges, FsTree } from '../../generators/tree';
import { combineOptionsForGenerator, handleErrors } from '../../utils/params';
function removeSpecialFlags(generatorOptions: { [p: string]: any }): void {
delete generatorOptions.interactive;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
import { ArgumentsCamelCase, CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
export const yargsRepairCommand: CommandModule = {
command: 'repair',
describe: 'Repair any configuration that is no longer supported by Nx.',
builder: (yargs) =>
linkToNxDevAndExamples(yargs, 'repair').option('verbose', {
type: 'boolean',
describe:
'Prints additional information about the commands (e.g., stack traces)',
}),
handler: async (args: ArgumentsCamelCase<{ verbose: boolean }>) =>
process.exit(await (await import('./repair')).repair(args)),
};

View File

@ -1,7 +1,7 @@
import { handleErrors } from '../utils/params';
import * as migrationsJson from '../../migrations.json';
import { executeMigrations } from './migrate';
import { output } from '../utils/output';
import { handleErrors } from '../../utils/params';
import * as migrationsJson from '../../../migrations.json';
import { executeMigrations } from '../migrate/migrate';
import { output } from '../../utils/output';
export async function repair(
args: { verbose: boolean },

View File

@ -0,0 +1,10 @@
import { CommandModule } from 'yargs';
export const yargsReportCommand: CommandModule = {
command: 'report',
describe: 'Reports useful version numbers to copy into the Nx issue template',
handler: async () => {
await (await import('./report')).reportHandler();
process.exit(0);
},
};

View File

@ -1,5 +1,5 @@
import * as fileUtils from '../utils/fileutils';
import * as packageJsonUtils from '../utils/package-json';
import * as fileUtils from '../../utils/fileutils';
import * as packageJsonUtils from '../../utils/package-json';
import {
findInstalledCommunityPlugins,
findInstalledPackagesWeCareAbout,
@ -11,8 +11,8 @@ jest.mock('nx/src/utils/workspace-root', () => ({
workspaceRoot: '',
}));
jest.mock('../utils/fileutils', () => ({
...(jest.requireActual('../utils/fileutils') as typeof fileUtils),
jest.mock('../../utils/fileutils', () => ({
...(jest.requireActual('../../utils/fileutils') as typeof fileUtils),
resolve: (file) => `node_modules/${file}`,
}));

View File

@ -1,32 +1,32 @@
import * as chalk from 'chalk';
import { output } from '../utils/output';
import { output } from '../../utils/output';
import { join } from 'path';
import {
detectPackageManager,
getPackageManagerVersion,
PackageManager,
} from '../utils/package-manager';
import { readJsonFile } from '../utils/fileutils';
} from '../../utils/package-manager';
import { readJsonFile } from '../../utils/fileutils';
import {
PackageJson,
readModulePackageJson,
readNxMigrateConfig,
} from '../utils/package-json';
import { getLocalWorkspacePlugins } from '../utils/plugins/local-plugins';
} from '../../utils/package-json';
import { getLocalWorkspacePlugins } from '../../utils/plugins/local-plugins';
import {
createProjectGraphAsync,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
} from '../../project-graph/project-graph';
import { gt, valid } from 'semver';
import { findInstalledPlugins } from '../utils/plugins/installed-plugins';
import { getNxRequirePaths } from '../utils/installation-directory';
import { findInstalledPlugins } from '../../utils/plugins/installed-plugins';
import { getNxRequirePaths } from '../../utils/installation-directory';
import {
getHashingImplementation,
HasherImplementation,
} from '../utils/get-hashing-implementation';
} from '../../utils/get-hashing-implementation';
const nxPackageJson = readJsonFile<typeof import('../../package.json')>(
join(__dirname, '../../package.json')
const nxPackageJson = readJsonFile<typeof import('../../../package.json')>(
join(__dirname, '../../../package.json')
);
export const packagesWeCareAbout = [

View File

@ -0,0 +1,9 @@
import { CommandModule } from 'yargs';
export const yargsResetCommand: CommandModule = {
command: 'reset',
describe:
'Clears all the cached Nx artifacts and metadata about the workspace and shuts down the Nx Daemon.',
aliases: ['clear-cache'],
handler: async () => (await import('./reset')).resetHandler(),
};

View File

@ -1,7 +1,10 @@
import { rmSync } from 'fs-extra';
import { daemonClient } from '../daemon/client/client';
import { cacheDir, projectGraphCacheDirectory } from '../utils/cache-directory';
import { output } from '../utils/output';
import { daemonClient } from '../../daemon/client/client';
import {
cacheDir,
projectGraphCacheDirectory,
} from '../../utils/cache-directory';
import { output } from '../../utils/output';
export async function resetHandler() {
output.note({

View File

@ -0,0 +1,22 @@
import { CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import {
withRunManyOptions,
withOutputStyleOption,
withTargetAndConfigurationOption,
withOverrides,
} from '../yargs-utils/shared-options';
export const yargsRunManyCommand: CommandModule = {
command: 'run-many',
describe: 'Run target for multiple listed projects',
builder: (yargs) =>
linkToNxDevAndExamples(
withRunManyOptions(
withOutputStyleOption(withTargetAndConfigurationOption(yargs))
),
'run-many'
),
handler: async (args) =>
(await import('./run-many')).runMany(withOverrides(args)),
};

View File

@ -1,6 +1,6 @@
import { projectsToRun } from './run-many';
import { performance } from 'perf_hooks';
import { ProjectGraph } from '../config/project-graph';
import { ProjectGraph } from '../../config/project-graph';
describe('run-many', () => {
describe('projectsToRun', () => {

View File

@ -1,17 +1,20 @@
import { runCommand } from '../tasks-runner/run-command';
import type { NxArgs } from '../utils/command-line-utils';
import { splitArgsIntoNxArgsAndOverrides } from '../utils/command-line-utils';
import { projectHasTarget } from '../utils/project-graph-utils';
import { connectToNxCloudIfExplicitlyAsked } from './connect';
import { runCommand } from '../../tasks-runner/run-command';
import type { NxArgs } from '../../utils/command-line-utils';
import { splitArgsIntoNxArgsAndOverrides } from '../../utils/command-line-utils';
import { projectHasTarget } from '../../utils/project-graph-utils';
import { connectToNxCloudIfExplicitlyAsked } from '../connect/connect-to-nx-cloud';
import { performance } from 'perf_hooks';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { createProjectGraphAsync } from '../project-graph/project-graph';
import { TargetDependencyConfig } from '../config/workspace-json-project-json';
import { readNxJson } from '../config/configuration';
import { output } from '../utils/output';
import { findMatchingProjects } from '../utils/find-matching-projects';
import { workspaceConfigurationCheck } from '../utils/workspace-configuration-check';
import { generateGraph } from './dep-graph';
import {
ProjectGraph,
ProjectGraphProjectNode,
} from '../../config/project-graph';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { TargetDependencyConfig } from '../../config/workspace-json-project-json';
import { readNxJson } from '../../config/configuration';
import { output } from '../../utils/output';
import { findMatchingProjects } from '../../utils/find-matching-projects';
import { workspaceConfigurationCheck } from '../../utils/workspace-configuration-check';
import { generateGraph } from '../graph/graph';
export async function runMany(
args: { [k: string]: any },

View File

@ -0,0 +1,19 @@
import { CommandModule } from 'yargs';
import {
withOverrides,
withRunOneOptions,
} from '../yargs-utils/shared-options';
export const yargsRunCommand: CommandModule = {
command: 'run [project][:target][:configuration] [_..]',
describe: `Run a target for a project
(e.g., nx run myapp:serve:production).
You can also use the infix notation to run a target:
(e.g., nx serve myapp --configuration=production)
You can skip the use of Nx cache by using the --skip-nx-cache option.`,
builder: (yargs) => withRunOneOptions(yargs),
handler: async (args) =>
(await import('./run-one')).runOne(process.cwd(), withOverrides(args)),
};

View File

@ -1,23 +1,23 @@
import { runCommand } from '../tasks-runner/run-command';
import { splitArgsIntoNxArgsAndOverrides } from '../utils/command-line-utils';
import { connectToNxCloudIfExplicitlyAsked } from './connect';
import { runCommand } from '../../tasks-runner/run-command';
import { splitArgsIntoNxArgsAndOverrides } from '../../utils/command-line-utils';
import { connectToNxCloudIfExplicitlyAsked } from '../connect/connect-to-nx-cloud';
import { performance } from 'perf_hooks';
import {
createProjectGraphAsync,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
import { ProjectGraph } from '../config/project-graph';
import { NxJsonConfiguration } from '../config/nx-json';
import { workspaceRoot } from '../utils/workspace-root';
import { splitTarget } from '../utils/split-target';
import { output } from '../utils/output';
} from '../../project-graph/project-graph';
import { ProjectGraph } from '../../config/project-graph';
import { NxJsonConfiguration } from '../../config/nx-json';
import { workspaceRoot } from '../../utils/workspace-root';
import { splitTarget } from '../../utils/split-target';
import { output } from '../../utils/output';
import {
ProjectsConfigurations,
TargetDependencyConfig,
} from '../config/workspace-json-project-json';
import { readNxJson } from '../config/configuration';
import { workspaceConfigurationCheck } from '../utils/workspace-configuration-check';
import { generateGraph } from './dep-graph';
} from '../../config/workspace-json-project-json';
import { readNxJson } from '../../config/configuration';
import { workspaceConfigurationCheck } from '../../utils/workspace-configuration-check';
import { generateGraph } from '../graph/graph';
export async function runOne(
cwd: string,

View File

@ -2,31 +2,31 @@ import {
combineOptionsForExecutor,
handleErrors,
Schema,
} from '../utils/params';
import { printHelp } from '../utils/print-help';
import { Workspaces } from '../config/workspaces';
import { NxJsonConfiguration } from '../config/nx-json';
import { readJsonFile } from '../utils/fileutils';
import { buildTargetFromScript, PackageJson } from '../utils/package-json';
} from '../../utils/params';
import { printHelp } from '../../utils/print-help';
import { Workspaces } from '../../config/workspaces';
import { NxJsonConfiguration } from '../../config/nx-json';
import { readJsonFile } from '../../utils/fileutils';
import { buildTargetFromScript, PackageJson } from '../../utils/package-json';
import { join } from 'path';
import { existsSync } from 'fs';
import {
loadNxPlugins,
mergePluginTargetsWithNxTargets,
} from '../utils/nx-plugin';
} from '../../utils/nx-plugin';
import {
ProjectConfiguration,
TargetConfiguration,
ProjectsConfigurations,
} from '../config/workspace-json-project-json';
import { Executor, ExecutorContext } from '../config/misc-interfaces';
import { serializeOverridesIntoCommandLine } from '../utils/serialize-overrides-into-command-line';
} from '../../config/workspace-json-project-json';
import { Executor, ExecutorContext } from '../../config/misc-interfaces';
import { serializeOverridesIntoCommandLine } from '../../utils/serialize-overrides-into-command-line';
import {
readCachedProjectGraph,
readProjectsConfigurationFromProjectGraph,
} from '../project-graph/project-graph';
import { ProjectGraph } from '../config/project-graph';
import { readNxJson } from '../config/configuration';
} from '../../project-graph/project-graph';
import { ProjectGraph } from '../../config/project-graph';
import { readNxJson } from '../../config/configuration';
export interface Target {
project: string;
@ -210,9 +210,9 @@ async function runExecutorInternal<T extends { success: boolean }>(
);
}
} else {
require('../adapter/compat');
require('../../adapter/compat');
const observable = await (
await import('../adapter/ngcli-adapter')
await import('../../adapter/ngcli-adapter')
).scheduleTarget(
root,
{
@ -223,7 +223,7 @@ async function runExecutorInternal<T extends { success: boolean }>(
},
isVerbose
);
const { eachValueFrom } = await import('../adapter/rxjs-for-await');
const { eachValueFrom } = await import('../../adapter/rxjs-for-await');
return eachValueFrom(observable as any);
}
}

View File

@ -0,0 +1,45 @@
import { Argv, CommandModule } from 'yargs';
const validObjectTypes = ['projects'] as const;
type NxObject = typeof validObjectTypes[number];
interface ShowCommandArguments {
object: NxObject;
}
export const yargsShowCommand: CommandModule<
ShowCommandArguments,
ShowCommandArguments
> = {
command: 'show <object>',
describe: 'Show information about the workspace (e.g., list of projects)',
builder: (yargs) => withShowOptions(yargs),
handler: async (args) => {
if (!validObjectTypes.includes(args.object)) {
}
await import('./show').then((m) => m.show(args));
process.exit(0);
},
};
function withShowOptions(yargs: Argv) {
return yargs
.positional('object', {
describe: 'What to show (e.g., projects)',
choices: ['projects'],
required: true,
})
.coerce({
object: (arg) => {
if (validObjectTypes.includes(arg)) {
return arg;
} else {
throw new Error(
`Invalid object type: ${arg}. Valid object types are: ${validObjectTypes.join(
', '
)}`
);
}
},
});
}

View File

@ -1,4 +1,4 @@
import { createProjectGraphAsync } from '../project-graph/project-graph';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
export async function show(args: { object: 'projects' }): Promise<void> {
if (args.object == 'projects') {

View File

@ -0,0 +1,68 @@
import { Argv, CommandModule } from 'yargs';
import { WatchArguments } from './watch';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import { parseCSV } from '../yargs-utils/shared-options';
export const yargsWatchCommand: CommandModule = {
command: 'watch',
describe: 'Watch for changes within projects, and execute commands',
builder: (yargs) => linkToNxDevAndExamples(withWatchOptions(yargs), 'watch'),
handler: async (args) => {
await import('./watch').then((m) => m.watch(args as WatchArguments));
},
};
function withWatchOptions(yargs: Argv) {
return yargs
.parserConfiguration({
'strip-dashed': true,
'populate--': true,
})
.option('projects', {
type: 'string',
alias: 'p',
coerce: parseCSV,
description: 'Projects to watch (comma/space delimited).',
})
.option('all', {
type: 'boolean',
description: 'Watch all projects.',
})
.option('includeDependentProjects', {
type: 'boolean',
description:
'When watching selected projects, include dependent projects as well.',
alias: 'd',
})
.option('includeGlobalWorkspaceFiles', {
type: 'boolean',
description:
'Include global workspace files that are not part of a project. For example, the root eslint, or tsconfig file.',
alias: 'g',
hidden: true,
})
.option('command', { type: 'string', hidden: true })
.option('verbose', {
type: 'boolean',
description:
'Run watch mode in verbose mode, where commands are logged before execution.',
})
.conflicts({
all: 'projects',
})
.check((args) => {
if (!args.all && !args.projects) {
throw Error('Please specify either --all or --projects');
}
return true;
})
.middleware((args) => {
const { '--': doubledash } = args;
if (doubledash && Array.isArray(doubledash)) {
args.command = (doubledash as string[]).join(' ');
} else {
throw Error('No command specified for watch mode.');
}
}, true);
}

View File

@ -1,6 +1,6 @@
import { spawn } from 'child_process';
import { ChangedFile, daemonClient } from '../daemon/client/client';
import { output } from '../utils/output';
import { ChangedFile, daemonClient } from '../../daemon/client/client';
import { output } from '../../utils/output';
export interface WatchArguments {
projects?: string[];

View File

@ -1,35 +0,0 @@
import yargs = require('yargs');
import { readNxJson } from '../config/configuration';
import { NxJsonConfiguration } from '../devkit-exports';
import { NX_PREFIX } from '../utils/logger';
import { output } from '../utils/output';
/**
* Wraps `workspace-generator` to invoke `generate`.
*
* @deprecated(v17): Remove `workspace-generator in v17. Use local plugins.
*/
export async function workspaceGenerators(args: yargs.Arguments) {
const generator = process.argv.slice(3);
output.warn({
title: `Workspace Generators are no longer supported`,
bodyLines: [
'Instead, Nx now supports executing generators or executors from ',
'local plugins. To run a generator from a local plugin, ',
'use `nx generate` like you would with any other generator.',
'',
'For more information, see: https://nx.dev/deprecated/workspace-generators',
],
});
const nxJson: NxJsonConfiguration = readNxJson();
const collection = nxJson.npmScope
? `@${nxJson.npmScope}/workspace-plugin`
: 'workspace-plugin';
args._ = args._.slice(1);
args.generator = `${collection}:${generator}`;
return (await import('./generate')).generate(process.cwd(), args);
}

View File

@ -0,0 +1,15 @@
import { CommandModule } from 'yargs';
/**
* @deprecated workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.
*/
export const yargsWorkspaceLintCommand: CommandModule = {
command: 'workspace-lint [files..]',
describe: 'Lint nx specific workspace files (nx.json, workspace.json)',
deprecated:
'workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.',
handler: async () => {
await (await import('./workspace-lint')).workspaceLint();
process.exit(0);
},
};

View File

@ -1,4 +1,4 @@
import { output } from '../utils/output';
import { output } from '../../utils/output';
export async function workspaceLint(): Promise<void> {
output.warn({

View File

@ -0,0 +1,17 @@
import chalk = require('chalk');
import yargs = require('yargs');
import { examples } from '../examples';
export function linkToNxDevAndExamples(yargs: yargs.Argv, command: string) {
(examples[command] || []).forEach((t) => {
yargs = yargs.example(t.command, t.description);
});
return yargs.epilog(
chalk.bold(
`Find more information and examples at https://nx.dev/nx/${command.replace(
':',
'-'
)}`
)
);
}

View File

@ -0,0 +1,291 @@
import { Argv } from 'yargs';
export function withExcludeOption(yargs: Argv): Argv {
return yargs.option('exclude', {
describe: 'Exclude certain projects from being processed',
type: 'string',
coerce: parseCSV,
});
}
export function withRunOptions(yargs: Argv): Argv {
return withExcludeOption(yargs)
.option('parallel', {
describe: 'Max number of parallel processes [default is 3]',
type: 'string',
})
.option('maxParallel', {
type: 'number',
hidden: true,
})
.options('runner', {
describe: 'This is the name of the tasks runner configured in nx.json',
type: 'string',
})
.option('prod', {
describe: 'Use the production configuration',
type: 'boolean',
default: false,
hidden: true,
})
.option('graph', {
type: 'boolean',
describe: 'Show the task graph of the command',
default: false,
})
.option('verbose', {
type: 'boolean',
describe:
'Prints additional information about the commands (e.g., stack traces)',
})
.option('nx-bail', {
describe: 'Stop command execution after the first failed task',
type: 'boolean',
default: false,
})
.option('nx-ignore-cycles', {
describe: 'Ignore cycles in the task graph',
type: 'boolean',
default: false,
})
.options('skip-nx-cache', {
describe:
'Rerun the tasks even when the results are available in the cache',
type: 'boolean',
default: false,
})
.options('cloud', {
type: 'boolean',
hidden: true,
})
.options('dte', {
type: 'boolean',
hidden: true,
});
}
export function withTargetAndConfigurationOption(
yargs: Argv,
demandOption = true
): Argv {
return withConfiguration(yargs).option('targets', {
describe: 'Tasks to run for affected projects',
type: 'string',
alias: ['target', 't'],
requiresArg: true,
coerce: parseCSV,
demandOption,
global: false,
});
}
export function withConfiguration(yargs: Argv) {
return yargs.options('configuration', {
describe:
'This is the configuration to use when performing tasks on projects',
type: 'string',
alias: 'c',
});
}
export function withAffectedOptions(yargs: Argv): Argv {
return withExcludeOption(yargs)
.parserConfiguration({
'strip-dashed': true,
'unknown-options-as-args': true,
'populate--': true,
})
.option('files', {
describe:
'Change the way Nx is calculating the affected command by providing directly changed files, list of files delimited by commas or spaces',
type: 'string',
requiresArg: true,
coerce: parseCSV,
})
.option('uncommitted', {
describe: 'Uncommitted changes',
type: 'boolean',
default: undefined,
})
.option('untracked', {
describe: 'Untracked changes',
type: 'boolean',
default: undefined,
})
.option('all', {
describe: 'All projects',
type: 'boolean',
default: undefined,
})
.option('base', {
describe: 'Base of the current branch (usually main)',
type: 'string',
requiresArg: true,
})
.option('head', {
describe: 'Latest commit of the current branch (usually HEAD)',
type: 'string',
requiresArg: true,
})
.group(
['base'],
'Run command using --base=[SHA1] (affected by the committed, uncommitted and untracked changes):'
)
.group(
['base', 'head'],
'or using --base=[SHA1] --head=[SHA2] (affected by the committed changes):'
)
.group(['files', 'uncommitted', 'untracked'], 'or using:')
.implies('head', 'base')
.conflicts({
files: ['uncommitted', 'untracked', 'base', 'head', 'all'],
untracked: ['uncommitted', 'files', 'base', 'head', 'all'],
uncommitted: ['files', 'untracked', 'base', 'head', 'all'],
all: ['files', 'untracked', 'uncommitted', 'base', 'head'],
});
}
export function withRunManyOptions(yargs: Argv): Argv {
return withRunOptions(yargs)
.parserConfiguration({
'strip-dashed': true,
'unknown-options-as-args': true,
'populate--': true,
})
.option('projects', {
type: 'string',
alias: 'p',
coerce: parseCSV,
describe:
'Projects to run. (comma/space delimited project names and/or patterns)',
})
.option('all', {
describe: '[deprecated] Run the target on all projects in the workspace',
type: 'boolean',
default: true,
});
}
export function withOverrides(args: any): any {
args.__overrides_unparsed__ = (args['--'] ?? args._.slice(1)).map((v) =>
v.toString()
);
delete args['--'];
delete args._;
return args;
}
export function withOutputStyleOption(
yargs: Argv,
choices = ['dynamic', 'static', 'stream', 'stream-without-prefixes']
): Argv {
return yargs.option('output-style', {
describe: 'Defines how Nx emits outputs tasks logs',
type: 'string',
choices,
});
}
export function withDepGraphOptions(yargs: Argv): Argv {
return yargs
.option('file', {
describe:
'Output file (e.g. --file=output.json or --file=dep-graph.html)',
type: 'string',
})
.option('view', {
describe: 'Choose whether to view the projects or task graph',
type: 'string',
default: 'projects',
choices: ['projects', 'tasks'],
})
.option('targets', {
describe: 'The target to show tasks for in the task graph',
type: 'string',
coerce: parseCSV,
})
.option('focus', {
describe:
'Use to show the project graph for a particular project and every node that is either an ancestor or a descendant.',
type: 'string',
})
.option('exclude', {
describe:
'List of projects delimited by commas to exclude from the project graph.',
type: 'string',
coerce: parseCSV,
})
.option('groupByFolder', {
describe: 'Group projects by folder in the project graph',
type: 'boolean',
})
.option('host', {
describe: 'Bind the project graph server to a specific ip address.',
type: 'string',
})
.option('port', {
describe: 'Bind the project graph server to a specific port.',
type: 'number',
})
.option('watch', {
describe: 'Watch for changes to project graph and update in-browser',
type: 'boolean',
default: false,
})
.option('open', {
describe: 'Open the project graph in the browser.',
type: 'boolean',
default: true,
});
}
export function withRunOneOptions(yargs: Argv) {
const executorShouldShowHelp = !(
process.argv[2] === 'run' && process.argv[3] === '--help'
);
const res = withRunOptions(
withOutputStyleOption(withConfiguration(yargs), [
'dynamic',
'static',
'stream',
'stream-without-prefixes',
'compact',
])
)
.parserConfiguration({
'strip-dashed': true,
'unknown-options-as-args': true,
'populate--': true,
})
.option('project', {
describe: 'Target project',
type: 'string',
})
.option('help', {
describe: 'Show Help',
type: 'boolean',
});
if (executorShouldShowHelp) {
return res.help(false);
} else {
return res.epilog(
`Run "nx run myapp:mytarget --help" to see information about the executor's schema.`
);
}
}
export function parseCSV(args: string[] | string) {
if (!args) {
return args;
}
if (Array.isArray(args)) {
return args;
}
const items = args.split(',');
return items.map((i) =>
i.startsWith('"') && i.endsWith('"') ? i.slice(1, -1) : i
);
}

View File

@ -92,11 +92,11 @@ export {
/**
* @category Commands
*/
export type { Target } from './command-line/run';
export type { Target } from './command-line/run/run';
/**
* @category Commands
*/
export { runExecutor } from './command-line/run';
export { runExecutor } from './command-line/run/run';
/**
* @category Generators

View File

@ -13,6 +13,7 @@ import { output } from '../utils/output';
import { dirname, join, relative, sep } from 'path';
import * as chalk from 'chalk';
import { gt } from 'semver';
import { nxVersion } from '../utils/versions';
/**
* Options to set when writing a file in the Virtual file system tree.
@ -354,7 +355,7 @@ export class FsTree implements Tree {
private assertUnlocked() {
if (this.locked) {
// TODO (v17): Remove condition
if (gt(require('../../package.json').version, '17.0.0')) {
if (gt(nxVersion, '17.0.0')) {
throw new Error(
'The tree has already been committed to disk. It can no longer be modified. Do not modify the tree during a GeneratorCallback and ensure that Promises have resolved before the generator returns or resolves.'
);

View File

@ -1,7 +1,7 @@
import {
getNxWrapperContents,
nxWrapperPath,
} from '../../nx-init/dot-nx/add-nx-scripts';
} from '../../command-line/init/implementation/dot-nx/add-nx-scripts';
import { normalizePath } from '../../utils/path';
import { Tree } from '../../generators/tree';