Skip to content

Commit

Permalink
feat(core): version option should display global and local installati…
Browse files Browse the repository at this point in the history
…on separately (#15911)
  • Loading branch information
AgentEnder committed Mar 30, 2023
1 parent 62c2ebe commit 3575028
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 18 deletions.
40 changes: 40 additions & 0 deletions e2e/nx-misc/src/misc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ describe('global installation', () => {
});

it('should warn if local Nx has higher major version', () => {
const packageJsonContents = readFile('node_modules/nx/package.json');
updateJson('node_modules/nx/package.json', (json) => {
json.version = `${major(getPublishedVersion()) + 2}.0.0`;
return json;
Expand All @@ -632,5 +633,44 @@ describe('global installation', () => {
output = runCommand(`nx show projects`);
}).not.toThrow();
expect(output).toContain('Its time to update Nx');
updateFile('node_modules/nx/package.json', packageJsonContents);
});

it('--version should display global installs version', () => {
const packageJsonContents = readFile('node_modules/nx/package.json');
const localVersion = `${major(getPublishedVersion()) + 2}.0.0`;
updateJson('node_modules/nx/package.json', (json) => {
json.version = localVersion;
return json;
});
let output: string;
expect(() => {
output = runCommand(`nx --version`);
}).not.toThrow();
expect(output).toContain(`- Local: v${localVersion}`);
expect(output).toContain(`- Global: v${getPublishedVersion()}`);
updateFile('node_modules/nx/package.json', packageJsonContents);
});

it('report should display global installs version', () => {
const packageJsonContents = readFile('node_modules/nx/package.json');
const localVersion = `${major(getPublishedVersion()) + 2}.0.0`;
updateJson('node_modules/nx/package.json', (json) => {
json.version = localVersion;
return json;
});
let output: string;
expect(() => {
output = runCommand(`nx report`);
}).not.toThrow();
expect(output).toEqual(
expect.stringMatching(new RegExp(`nx.*:.*${localVersion}`))
);
expect(output).toEqual(
expect.stringMatching(
new RegExp(`nx \\(global\\).*:.*${getPublishedVersion()}`)
)
);
updateFile('node_modules/nx/package.json', packageJsonContents);
});
});
56 changes: 41 additions & 15 deletions packages/nx/bin/nx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '../src/utils/installation-directory';
import { major } from 'semver';
import { readJsonFile } from '../src/utils/fileutils';
import { stripIndents } from '../src/utils/strip-indents';
import { execSync } from 'child_process';

function main() {
Expand Down Expand Up @@ -60,21 +61,36 @@ function main() {
try {
localNx = resolveNx(workspace);
} catch {
// If we can't resolve a local copy of Nx, we must be global.
warnIfUsingOutdatedGlobalInstall();
output.error({
title: `Could not find Nx modules in this workspace.`,
bodyLines: [`Have you run ${chalk.bold.white(`npm/yarn install`)}?`],
});
process.exit(1);
localNx = null;
}

const isLocalInstall = localNx === resolveNx(null);
const LOCAL_NX_VERSION: string | null = localNx
? getLocalNxVersion(workspace)
: null;
const GLOBAL_NX_VERSION: string | null = isLocalInstall
? null
: require('../package.json').version;

globalThis.GLOBAL_NX_VERSION ??= GLOBAL_NX_VERSION;

if (process.argv[2] === '--version') {
console.log(stripIndents`Nx Version:
- Local: v${LOCAL_NX_VERSION ?? 'Not found'}
- Global: v${GLOBAL_NX_VERSION ?? 'Not found'}`);
process.exit(0);
}

if (!localNx) {
handleMissingLocalInstallation();
}

// this file is already in the local workspace
if (localNx === resolveNx(null)) {
if (isLocalInstall) {
initLocal(workspace);
} else {
// Nx is being run from globally installed CLI - hand off to the local
warnIfUsingOutdatedGlobalInstall(getLocalNxVersion(workspace));
warnIfUsingOutdatedGlobalInstall(GLOBAL_NX_VERSION, LOCAL_NX_VERSION);
if (localNx.includes('.nx')) {
const nxWrapperPath = localNx.replace(/\.nx.*/, '.nx/') + 'nxw.js';
require(nxWrapperPath);
Expand Down Expand Up @@ -106,24 +122,34 @@ function resolveNx(workspace: WorkspaceTypeAndRoot | null) {
}
}

function handleMissingLocalInstallation() {
output.error({
title: `Could not find Nx modules in this workspace.`,
bodyLines: [`Have you run ${chalk.bold.white(`npm/yarn install`)}?`],
});
process.exit(1);
}

/**
* Assumes currently running Nx is global install.
* Warns if out of date by 1 major version or more.
*/
function warnIfUsingOutdatedGlobalInstall(localNxVersion?: string) {
const globalVersion = require('../package.json').version;
function warnIfUsingOutdatedGlobalInstall(
globalNxVersion: string,
localNxVersion?: string
) {
const isOutdatedGlobalInstall =
globalVersion &&
((localNxVersion && major(globalVersion) < major(localNxVersion)) ||
globalNxVersion &&
((localNxVersion && major(globalNxVersion) < major(localNxVersion)) ||
(!localNxVersion &&
getLatestVersionOfNx() &&
major(globalVersion) < major(getLatestVersionOfNx())));
major(globalNxVersion) < major(getLatestVersionOfNx())));

// Using a global Nx Install
if (isOutdatedGlobalInstall) {
const bodyLines = localNxVersion
? [
`Your repository uses a higher version of Nx (${localNxVersion}) than your global CLI version (${globalVersion})`,
`Your repository uses a higher version of Nx (${localNxVersion}) than your global CLI version (${globalNxVersion})`,
]
: [];

Expand Down
6 changes: 5 additions & 1 deletion packages/nx/src/command-line/nx-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getPackageManagerCommand } from '../utils/package-manager';
import { writeJsonFile } from '../utils/fileutils';
import { WatchArguments } from './watch';
import { runNxSync } from '../utils/child-process';
import { stripIndents } from '../utils/strip-indents';

// Ensure that the output takes up the available width of the terminal.
yargs.wrap(yargs.terminalWidth());
Expand Down Expand Up @@ -411,7 +412,10 @@ export const commandsObject = yargs
})
.scriptName('nx')
.help()
.version(nxVersion);
// NOTE: we handle --version in nx.ts, this just tells yargs that the option exists
// so that it shows up in help. The default yargs implementation of --version is not
// hit, as the implementation in nx.ts is hit first and calls process.exit(0).
.version();

function withShowOptions(yargs: yargs.Argv): yargs.Argv {
return yargs.positional('object', {
Expand Down
13 changes: 11 additions & 2 deletions packages/nx/src/command-line/report.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as chalk from 'chalk';
import { workspaceRoot } from '../utils/workspace-root';
import { output } from '../utils/output';
import { join } from 'path';
import {
Expand Down Expand Up @@ -27,7 +26,6 @@ const nxPackageJson = readJsonFile<typeof import('../../package.json')>(
);

export const packagesWeCareAbout = [
'nx',
'lerna',
...nxPackageJson['nx-migrations'].packageGroup.map((x) =>
typeof x === 'string' ? x : x.package
Expand Down Expand Up @@ -161,6 +159,16 @@ export async function getReportData(): Promise<ReportData> {
}

const packageVersionsWeCareAbout = findInstalledPackagesWeCareAbout();
packageVersionsWeCareAbout.unshift({
package: 'nx',
version: nxPackageJson.version,
});
if (globalThis.GLOBAL_NX_VERSION) {
packageVersionsWeCareAbout.unshift({
package: 'nx (global)',
version: globalThis.GLOBAL_NX_VERSION,
});
}

const outOfSyncPackageGroup = findMisalignedPackagesForPackage(nxPackageJson);

Expand Down Expand Up @@ -248,6 +256,7 @@ export function findInstalledCommunityPlugins(): PackageJson[] {
const installedPlugins = findInstalledPlugins();
return installedPlugins.filter(
(dep) =>
dep.name !== 'nx' &&
!patternsWeIgnoreInCommunityReport.some((pattern) =>
typeof pattern === 'string'
? pattern === dep.name
Expand Down

1 comment on commit 3575028

@vercel
Copy link

@vercel vercel bot commented on 3575028 Mar 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-five.vercel.app
nx-dev-nrwl.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx.dev

Please sign in to comment.