Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ProjectConfigurationsError,
mergeTargetConfigurations,
retrieveProjectConfigurations,
globalSpinner,
} from 'nx/src/devkit-internals';
import type { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl';
import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils';
Expand Down Expand Up @@ -423,6 +424,10 @@ async function migrateProjects<T>(
logger?: typeof devkitLogger
): Promise<Map<string, Record<string, string>>> {
const projects = new Map<string, Record<string, string>>();
const spinner = globalSpinner.start(
`Calculating migration scope...`,
pluginPath
);

for (const migration of migrations) {
for (const executor of migration.executors) {
Expand All @@ -442,9 +447,7 @@ async function migrateProjects<T>(
},
logger
);

const result = await migrator.run();

// invert the result to have a map of projects to their targets
for (const [target, projectList] of result.entries()) {
for (const project of projectList) {
Expand Down Expand Up @@ -476,8 +479,10 @@ async function migrateProjects<T>(
createNodes,
createNodesV2,
defaultPluginOptions,
projectGraph
projectGraph,
spinner
);
spinner.succeed(`Migrated configuration for ${projects.size} project(s).\n`);

return projects;
}
Expand All @@ -489,15 +494,21 @@ async function addPluginRegistrations<T>(
createNodes: CreateNodesV2 | undefined,
createNodesV2: CreateNodesV2 | undefined,
defaultPluginOptions: T,
projectGraph: ProjectGraph
projectGraph: ProjectGraph,
spinner: typeof globalSpinner
) {
const nxJson = readNxJson(tree);

// collect createNodes results for each project before adding the plugins
const createNodesResults = new Map<string, ConfigurationResult>();
global.NX_GRAPH_CREATION = true;
try {
let index = 0;
for (const [project, options] of projects.entries()) {
index++;
spinner.updateText(
`${index}/${projects.size} - Parsing "${project}" configuration...`
);
const projectConfigs = await getCreateNodesResultsForPlugin(
tree,
{ plugin: pluginPath, options },
Expand Down Expand Up @@ -537,7 +548,12 @@ async function addPluginRegistrations<T>(
return !deepEqual(originalResults, result);
};

let index = 0;
for (const [project, options] of projects.entries()) {
index++;
spinner.updateText(
`${index}/${projects.size} - Applying "${project}" configuration...`
);
const existingPlugin = nxJson.plugins?.find(
(plugin): plugin is ExpandedPluginConfiguration =>
typeof plugin !== 'string' &&
Expand Down Expand Up @@ -581,6 +597,7 @@ async function addPluginRegistrations<T>(
}
}
}
spinner.updateText(`Migrations done`);

updateNxJson(tree, nxJson);
}
Expand Down
8 changes: 3 additions & 5 deletions packages/nx/src/command-line/add/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
runPluginInitGenerator,
getFailedToInstallPluginErrorMessages,
} from '../init/configure-plugins';
import * as ora from 'ora';
import { globalSpinner } from '../../utils/spinner';

export function addHandler(options: AddOptions): Promise<number> {
return handleErrors(options.verbose, async () => {
Expand All @@ -43,8 +43,7 @@ async function installPackage(
version: string,
nxJson: NxJsonConfiguration
): Promise<void> {
const spinner = ora(`Installing ${pkgName}@${version}...`);
spinner.start();
const spinner = globalSpinner.start(`Installing ${pkgName}@${version}...`);

if (existsSync('package.json')) {
const pm = detectPackageManager();
Expand Down Expand Up @@ -121,8 +120,7 @@ async function initializePlugin(
updatePackageScripts = true;
}

const spinner = ora(`Initializing ${pkgName}...`);
spinner.start();
const spinner = globalSpinner.start(`Initializing ${pkgName}...`);

try {
await runPluginInitGenerator(
Expand Down
5 changes: 2 additions & 3 deletions packages/nx/src/command-line/init/configure-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as createSpinner from 'ora';
import { bold } from 'chalk';

import {
Expand All @@ -22,6 +21,7 @@ import { readNxJson } from '../../config/configuration';
import { nxVersion } from '../../utils/versions';
import { runNxSync } from '../../utils/child-process';
import { writeJsonFile } from '../../utils/fileutils';
import { globalSpinner } from '../../utils/spinner';

export function installPluginPackages(
repoRoot: string,
Expand Down Expand Up @@ -116,15 +116,14 @@ export async function runPluginInitGenerators(
failedPlugins: {},
};
}
const spinner = createSpinner();
let succeededPlugins = [];
const failedPlugins: {
[pluginName: string]: Error;
} = {};

for (const plugin of plugins) {
const spinner = globalSpinner.start('Installing plugin ' + plugin);
try {
spinner.start('Installing plugin ' + plugin);
await runPluginInitGenerator(
plugin,
repoRoot,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import chalk = require('chalk');
import * as ora from 'ora';
import { prompt } from 'enquirer';
import { NxReleaseVersionConfiguration } from '../../../config/nx-json';
import type { ProjectGraphProjectNode } from '../../../config/project-graph';
Expand All @@ -9,6 +8,7 @@ import { getLatestGitTagForPattern } from '../utils/git';
import { ProjectLogger } from './project-logger';
import type { FinalConfigForProject } from '../utils/release-graph';
import { VersionActions } from './version-actions';
import { globalSpinner } from '../../../utils/spinner';

export async function resolveCurrentVersion(
tree: Tree,
Expand Down Expand Up @@ -152,11 +152,9 @@ export async function resolveCurrentVersionFromRegistry(

let registryTxt = '';

const spinner = ora(
const spinner = globalSpinner.start(
`Resolving the current version for ${projectGraphNode.name} from the configured registry...`
);
spinner.color = 'cyan';
spinner.start();

try {
const res = await versionActions.readCurrentVersionFromRegistry(
Expand Down
5 changes: 2 additions & 3 deletions packages/nx/src/command-line/sync/sync.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as ora from 'ora';
import { readNxJson } from '../../config/nx-json';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { output } from '../../utils/output';
Expand All @@ -14,6 +13,7 @@ import {
} from '../../utils/sync-generators';
import type { SyncArgs } from './command-object';
import chalk = require('chalk');
import { globalSpinner } from '../../utils/spinner';

interface SyncOptions extends SyncArgs {
check?: boolean;
Expand Down Expand Up @@ -111,8 +111,7 @@ export function syncHandler(options: SyncOptions): Promise<number> {
bodyLines: resultBodyLines,
});

const spinner = ora('Syncing the workspace...');
spinner.start();
const spinner = globalSpinner.start('Syncing the workspace...');

try {
const flushResult = await flushSyncGeneratorChanges(results);
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/devkit-internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ export { interpolate } from './tasks-runner/utils';
export { isCI } from './utils/is-ci';
export { isUsingPrettierInTree } from './utils/is-using-prettier';
export { readYamlFile } from './utils/fileutils';
export { globalSpinner } from './utils/spinner';
12 changes: 5 additions & 7 deletions packages/nx/src/utils/delayed-spinner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as ora from 'ora';
import { isCI } from './is-ci';
import { globalSpinner, SHOULD_SHOW_SPINNERS } from './spinner';

export type DelayedSpinnerOptions = {
delay?: number;
Expand All @@ -13,7 +13,7 @@ export type DelayedSpinnerOptions = {
* takes longer than a certain amount of time.
*/
export class DelayedSpinner {
spinner: ora.Ora;
spinner: typeof globalSpinner;
timeouts: NodeJS.Timeout[] = [];

private lastMessage: string;
Expand All @@ -34,8 +34,8 @@ export class DelayedSpinner {
this.lastMessage = message;
if (!SHOULD_SHOW_SPINNERS) {
console.warn(this.lastMessage);
} else {
this.spinner = ora(this.lastMessage).start();
} else if (!globalSpinner.isSpinning()) {
this.spinner = globalSpinner.start(this.lastMessage);
}
}, delay).unref()
);
Expand All @@ -50,7 +50,7 @@ export class DelayedSpinner {
setMessage(message: string) {
if (SHOULD_SHOW_SPINNERS) {
if (this.spinner) {
this.spinner.text = message;
this.spinner.updateText(message);
}
} else if (this.ready && this.lastMessage && this.lastMessage !== message) {
console.warn(message);
Expand Down Expand Up @@ -88,8 +88,6 @@ export class DelayedSpinner {
}
}

const SHOULD_SHOW_SPINNERS = process.stdout.isTTY && !isCI();

function normalizeDelayedSpinnerOpts(
opts: DelayedSpinnerOptions | null | undefined
) {
Expand Down
61 changes: 61 additions & 0 deletions packages/nx/src/utils/spinner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as ora from 'ora';
import { isCI } from './is-ci';

export const SHOULD_SHOW_SPINNERS = process.stdout.isTTY && !isCI();

class SpinnerManager {
#ora!: ReturnType<typeof ora>;
#prefix: string | undefined;

start(text?: string, prefix?: string): SpinnerManager {
if (!SHOULD_SHOW_SPINNERS) {
return this;
}
if (prefix !== undefined) {
this.#prefix = prefix;
}
if (this.#ora) {
this.#ora.text = text;
this.#ora.prefixText = this.#prefix;
} else {
this.#createOra(text);
}
this.#ora.start();
return this;
}

succeed(text?: string) {
this.#ora?.succeed(text);
}

stop() {
this.#ora?.stop();
}

fail(text?: string) {
this.#ora?.fail(text);
}

updateText(text?: string) {
if (this.#ora) {
this.#ora.text = text;
} else if (SHOULD_SHOW_SPINNERS) {
this.#createOra(text);
}
}

isSpinning() {
return this.#ora?.isSpinning ?? false;
}

#createOra(text?: string) {
this.#ora = ora({
text: text,
prefixText: this.#prefix,
hideCursor: false,
discardStdin: false,
});
}
}

export const globalSpinner = new SpinnerManager();
Loading