fix(core): nx migrate should work in encapsulated Nx repos (#15338)
This commit is contained in:
parent
17a0d2c085
commit
4a53ace70d
@ -8,6 +8,8 @@ import {
|
|||||||
cleanupProject,
|
cleanupProject,
|
||||||
getPublishedVersion,
|
getPublishedVersion,
|
||||||
uniq,
|
uniq,
|
||||||
|
readJson,
|
||||||
|
readFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
import { bold } from 'chalk';
|
import { bold } from 'chalk';
|
||||||
|
|
||||||
@ -104,6 +106,161 @@ describe('encapsulated nx', () => {
|
|||||||
).not.toThrow();
|
).not.toThrow();
|
||||||
expect(() => checkFilesExist());
|
expect(() => checkFilesExist());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work with migrate', () => {
|
||||||
|
updateFile(
|
||||||
|
`.nx/installation/node_modules/migrate-parent-package/package.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
version: '1.0.0',
|
||||||
|
name: 'migrate-parent-package',
|
||||||
|
'nx-migrations': './migrations.json',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`.nx/installation/node_modules/migrate-parent-package/migrations.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
schematics: {
|
||||||
|
run11: {
|
||||||
|
version: '1.1.0',
|
||||||
|
description: '1.1.0',
|
||||||
|
factory: './run11',
|
||||||
|
},
|
||||||
|
run20: {
|
||||||
|
version: '2.0.0',
|
||||||
|
description: '2.0.0',
|
||||||
|
implementation: './run20',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`.nx/installation/node_modules/migrate-parent-package/run11.js`,
|
||||||
|
`
|
||||||
|
exports.default = function default_1() {
|
||||||
|
return function(host) {
|
||||||
|
host.create('file-11', 'content11')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`.nx/installation/node_modules/migrate-parent-package/run20.js`,
|
||||||
|
`
|
||||||
|
exports.default = function (host) {
|
||||||
|
host.write('file-20', 'content20')
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
updateFile(
|
||||||
|
`.nx/installation/node_modules/migrate-child-package/package.json`,
|
||||||
|
JSON.stringify({
|
||||||
|
name: 'migrate-child-package',
|
||||||
|
version: '1.0.0',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches migration fetcher to load in migrations that we are using to test.
|
||||||
|
*/
|
||||||
|
updateFile(
|
||||||
|
'.nx/installation/node_modules/nx/src/command-line/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 = `
|
||||||
|
function createFetcher(logger) {
|
||||||
|
return function fetch(packageName) {
|
||||||
|
if (packageName === 'migrate-parent-package') {
|
||||||
|
return Promise.resolve({
|
||||||
|
version: '2.0.0',
|
||||||
|
generators: {
|
||||||
|
'run11': {
|
||||||
|
version: '1.1.0'
|
||||||
|
},
|
||||||
|
'run20': {
|
||||||
|
version: '2.0.0',
|
||||||
|
cli: 'nx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
packageJsonUpdates: {
|
||||||
|
'run-11': {version: '1.1.0', packages: {
|
||||||
|
'migrate-child-package': {version: '9.0.0', alwaysAddToPackageJson: false},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve({version: '9.0.0'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return `${before}${newFetch}${after}`;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
updateJson('nx.json', (j: NxJsonConfiguration) => {
|
||||||
|
j.installation = {
|
||||||
|
version: getPublishedVersion(),
|
||||||
|
plugins: {
|
||||||
|
'migrate-child-package': '1.0.0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return j;
|
||||||
|
});
|
||||||
|
runEncapsulatedNx(
|
||||||
|
'migrate migrate-parent-package@2.0.0 --from="migrate-parent-package@1.0.0"',
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
NX_MIGRATE_SKIP_INSTALL: 'true',
|
||||||
|
NX_MIGRATE_USE_LOCAL: 'true',
|
||||||
|
NX_WRAPPER_SKIP_INSTALL: 'true',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const nxJson: NxJsonConfiguration = readJson(`nx.json`);
|
||||||
|
expect(nxJson.installation.plugins['migrate-child-package']).toEqual(
|
||||||
|
'9.0.0'
|
||||||
|
);
|
||||||
|
// creates migrations.json
|
||||||
|
const migrationsJson = readJson(`migrations.json`);
|
||||||
|
expect(migrationsJson).toEqual({
|
||||||
|
migrations: [
|
||||||
|
{
|
||||||
|
package: 'migrate-parent-package',
|
||||||
|
version: '1.1.0',
|
||||||
|
name: 'run11',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: 'migrate-parent-package',
|
||||||
|
version: '2.0.0',
|
||||||
|
name: 'run20',
|
||||||
|
cli: 'nx',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// runs migrations
|
||||||
|
runEncapsulatedNx('migrate --run-migrations=migrations.json', {
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
NX_MIGRATE_SKIP_INSTALL: 'true',
|
||||||
|
NX_MIGRATE_USE_LOCAL: 'true',
|
||||||
|
NX_WRAPPER_SKIP_INSTALL: 'true',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(readFile('file-11')).toEqual('content11');
|
||||||
|
expect(readFile('file-20')).toEqual('content20');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function assertNoRootPackages() {
|
function assertNoRootPackages() {
|
||||||
|
|||||||
@ -66,19 +66,20 @@ export function setMaxWorkers() {
|
|||||||
|
|
||||||
export function runCommand(
|
export function runCommand(
|
||||||
command: string,
|
command: string,
|
||||||
options?: Partial<ExecSyncOptions>
|
options?: Partial<ExecSyncOptions> & { failOnError?: boolean }
|
||||||
): string {
|
): string {
|
||||||
|
const { failOnError, ...childProcessOptions } = options ?? {};
|
||||||
try {
|
try {
|
||||||
const r = execSync(command, {
|
const r = execSync(command, {
|
||||||
cwd: tmpProjPath(),
|
cwd: tmpProjPath(),
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
env: {
|
env: {
|
||||||
...getStrippedEnvironmentVariables(),
|
...getStrippedEnvironmentVariables(),
|
||||||
...options?.env,
|
...childProcessOptions?.env,
|
||||||
FORCE_COLOR: 'false',
|
FORCE_COLOR: 'false',
|
||||||
},
|
},
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
...options,
|
...childProcessOptions,
|
||||||
}).toString();
|
}).toString();
|
||||||
if (process.env.NX_VERBOSE_LOGGING) {
|
if (process.env.NX_VERBOSE_LOGGING) {
|
||||||
console.log(r);
|
console.log(r);
|
||||||
@ -87,7 +88,7 @@ export function runCommand(
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// this is intentional
|
// this is intentional
|
||||||
// npm ls fails if package is not found
|
// npm ls fails if package is not found
|
||||||
if (e.stdout || e.stderr) {
|
if (!failOnError && (e.stdout || e.stderr)) {
|
||||||
return e.stdout?.toString() + e.stderr?.toString();
|
return e.stdout?.toString() + e.stderr?.toString();
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import * as isCI from 'is-ci';
|
|||||||
|
|
||||||
import { angularCliVersion } from '@nrwl/workspace/src/utils/versions';
|
import { angularCliVersion } from '@nrwl/workspace/src/utils/versions';
|
||||||
import { dump } from '@zkochan/js-yaml';
|
import { dump } from '@zkochan/js-yaml';
|
||||||
import { execSync } from 'child_process';
|
import { execSync, ExecSyncOptions } from 'child_process';
|
||||||
|
|
||||||
import { isVerbose } from './get-env-info';
|
import { isVerbose } from './get-env-info';
|
||||||
import { logError, logInfo } from './log-utils';
|
import { logError, logInfo } from './log-utils';
|
||||||
@ -372,15 +372,15 @@ export function newLernaWorkspace({
|
|||||||
export function newEncapsulatedNxWorkspace({
|
export function newEncapsulatedNxWorkspace({
|
||||||
name = uniq('encapsulated'),
|
name = uniq('encapsulated'),
|
||||||
pmc = getPackageManagerCommand(),
|
pmc = getPackageManagerCommand(),
|
||||||
} = {}): (command: string) => string {
|
} = {}): (command: string, opts?: Partial<ExecSyncOptions>) => string {
|
||||||
projName = name;
|
projName = name;
|
||||||
ensureDirSync(tmpProjPath());
|
ensureDirSync(tmpProjPath());
|
||||||
runCommand(`${pmc.runUninstalledPackage} nx@latest init --encapsulated`);
|
runCommand(`${pmc.runUninstalledPackage} nx@latest init --encapsulated`);
|
||||||
return (command: string) => {
|
return (command: string, opts: Partial<ExecSyncOptions>) => {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
return runCommand(`./nx.bat ${command}`);
|
return runCommand(`./nx.bat ${command}`, { ...opts, failOnError: true });
|
||||||
} else {
|
} else {
|
||||||
return runCommand(`./nx ${command}`);
|
return runCommand(`./nx ${command}`, { ...opts, failOnError: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { Tree } from '@nrwl/devkit';
|
import type { Tree } from '@nrwl/devkit';
|
||||||
import { getPackageManagerCommand } from '@nrwl/devkit';
|
import { getPackageManagerCommand } from '@nrwl/devkit';
|
||||||
import { execSync } from 'child_process';
|
import { runNxSync } from 'nx/src/utils/child-process';
|
||||||
|
|
||||||
export function formatFilesTask(tree: Tree): void {
|
export function formatFilesTask(tree: Tree): void {
|
||||||
if (
|
if (
|
||||||
@ -11,8 +11,7 @@ export function formatFilesTask(tree: Tree): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pmc = getPackageManagerCommand();
|
|
||||||
try {
|
try {
|
||||||
execSync(`${pmc.exec} nx format`, { cwd: tree.root, stdio: [0, 1, 2] });
|
runNxSync(`format`, { cwd: tree.root, stdio: [0, 1, 2] });
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import {
|
|||||||
} from '../generators/utils/project-configuration';
|
} from '../generators/utils/project-configuration';
|
||||||
import { createProjectGraphAsync } from '../project-graph/project-graph';
|
import { createProjectGraphAsync } from '../project-graph/project-graph';
|
||||||
import { readJsonFile } from '../utils/fileutils';
|
import { readJsonFile } from '../utils/fileutils';
|
||||||
|
import { getNxRequirePaths } from '../utils/installation-directory';
|
||||||
import { parseJson } from '../utils/json';
|
import { parseJson } from '../utils/json';
|
||||||
import { NX_ERROR, NX_PREFIX } from '../utils/logger';
|
import { NX_ERROR, NX_PREFIX } from '../utils/logger';
|
||||||
import { readModulePackageJson } from '../utils/package-json';
|
import { readModulePackageJson } from '../utils/package-json';
|
||||||
@ -643,9 +644,10 @@ function resolveMigrationsCollection(name: string): string {
|
|||||||
if (extname(name)) {
|
if (extname(name)) {
|
||||||
collectionPath = require.resolve(name);
|
collectionPath = require.resolve(name);
|
||||||
} else {
|
} else {
|
||||||
const { path: packageJsonPath, packageJson } = readModulePackageJson(name, [
|
const { path: packageJsonPath, packageJson } = readModulePackageJson(
|
||||||
process.cwd(),
|
name,
|
||||||
]);
|
getNxRequirePaths(process.cwd())
|
||||||
|
);
|
||||||
|
|
||||||
let pkgJsonSchematics =
|
let pkgJsonSchematics =
|
||||||
packageJson['nx-migrations'] ?? packageJson['ng-update'];
|
packageJson['nx-migrations'] ?? packageJson['ng-update'];
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { workspaceRoot } from '../utils/workspace-root';
|
import { workspaceRoot } from '../utils/workspace-root';
|
||||||
|
import { runNxSync } from '../utils/child-process';
|
||||||
|
|
||||||
export async function connectToNxCloudIfExplicitlyAsked(opts: {
|
export async function connectToNxCloudIfExplicitlyAsked(opts: {
|
||||||
[k: string]: any;
|
[k: string]: any;
|
||||||
@ -24,13 +25,7 @@ export async function connectToNxCloudIfExplicitlyAsked(opts: {
|
|||||||
output.log({
|
output.log({
|
||||||
title: '--cloud requires the workspace to be connected to Nx Cloud.',
|
title: '--cloud requires the workspace to be connected to Nx Cloud.',
|
||||||
});
|
});
|
||||||
const pmc = getPackageManagerCommand();
|
runNxSync(`connect-to-nx-cloud`, {
|
||||||
const nxCommand = existsSync(join(workspaceRoot, 'package.json'))
|
|
||||||
? `${pmc.exec} nx`
|
|
||||||
: process.platform === 'win32'
|
|
||||||
? './nx.bat'
|
|
||||||
: './nx';
|
|
||||||
execSync(`${nxCommand} connect-to-nx-cloud`, {
|
|
||||||
stdio: [0, 1, 2],
|
stdio: [0, 1, 2],
|
||||||
});
|
});
|
||||||
output.success({
|
output.success({
|
||||||
@ -60,11 +55,6 @@ export async function connectToNxCloudCommand(
|
|||||||
const res = await connectToNxCloudPrompt(promptOverride);
|
const res = await connectToNxCloudPrompt(promptOverride);
|
||||||
if (!res) return false;
|
if (!res) return false;
|
||||||
const pmc = getPackageManagerCommand();
|
const pmc = getPackageManagerCommand();
|
||||||
const nxCommand = pmc
|
|
||||||
? `${pmc.exec} nx`
|
|
||||||
: process.platform === 'win32'
|
|
||||||
? './nx.bat'
|
|
||||||
: './nx';
|
|
||||||
if (pmc) {
|
if (pmc) {
|
||||||
execSync(`${pmc.addDev} @nrwl/nx-cloud@latest`);
|
execSync(`${pmc.addDev} @nrwl/nx-cloud@latest`);
|
||||||
} else {
|
} else {
|
||||||
@ -76,7 +66,7 @@ export async function connectToNxCloudCommand(
|
|||||||
).toString();
|
).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
execSync(`${nxCommand} g @nrwl/nx-cloud:init`, {
|
runNxSync(`g @nrwl/nx-cloud:init`, {
|
||||||
stdio: [0, 1, 2],
|
stdio: [0, 1, 2],
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -53,6 +53,9 @@ import { nxVersion } from '../utils/versions';
|
|||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { workspaceRoot } from '../utils/workspace-root';
|
import { workspaceRoot } from '../utils/workspace-root';
|
||||||
import { isCI } from '../utils/is-ci';
|
import { isCI } from '../utils/is-ci';
|
||||||
|
import { getNxRequirePaths } from '../utils/installation-directory';
|
||||||
|
import { readNxJson } from '../config/configuration';
|
||||||
|
import { runNxSync } from '../utils/child-process';
|
||||||
|
|
||||||
export interface ResolvedMigrationConfiguration extends MigrationsJson {
|
export interface ResolvedMigrationConfiguration extends MigrationsJson {
|
||||||
packageGroup?: ArrayPackageGroup;
|
packageGroup?: ArrayPackageGroup;
|
||||||
@ -100,7 +103,8 @@ function normalizeSlashes(packageName: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MigratorOptions {
|
export interface MigratorOptions {
|
||||||
packageJson: PackageJson;
|
packageJson?: PackageJson;
|
||||||
|
nxInstallation?: NxJsonConfiguration['installation'];
|
||||||
getInstalledPackageVersion: (
|
getInstalledPackageVersion: (
|
||||||
pkg: string,
|
pkg: string,
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
@ -116,7 +120,7 @@ export interface MigratorOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Migrator {
|
export class Migrator {
|
||||||
private readonly packageJson: MigratorOptions['packageJson'];
|
private readonly packageJson?: MigratorOptions['packageJson'];
|
||||||
private readonly getInstalledPackageVersion: MigratorOptions['getInstalledPackageVersion'];
|
private readonly getInstalledPackageVersion: MigratorOptions['getInstalledPackageVersion'];
|
||||||
private readonly fetch: MigratorOptions['fetch'];
|
private readonly fetch: MigratorOptions['fetch'];
|
||||||
private readonly installedPkgVersionOverrides: MigratorOptions['from'];
|
private readonly installedPkgVersionOverrides: MigratorOptions['from'];
|
||||||
@ -126,9 +130,11 @@ export class Migrator {
|
|||||||
private readonly packageUpdates: Record<string, PackageUpdate> = {};
|
private readonly packageUpdates: Record<string, PackageUpdate> = {};
|
||||||
private readonly collectedVersions: Record<string, string> = {};
|
private readonly collectedVersions: Record<string, string> = {};
|
||||||
private readonly promptAnswers: Record<string, boolean> = {};
|
private readonly promptAnswers: Record<string, boolean> = {};
|
||||||
|
private readonly nxInstallation: NxJsonConfiguration['installation'] | null;
|
||||||
|
|
||||||
constructor(opts: MigratorOptions) {
|
constructor(opts: MigratorOptions) {
|
||||||
this.packageJson = opts.packageJson;
|
this.packageJson = opts.packageJson;
|
||||||
|
this.nxInstallation = opts.nxInstallation;
|
||||||
this.getInstalledPackageVersion = opts.getInstalledPackageVersion;
|
this.getInstalledPackageVersion = opts.getInstalledPackageVersion;
|
||||||
this.fetch = opts.fetch;
|
this.fetch = opts.fetch;
|
||||||
this.installedPkgVersionOverrides = opts.from;
|
this.installedPkgVersionOverrides = opts.from;
|
||||||
@ -400,33 +406,34 @@ export class Migrator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { dependencies, devDependencies } = this.packageJson;
|
const dependencies: Record<string, string> = {
|
||||||
packageJsonUpdate.packages = Object.entries(packageJsonUpdate.packages)
|
...this.packageJson?.dependencies,
|
||||||
.filter(
|
...this.packageJson?.devDependencies,
|
||||||
([packageName, packageUpdate]) =>
|
...this.nxInstallation?.plugins,
|
||||||
(!packageUpdate.ifPackageInstalled ||
|
...(this.nxInstallation && { nx: this.nxInstallation.version }),
|
||||||
this.getPkgVersion(packageUpdate.ifPackageInstalled)) &&
|
};
|
||||||
(packageUpdate.alwaysAddToPackageJson ||
|
|
||||||
packageUpdate.addToPackageJson ||
|
const filtered: Record<string, PackageUpdate> = {};
|
||||||
!!dependencies?.[packageName] ||
|
for (const [packageName, packageUpdate] of Object.entries(
|
||||||
!!devDependencies?.[packageName]) &&
|
packageJsonUpdate.packages
|
||||||
(!this.collectedVersions[packageName] ||
|
)) {
|
||||||
this.gt(
|
if (
|
||||||
packageUpdate.version,
|
this.shouldApplyPackageUpdate(
|
||||||
this.collectedVersions[packageName]
|
packageUpdate,
|
||||||
))
|
packageName,
|
||||||
|
dependencies
|
||||||
)
|
)
|
||||||
.reduce((acc, [packageName, packageUpdate]) => {
|
) {
|
||||||
acc[packageName] = {
|
filtered[packageName] = {
|
||||||
version: packageUpdate.version,
|
version: packageUpdate.version,
|
||||||
addToPackageJson: packageUpdate.alwaysAddToPackageJson
|
addToPackageJson: packageUpdate.alwaysAddToPackageJson
|
||||||
? 'dependencies'
|
? 'dependencies'
|
||||||
: packageUpdate.addToPackageJson || false,
|
: packageUpdate.addToPackageJson || false,
|
||||||
};
|
};
|
||||||
return acc;
|
}
|
||||||
}, {} as Record<string, PackageUpdate>);
|
}
|
||||||
|
if (Object.keys(filtered).length) {
|
||||||
if (Object.keys(packageJsonUpdate.packages).length) {
|
packageJsonUpdate.packages = filtered;
|
||||||
filteredPackageJsonUpdates.push(packageJsonUpdate);
|
filteredPackageJsonUpdates.push(packageJsonUpdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,6 +441,22 @@ export class Migrator {
|
|||||||
return filteredPackageJsonUpdates;
|
return filteredPackageJsonUpdates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private shouldApplyPackageUpdate(
|
||||||
|
packageUpdate: PackageUpdate,
|
||||||
|
packageName: string,
|
||||||
|
dependencies: Record<string, string>
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
(!packageUpdate.ifPackageInstalled ||
|
||||||
|
this.getPkgVersion(packageUpdate.ifPackageInstalled)) &&
|
||||||
|
(packageUpdate.alwaysAddToPackageJson ||
|
||||||
|
packageUpdate.addToPackageJson ||
|
||||||
|
!!dependencies?.[packageName]) &&
|
||||||
|
(!this.collectedVersions[packageName] ||
|
||||||
|
this.gt(packageUpdate.version, this.collectedVersions[packageName]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private addPackageUpdate(name: string, packageUpdate: PackageUpdate): void {
|
private addPackageUpdate(name: string, packageUpdate: PackageUpdate): void {
|
||||||
if (
|
if (
|
||||||
!this.packageUpdates[name] ||
|
!this.packageUpdates[name] ||
|
||||||
@ -732,9 +755,10 @@ function createInstalledPackageVersionsResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!cache[packageName]) {
|
if (!cache[packageName]) {
|
||||||
const { packageJson, path } = readModulePackageJson(packageName, [
|
const { packageJson, path } = readModulePackageJson(
|
||||||
root,
|
packageName,
|
||||||
]);
|
getNxRequirePaths()
|
||||||
|
);
|
||||||
// old workspaces would have the temp installation of nx in the cache,
|
// old workspaces would have the temp installation of nx in the cache,
|
||||||
// so the resolved package is not the one we need
|
// so the resolved package is not the one we need
|
||||||
if (!path.startsWith(workspaceRoot)) {
|
if (!path.startsWith(workspaceRoot)) {
|
||||||
@ -970,7 +994,7 @@ function readPackageMigrationConfig(
|
|||||||
): PackageMigrationConfig {
|
): PackageMigrationConfig {
|
||||||
const { path: packageJsonPath, packageJson: json } = readModulePackageJson(
|
const { path: packageJsonPath, packageJson: json } = readModulePackageJson(
|
||||||
packageName,
|
packageName,
|
||||||
[dir]
|
getNxRequirePaths(dir)
|
||||||
);
|
);
|
||||||
|
|
||||||
const config = readNxMigrateConfig(json);
|
const config = readNxMigrateConfig(json);
|
||||||
@ -1043,7 +1067,7 @@ function updatePackageJson(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateInstallationDetails(
|
async function updateInstallationDetails(
|
||||||
root: string,
|
root: string,
|
||||||
updatedPackages: Record<string, PackageUpdate>
|
updatedPackages: Record<string, PackageUpdate>
|
||||||
) {
|
) {
|
||||||
@ -1064,7 +1088,9 @@ function updateInstallationDetails(
|
|||||||
for (const dep in nxJson.installation.plugins) {
|
for (const dep in nxJson.installation.plugins) {
|
||||||
const update = updatedPackages[dep];
|
const update = updatedPackages[dep];
|
||||||
if (update) {
|
if (update) {
|
||||||
nxJson.installation.plugins[dep] = update.version;
|
nxJson.installation.plugins[dep] = valid(update.version)
|
||||||
|
? update.version
|
||||||
|
: await resolvePackageVersionUsingRegistry(dep, update.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1101,10 +1127,13 @@ async function generateMigrationsJsonAndUpdatePackageJson(
|
|||||||
) {
|
) {
|
||||||
const pmc = getPackageManagerCommand();
|
const pmc = getPackageManagerCommand();
|
||||||
try {
|
try {
|
||||||
let originalPackageJson = readJsonFile<PackageJson>(
|
const rootPkgJsonPath = join(root, 'package.json');
|
||||||
join(root, 'package.json')
|
let originalPackageJson = existsSync(rootPkgJsonPath)
|
||||||
);
|
? readJsonFile<PackageJson>(rootPkgJsonPath)
|
||||||
const from = readNxVersion(originalPackageJson);
|
: null;
|
||||||
|
const originalNxInstallation = readNxJson().installation;
|
||||||
|
const from =
|
||||||
|
originalNxInstallation?.version ?? readNxVersion(originalPackageJson);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
@ -1135,6 +1164,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(
|
|||||||
|
|
||||||
const migrator = new Migrator({
|
const migrator = new Migrator({
|
||||||
packageJson: originalPackageJson,
|
packageJson: originalPackageJson,
|
||||||
|
nxInstallation: originalNxInstallation,
|
||||||
getInstalledPackageVersion: createInstalledPackageVersionsResolver(root),
|
getInstalledPackageVersion: createInstalledPackageVersionsResolver(root),
|
||||||
fetch: createFetcher(),
|
fetch: createFetcher(),
|
||||||
from: opts.from,
|
from: opts.from,
|
||||||
@ -1149,7 +1179,7 @@ async function generateMigrationsJsonAndUpdatePackageJson(
|
|||||||
);
|
);
|
||||||
|
|
||||||
updatePackageJson(root, packageUpdates);
|
updatePackageJson(root, packageUpdates);
|
||||||
updateInstallationDetails(root, packageUpdates);
|
await updateInstallationDetails(root, packageUpdates);
|
||||||
|
|
||||||
if (migrations.length > 0) {
|
if (migrations.length > 0) {
|
||||||
createMigrationsFile(root, [
|
createMigrationsFile(root, [
|
||||||
@ -1352,8 +1382,7 @@ async function runMigrations(
|
|||||||
if (!__dirname.startsWith(workspaceRoot)) {
|
if (!__dirname.startsWith(workspaceRoot)) {
|
||||||
// we are running from a temp installation with nx latest, switch to running
|
// we are running from a temp installation with nx latest, switch to running
|
||||||
// from local installation
|
// from local installation
|
||||||
const pmc = getPackageManagerCommand();
|
runNxSync(`migrate ${args.join(' ')}`, {
|
||||||
execSync(`${pmc.exec} nx migrate ${args.join(' ')}`, {
|
|
||||||
stdio: ['inherit', 'inherit', 'inherit'],
|
stdio: ['inherit', 'inherit', 'inherit'],
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
@ -1410,11 +1439,17 @@ async function runMigrations(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getStringifiedPackageJsonDeps(root: string): string {
|
function getStringifiedPackageJsonDeps(root: string): string {
|
||||||
|
try {
|
||||||
const { dependencies, devDependencies } = readJsonFile<PackageJson>(
|
const { dependencies, devDependencies } = readJsonFile<PackageJson>(
|
||||||
join(root, 'package.json')
|
join(root, 'package.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify([dependencies, devDependencies]);
|
return JSON.stringify([dependencies, devDependencies]);
|
||||||
|
} catch {
|
||||||
|
// We don't really care if the .nx/installation property changes,
|
||||||
|
// whenever nxw is invoked it will handle the dep updates.
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitChanges(commitMessage: string): string | null {
|
function commitChanges(commitMessage: string): string | null {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { workspaceRoot } from '../utils/workspace-root';
|
|||||||
import { getPackageManagerCommand } from '../utils/package-manager';
|
import { getPackageManagerCommand } from '../utils/package-manager';
|
||||||
import { writeJsonFile } from '../utils/fileutils';
|
import { writeJsonFile } from '../utils/fileutils';
|
||||||
import { WatchArguments } from './watch';
|
import { WatchArguments } from './watch';
|
||||||
|
import { runNxSync } from '../utils/child-process';
|
||||||
|
|
||||||
// Ensure that the output takes up the available width of the terminal.
|
// Ensure that the output takes up the available width of the terminal.
|
||||||
yargs.wrap(yargs.terminalWidth());
|
yargs.wrap(yargs.terminalWidth());
|
||||||
@ -1090,8 +1091,7 @@ function withListOptions(yargs) {
|
|||||||
|
|
||||||
function runMigration() {
|
function runMigration() {
|
||||||
const runLocalMigrate = () => {
|
const runLocalMigrate = () => {
|
||||||
const pmc = getPackageManagerCommand();
|
runNxSync(`_migrate ${process.argv.slice(3).join(' ')}`, {
|
||||||
execSync(`${pmc.exec} nx _migrate ${process.argv.slice(3).join(' ')}`, {
|
|
||||||
stdio: ['inherit', 'inherit', 'inherit'],
|
stdio: ['inherit', 'inherit', 'inherit'],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { getPackageManagerCommand } from '../utils/package-manager';
|
|||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import { isNxCloudUsed } from '../utils/nx-cloud-utils';
|
import { isNxCloudUsed } from '../utils/nx-cloud-utils';
|
||||||
import { output } from '../utils/output';
|
import { output } from '../utils/output';
|
||||||
|
import { runNxSync } from '../utils/child-process';
|
||||||
|
|
||||||
export async function viewLogs(): Promise<number> {
|
export async function viewLogs(): Promise<number> {
|
||||||
const pmc = getPackageManagerCommand();
|
const pmc = getPackageManagerCommand();
|
||||||
@ -48,10 +49,9 @@ export async function viewLogs(): Promise<number> {
|
|||||||
output.log({
|
output.log({
|
||||||
title: 'Connecting to Nx Cloud',
|
title: 'Connecting to Nx Cloud',
|
||||||
});
|
});
|
||||||
execSync(
|
runNxSync(`g @nrwl/nx-cloud:init --installation-source=view-logs`, {
|
||||||
`${pmc.exec} nx g @nrwl/nx-cloud:init --installation-source=view-logs`,
|
stdio: 'ignore',
|
||||||
{ stdio: 'ignore' }
|
});
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
output.log({
|
output.log({
|
||||||
title: 'Failed to connect to Nx Cloud',
|
title: 'Failed to connect to Nx Cloud',
|
||||||
|
|||||||
@ -99,8 +99,10 @@ function ensureUpToDateInstallation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module && !process.env.NX_WRAPPER_SET) {
|
if (require.main === module || !process.env.NX_WRAPPER_SET) {
|
||||||
process.env.NX_WRAPPER_SET = 'true';
|
if (!process.env.NX_WRAPPER_SKIP_INSTALL) {
|
||||||
ensureUpToDateInstallation();
|
ensureUpToDateInstallation();
|
||||||
|
}
|
||||||
|
process.env.NX_WRAPPER_SET = 'true';
|
||||||
require('./installation/node_modules/nx/bin/nx');
|
require('./installation/node_modules/nx/bin/nx');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
getPackageManagerCommand,
|
getPackageManagerCommand,
|
||||||
PackageManagerCommands,
|
PackageManagerCommands,
|
||||||
} from '../utils/package-manager';
|
} from '../utils/package-manager';
|
||||||
|
import { runNxSync } from '../utils/child-process';
|
||||||
|
|
||||||
export function askAboutNxCloud() {
|
export function askAboutNxCloud() {
|
||||||
return enquirer
|
return enquirer
|
||||||
@ -121,12 +122,8 @@ export function runInstall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function initCloud(repoRoot: string) {
|
export function initCloud(repoRoot: string) {
|
||||||
const pmc = getPackageManagerCommand();
|
runNxSync(`g @nrwl/nx-cloud:init --installationSource=add-nx-to-monorepo`, {
|
||||||
execSync(
|
|
||||||
`${pmc.exec} nx g @nrwl/nx-cloud:init --installationSource=add-nx-to-monorepo`,
|
|
||||||
{
|
|
||||||
stdio: [0, 1, 2],
|
stdio: [0, 1, 2],
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
28
packages/nx/src/utils/child-process.ts
Normal file
28
packages/nx/src/utils/child-process.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { execSync, ExecSyncOptions } from 'child_process';
|
||||||
|
import { existsSync } from 'fs';
|
||||||
|
import { join, relative } from 'path';
|
||||||
|
import { getPackageManagerCommand } from './package-manager';
|
||||||
|
import { workspaceRoot, workspaceRootInner } from './workspace-root';
|
||||||
|
|
||||||
|
export function runNxSync(
|
||||||
|
cmd: string,
|
||||||
|
options?: ExecSyncOptions & { cwd?: string }
|
||||||
|
) {
|
||||||
|
let baseCmd: string;
|
||||||
|
if (existsSync(join(workspaceRoot, 'package.json'))) {
|
||||||
|
baseCmd = `${getPackageManagerCommand().exec} nx`;
|
||||||
|
} else {
|
||||||
|
options ??= {};
|
||||||
|
options.cwd ??= process.cwd();
|
||||||
|
const offsetFromRoot = relative(
|
||||||
|
options.cwd,
|
||||||
|
workspaceRootInner(options.cwd, null)
|
||||||
|
);
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
baseCmd = '.\\' + join(`${offsetFromRoot}`, 'nx.bat');
|
||||||
|
} else {
|
||||||
|
baseCmd = './' + join(`${offsetFromRoot}`, 'nx');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
execSync(`${baseCmd} ${cmd}`, options);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user