216 lines
6.7 KiB
TypeScript
216 lines
6.7 KiB
TypeScript
import { performance } from 'perf_hooks';
|
|
|
|
import { commandsObject } from '../src/command-line/nx-commands';
|
|
import { WorkspaceTypeAndRoot } from '../src/utils/find-workspace-root';
|
|
import { stripIndents } from '../src/utils/strip-indents';
|
|
import { daemonClient } from '../src/daemon/client/client';
|
|
import { prompt } from 'enquirer';
|
|
import { output } from '../src/utils/output';
|
|
import { flushAnalytics } from '../src/analytics';
|
|
|
|
/**
|
|
* Nx is being run inside a workspace.
|
|
*
|
|
* @param workspace Relevant local workspace properties
|
|
*/
|
|
export async function initLocal(workspace: WorkspaceTypeAndRoot) {
|
|
process.env.NX_CLI_SET = 'true';
|
|
|
|
try {
|
|
// In case Nx Cloud forcibly exits while the TUI is running, ensure the terminal is restored etc.
|
|
process.on('exit', (...args) => {
|
|
if (typeof globalThis.tuiOnProcessExit === 'function') {
|
|
globalThis.tuiOnProcessExit(...args);
|
|
}
|
|
});
|
|
performance.mark('init-local');
|
|
|
|
if (workspace.type !== 'nx' && shouldDelegateToAngularCLI()) {
|
|
console.warn(
|
|
stripIndents`Using Nx to run Angular CLI commands is deprecated and will be removed in a future version.
|
|
To run Angular CLI commands, use \`ng\`.`
|
|
);
|
|
handleAngularCLIFallbacks(workspace);
|
|
return;
|
|
}
|
|
|
|
// Skip per-TAB shell completion calls — those must not spawn the daemon.
|
|
if (!process.env.NX_COMPLETE) {
|
|
try {
|
|
await ensureNxConsoleInstalledViaDaemon();
|
|
} catch {}
|
|
}
|
|
|
|
const command = process.argv[2];
|
|
if (
|
|
command === 'completion' ||
|
|
command === 'run' ||
|
|
command === 'g' ||
|
|
command === 'generate'
|
|
) {
|
|
commandsObject.parse(process.argv.slice(2));
|
|
} else if (isKnownCommand(command)) {
|
|
const newArgs = rewriteTargetsAndProjects(process.argv);
|
|
const help = newArgs.indexOf('--help');
|
|
const split = newArgs.indexOf('--');
|
|
if (help > -1 && (split === -1 || split > help)) {
|
|
commandsObject.showHelp();
|
|
process.exit(0);
|
|
} else {
|
|
commandsObject.parse(newArgs);
|
|
}
|
|
} else {
|
|
commandsObject.parse(process.argv.slice(2));
|
|
}
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
flushAnalytics();
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
export function rewriteTargetsAndProjects(args: string[]) {
|
|
const newArgs = [args[2]];
|
|
let i = 3;
|
|
while (i < args.length) {
|
|
if (args[i] === '--') {
|
|
return [...newArgs, ...args.slice(i)];
|
|
} else if (
|
|
args[i] === '-p' ||
|
|
args[i] === '--projects' ||
|
|
args[i] === '--exclude' ||
|
|
args[i] === '--files' ||
|
|
args[i] === '-t' ||
|
|
args[i] === '--target' ||
|
|
args[i] === '--targets'
|
|
) {
|
|
newArgs.push(args[i]);
|
|
i++;
|
|
const items = [];
|
|
while (i < args.length && !args[i].startsWith('-')) {
|
|
items.push(args[i]);
|
|
i++;
|
|
}
|
|
newArgs.push(items.join(','));
|
|
} else {
|
|
newArgs.push(args[i]);
|
|
++i;
|
|
}
|
|
}
|
|
return newArgs;
|
|
}
|
|
|
|
function isKnownCommand(command: string) {
|
|
const commands = [
|
|
...Object.keys(
|
|
(commandsObject as any)
|
|
.getInternalMethods()
|
|
.getCommandInstance()
|
|
.getCommandHandlers()
|
|
),
|
|
'g',
|
|
'dep-graph',
|
|
'affected:dep-graph',
|
|
'format',
|
|
'workspace-schematic',
|
|
'connect-to-nx-cloud',
|
|
'clear-cache',
|
|
'help',
|
|
];
|
|
return !command || command.startsWith('-') || commands.indexOf(command) > -1;
|
|
}
|
|
|
|
function shouldDelegateToAngularCLI() {
|
|
const command = process.argv[2];
|
|
const commands = ['analytics', 'cache', 'config', 'doc', 'update'];
|
|
return commands.indexOf(command) > -1;
|
|
}
|
|
|
|
async function ensureNxConsoleInstalledViaDaemon(): Promise<void> {
|
|
// Only proceed if daemon is available
|
|
if (!daemonClient.enabled() || !(await daemonClient.isServerAvailable())) {
|
|
return;
|
|
}
|
|
|
|
// Get status from daemon
|
|
const status = await daemonClient.getNxConsoleStatus();
|
|
|
|
// If we should prompt the user
|
|
if (status.shouldPrompt && process.stdout.isTTY) {
|
|
output.log({
|
|
title: "Install Nx's official editor extension to:",
|
|
bodyLines: [
|
|
'- Enable your AI assistant to do more by understanding your workspace',
|
|
'- Add IntelliSense for Nx configuration files',
|
|
'- Explore your workspace visually',
|
|
],
|
|
});
|
|
|
|
try {
|
|
const { shouldInstallNxConsole } = await prompt<{
|
|
shouldInstallNxConsole: boolean;
|
|
}>({
|
|
type: 'confirm',
|
|
name: 'shouldInstallNxConsole',
|
|
message: 'Install Nx Console? (you can uninstall anytime)',
|
|
initial: true,
|
|
});
|
|
|
|
// Set preference and install if user said yes
|
|
const result = await daemonClient.setNxConsolePreferenceAndInstall(
|
|
shouldInstallNxConsole
|
|
);
|
|
|
|
if (result.installed) {
|
|
output.log({ title: 'Successfully installed Nx Console!' });
|
|
}
|
|
} catch (error) {
|
|
// User cancelled or error occurred, save preference as false
|
|
await daemonClient.setNxConsolePreferenceAndInstall(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleAngularCLIFallbacks(workspace: WorkspaceTypeAndRoot) {
|
|
if (process.argv[2] === 'update' && process.env.FORCE_NG_UPDATE != 'true') {
|
|
console.log(
|
|
`Nx provides a much improved version of "ng update". It runs the same migrations, but allows you to:`
|
|
);
|
|
console.log(`- rerun the same migration multiple times`);
|
|
console.log(`- reorder migrations, skip migrations`);
|
|
console.log(`- fix migrations that "almost work"`);
|
|
console.log(`- commit a partially migrated state`);
|
|
console.log(
|
|
`- change versions of packages to match organizational requirements`
|
|
);
|
|
console.log(
|
|
`And, in general, it is lot more reliable for non-trivial workspaces. Read more at: https://nx.dev/docs/technologies/angular/guides/nx-and-angular#ng-update-vs-nx-migrate`
|
|
);
|
|
console.log(
|
|
`Run "nx migrate latest" to update to the latest version of Nx.`
|
|
);
|
|
console.log(
|
|
`Running "ng update" can still be useful in some dev workflows, so we aren't planning to remove it.`
|
|
);
|
|
console.log(`If you need to use it, run "FORCE_NG_UPDATE=true ng update".`);
|
|
} else if (process.argv[2] === 'cache') {
|
|
console.log(`"ng cache" is not natively supported by Nx.
|
|
To clear the cache, you can delete the ".angular/cache" directory (or the directory configured by "cli.cache.path" in the "nx.json" file).
|
|
To update the cache configuration, you can directly update the relevant options in your "nx.json" file (https://angular.dev/reference/configs/workspace-config#cache-options).`);
|
|
} else {
|
|
try {
|
|
// nx-ignore-next-line
|
|
const cli = require.resolve('@angular/cli/lib/init.js', {
|
|
paths: [workspace.dir],
|
|
});
|
|
require(cli);
|
|
} catch (e) {
|
|
console.error(
|
|
`Could not find '@angular/cli/lib/init.js' module in this workspace.`,
|
|
e
|
|
);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
}
|