nx
Version:
769 lines • 34.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrate = exports.executeMigrations = exports.parseMigrationsOptions = exports.Migrator = exports.normalizeVersion = void 0;
const tslib_1 = require("tslib");
const chalk = require("chalk");
const child_process_1 = require("child_process");
const path_1 = require("path");
const semver_1 = require("semver");
const util_1 = require("util");
const tree_1 = require("../generators/tree");
const fileutils_1 = require("../utils/fileutils");
const logger_1 = require("../utils/logger");
const package_json_1 = require("../utils/package-json");
const package_manager_1 = require("../utils/package-manager");
const params_1 = require("../utils/params");
const connect_to_nx_cloud_1 = require("./connect-to-nx-cloud");
const output_1 = require("../utils/output");
const execAsync = (0, util_1.promisify)(child_process_1.exec);
function normalizeVersion(version) {
const [semver, prereleaseTag] = version.split('-');
const [major, minor, patch] = semver.split('.');
const newSemver = `${major || 0}.${minor || 0}.${patch || 0}`;
const newVersion = prereleaseTag
? `${newSemver}-${prereleaseTag}`
: newSemver;
const withoutPatch = `${major || 0}.${minor || 0}.0`;
const withoutPatchAndMinor = `${major || 0}.0.0`;
const variationsToCheck = [
newVersion,
newSemver,
withoutPatch,
withoutPatchAndMinor,
];
for (const variation of variationsToCheck) {
try {
if ((0, semver_1.gt)(variation, '0.0.0')) {
return variation;
}
}
catch (_a) { }
}
return '0.0.0';
}
exports.normalizeVersion = normalizeVersion;
function normalizeSlashes(packageName) {
return packageName.replace(/\\/g, '/');
}
class Migrator {
constructor(opts) {
this.collectedVersions = {};
this.packageJson = opts.packageJson;
this.versions = opts.versions;
this.fetch = opts.fetch;
this.to = opts.to;
}
updatePackageJson(targetPackage, targetVersion) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const packageJson = yield this._updatePackageJson(targetPackage, {
version: targetVersion,
addToPackageJson: false,
});
const migrations = yield this._createMigrateJson(packageJson);
return { packageJson, migrations };
});
}
_createMigrateJson(versions) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const migrations = yield Promise.all(Object.keys(versions).map((packageName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const currentVersion = this.versions(packageName);
if (currentVersion === null)
return [];
const { version } = versions[packageName];
const { generators } = yield this.fetch(packageName, version);
if (!generators)
return [];
return Object.entries(generators)
.filter(([, migration]) => migration.version &&
this.gt(migration.version, currentVersion) &&
this.lte(migration.version, version))
.map(([migrationName, migration]) => (Object.assign(Object.assign({}, migration), { package: packageName, name: migrationName })));
})));
return migrations.flat();
});
}
_updatePackageJson(targetPackage, target) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
let targetVersion = target.version;
if (this.to[targetPackage]) {
targetVersion = this.to[targetPackage];
}
if (!this.versions(targetPackage)) {
return {
[targetPackage]: {
version: target.version,
addToPackageJson: target.addToPackageJson || false,
},
};
}
let migrationsJson;
try {
migrationsJson = yield this.fetch(targetPackage, targetVersion);
targetVersion = migrationsJson.version;
this.collectedVersions[targetPackage] = targetVersion;
}
catch (e) {
if ((_a = e === null || e === void 0 ? void 0 : e.message) === null || _a === void 0 ? void 0 : _a.includes('No matching version')) {
throw new Error(`${e.message}\nRun migrate with --to="package1@version1,package2@version2"`);
}
else {
throw e;
}
}
const packages = this.collapsePackages(targetPackage, targetVersion, migrationsJson);
const childPackageMigrations = yield Promise.all(Object.keys(packages)
.filter((packageName) => !this.collectedVersions[packageName] ||
this.gt(packages[packageName].version, this.collectedVersions[packageName]))
.map((packageName) => this._updatePackageJson(packageName, packages[packageName])));
return childPackageMigrations.reduce((migrations, childMigrations) => {
for (const migrationName of Object.keys(childMigrations)) {
if (!migrations[migrationName] ||
this.gt(childMigrations[migrationName].version, migrations[migrationName].version)) {
migrations[migrationName] = childMigrations[migrationName];
}
}
return migrations;
}, {
[targetPackage]: {
version: migrationsJson.version,
addToPackageJson: target.addToPackageJson || false,
},
});
});
}
collapsePackages(packageName, targetVersion, migration) {
// this should be used to know what version to include
// we should use from everywhere we use versions
var _a;
// Support Migrating to older versions of Nx
// Use the packageGroup of the latest version of Nx instead of the one from the target version which could be older.
if (packageName === '@nrwl/workspace' &&
(0, semver_1.lt)(targetVersion, '14.0.0-beta.0')) {
migration.packageGroup = {
'@nrwl/workspace': targetVersion,
'@nrwl/angular': targetVersion,
'@nrwl/cypress': targetVersion,
'@nrwl/devkit': targetVersion,
'@nrwl/eslint-plugin-nx': targetVersion,
'@nrwl/express': targetVersion,
'@nrwl/jest': targetVersion,
'@nrwl/linter': targetVersion,
'@nrwl/nest': targetVersion,
'@nrwl/next': targetVersion,
'@nrwl/node': targetVersion,
'@nrwl/nx-plugin': targetVersion,
'@nrwl/react': targetVersion,
'@nrwl/storybook': targetVersion,
'@nrwl/web': targetVersion,
'@nrwl/js': targetVersion,
'@nrwl/cli': targetVersion,
'@nrwl/nx-cloud': 'latest',
'@nrwl/react-native': targetVersion,
'@nrwl/detox': targetVersion,
};
}
if (migration.packageGroup) {
(_a = migration.packageJsonUpdates) !== null && _a !== void 0 ? _a : (migration.packageJsonUpdates = {});
const packageGroup = normalizePackageGroup(migration.packageGroup);
migration.packageJsonUpdates[targetVersion + '--PackageGroup'] = {
version: targetVersion,
packages: packageGroup.reduce((acc, packageConfig) => {
const { package: pkg, version } = typeof packageConfig === 'string'
? { package: packageConfig, version: targetVersion }
: packageConfig;
return Object.assign(Object.assign({}, acc), { [pkg]: {
version,
alwaysAddToPackageJson: false,
} });
}, {}),
};
}
if (!migration.packageJsonUpdates || !this.versions(packageName))
return {};
return Object.values(migration.packageJsonUpdates)
.filter(({ version, packages }) => {
return (packages &&
this.gt(version, this.versions(packageName)) &&
this.lte(version, targetVersion));
})
.map(({ packages }) => {
const { dependencies, devDependencies } = this.packageJson;
return Object.entries(packages)
.filter(([packageName, packageUpdate]) => {
return ((!packageUpdate.ifPackageInstalled ||
this.versions(packageUpdate.ifPackageInstalled)) &&
(packageUpdate.alwaysAddToPackageJson ||
packageUpdate.addToPackageJson ||
!!(dependencies === null || dependencies === void 0 ? void 0 : dependencies[packageName]) ||
!!(devDependencies === null || devDependencies === void 0 ? void 0 : devDependencies[packageName])));
})
.reduce((acc, [packageName, packageUpdate]) => (Object.assign(Object.assign({}, acc), { [packageName]: {
version: packageUpdate.version,
addToPackageJson: packageUpdate.alwaysAddToPackageJson
? 'dependencies'
: packageUpdate.addToPackageJson || false,
} })), {});
})
.reduce((m, c) => (Object.assign(Object.assign({}, m), c)), {});
}
gt(v1, v2) {
return (0, semver_1.gt)(normalizeVersion(v1), normalizeVersion(v2));
}
lte(v1, v2) {
return (0, semver_1.lte)(normalizeVersion(v1), normalizeVersion(v2));
}
}
exports.Migrator = Migrator;
function normalizePackageGroup(packageGroup) {
if (!Array.isArray(packageGroup)) {
return Object.entries(packageGroup).map(([pkg, version]) => ({
package: pkg,
version,
}));
}
return packageGroup;
}
function normalizeVersionWithTagCheck(version) {
if (version === 'latest' || version === 'next')
return version;
return normalizeVersion(version);
}
function versionOverrides(overrides, param) {
const res = {};
overrides.split(',').forEach((p) => {
const split = p.lastIndexOf('@');
if (split === -1 || split === 0) {
throw new Error(`Incorrect '${param}' section. Use --${param}="package@version"`);
}
const selectedPackage = p.substring(0, split).trim();
const selectedVersion = p.substring(split + 1).trim();
if (!selectedPackage || !selectedVersion) {
throw new Error(`Incorrect '${param}' section. Use --${param}="package@version"`);
}
res[normalizeSlashes(selectedPackage)] =
normalizeVersionWithTagCheck(selectedVersion);
});
return res;
}
function parseTargetPackageAndVersion(args) {
if (!args) {
throw new Error(`Provide the correct package name and version. E.g., my-package@9.0.0.`);
}
if (args.indexOf('@') > -1) {
const i = args.lastIndexOf('@');
if (i === 0) {
const targetPackage = args.trim();
const targetVersion = 'latest';
return { targetPackage, targetVersion };
}
else {
const targetPackage = args.substring(0, i);
const maybeVersion = args.substring(i + 1);
if (!targetPackage || !maybeVersion) {
throw new Error(`Provide the correct package name and version. E.g., my-package@9.0.0.`);
}
const targetVersion = normalizeVersionWithTagCheck(maybeVersion);
return { targetPackage, targetVersion };
}
}
else {
if (args === 'latest' ||
args === 'next' ||
(0, semver_1.valid)(args) ||
args.match(/^\d+(?:\.\d+)?(?:\.\d+)?$/)) {
const targetVersion = normalizeVersionWithTagCheck(args);
const targetPackage = !['latest', 'next'].includes(args) && (0, semver_1.lt)(targetVersion, '14.0.0-beta.0')
? '@nrwl/workspace'
: 'nx';
return {
targetPackage,
targetVersion,
};
}
else {
return {
targetPackage: args,
targetVersion: 'latest',
};
}
}
}
function parseMigrationsOptions(options) {
if (options.runMigrations === '') {
options.runMigrations = 'migrations.json';
}
if (!options.runMigrations) {
const from = options.from
? versionOverrides(options.from, 'from')
: {};
const to = options.to ? versionOverrides(options.to, 'to') : {};
const { targetPackage, targetVersion } = parseTargetPackageAndVersion(options['packageAndVersion']);
return {
type: 'generateMigrations',
targetPackage: normalizeSlashes(targetPackage),
targetVersion,
from,
to,
};
}
else {
return {
type: 'runMigrations',
runMigrations: options.runMigrations,
};
}
}
exports.parseMigrationsOptions = parseMigrationsOptions;
function versions(root, from) {
const cache = {};
function getFromVersion(packageName) {
try {
if (from[packageName]) {
return from[packageName];
}
if (!cache[packageName]) {
const { packageJson } = (0, package_json_1.readModulePackageJson)(packageName, [root]);
cache[packageName] = packageJson.version;
}
return cache[packageName];
}
catch (_a) {
// Support migrating old workspaces without nx package
if (packageName === 'nx') {
return getFromVersion('@nrwl/workspace');
}
return null;
}
}
return getFromVersion;
}
// testing-fetch-start
function createFetcher() {
const migrationsCache = {};
const resolvedVersionCache = {};
function fetchMigrations(packageName, packageVersion, setCache) {
const cacheKey = packageName + '-' + packageVersion;
return Promise.resolve(resolvedVersionCache[cacheKey])
.then((cachedResolvedVersion) => {
if (cachedResolvedVersion) {
return cachedResolvedVersion;
}
resolvedVersionCache[cacheKey] = (0, package_manager_1.resolvePackageVersionUsingRegistry)(packageName, packageVersion);
return resolvedVersionCache[cacheKey];
})
.then((resolvedVersion) => {
if (resolvedVersion !== packageVersion &&
migrationsCache[`${packageName}-${resolvedVersion}`]) {
return migrationsCache[`${packageName}-${resolvedVersion}`];
}
setCache(packageName, resolvedVersion);
return getPackageMigrationsUsingRegistry(packageName, resolvedVersion);
})
.catch(() => {
logger_1.logger.info(`Fetching ${packageName}@${packageVersion}`);
return getPackageMigrationsUsingInstall(packageName, packageVersion);
});
}
return function nxMigrateFetcher(packageName, packageVersion) {
if (migrationsCache[`${packageName}-${packageVersion}`]) {
return migrationsCache[`${packageName}-${packageVersion}`];
}
let resolvedVersion = packageVersion;
let migrations;
function setCache(packageName, packageVersion) {
migrationsCache[packageName + '-' + packageVersion] = migrations;
}
migrations = fetchMigrations(packageName, packageVersion, setCache).then((result) => {
if (result.schematics) {
result.generators = result.schematics;
delete result.schematics;
}
resolvedVersion = result.version;
return result;
});
setCache(packageName, packageVersion);
return migrations;
};
}
// testing-fetch-end
function getPackageMigrationsUsingRegistry(packageName, packageVersion) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
// check if there are migrations in the packages by looking at the
// registry directly
const migrationsConfig = yield getPackageMigrationsConfigFromRegistry(packageName, packageVersion);
if (!migrationsConfig) {
return {
version: packageVersion,
};
}
if (!migrationsConfig.migrations) {
return {
version: packageVersion,
packageGroup: migrationsConfig.packageGroup,
};
}
logger_1.logger.info(`Fetching ${packageName}@${packageVersion}`);
// try to obtain the migrations from the registry directly
return yield downloadPackageMigrationsFromRegistry(packageName, packageVersion, migrationsConfig);
});
}
function getPackageMigrationsConfigFromRegistry(packageName, packageVersion) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const result = yield (0, package_manager_1.packageRegistryView)(packageName, packageVersion, 'nx-migrations ng-update --json');
if (!result) {
return null;
}
return (0, package_json_1.readNxMigrateConfig)(JSON.parse(result));
});
}
function downloadPackageMigrationsFromRegistry(packageName, packageVersion, { migrations: migrationsFilePath, packageGroup }) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { dir, cleanup } = (0, package_manager_1.createTempNpmDirectory)();
let result;
try {
const { tarballPath } = yield (0, package_manager_1.packageRegistryPack)(dir, packageName, packageVersion);
const migrations = yield (0, fileutils_1.extractFileFromTarball)((0, path_1.join)(dir, tarballPath), (0, path_1.join)('package', migrationsFilePath), (0, path_1.join)(dir, migrationsFilePath)).then((path) => (0, fileutils_1.readJsonFile)(path));
result = Object.assign(Object.assign({}, migrations), { packageGroup, version: packageVersion });
}
catch (_a) {
throw new Error(`Failed to find migrations file "${migrationsFilePath}" in package "${packageName}@${packageVersion}".`);
}
finally {
yield cleanup();
}
return result;
});
}
function getPackageMigrationsUsingInstall(packageName, packageVersion) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { dir, cleanup } = (0, package_manager_1.createTempNpmDirectory)();
let result;
try {
const pmc = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(dir));
yield execAsync(`${pmc.add} ${packageName}@${packageVersion}`, {
cwd: dir,
});
const { migrations: migrationsFilePath, packageGroup, packageJson, } = readPackageMigrationConfig(packageName, dir);
let migrations = undefined;
if (migrationsFilePath) {
migrations = (0, fileutils_1.readJsonFile)(migrationsFilePath);
}
result = Object.assign(Object.assign({}, migrations), { packageGroup, version: packageJson.version });
}
finally {
yield cleanup();
}
return result;
});
}
function readPackageMigrationConfig(packageName, dir) {
const { path: packageJsonPath, packageJson: json } = (0, package_json_1.readModulePackageJson)(packageName, [dir]);
const migrationConfigOrFile = json['nx-migrations'] || json['ng-update'];
if (!migrationConfigOrFile) {
return { packageJson: json, migrations: null, packageGroup: [] };
}
const migrationsConfig = typeof migrationConfigOrFile === 'string'
? {
migrations: migrationConfigOrFile,
packageGroup: [],
}
: migrationConfigOrFile;
try {
const migrationFile = require.resolve(migrationsConfig.migrations, {
paths: [(0, path_1.dirname)(packageJsonPath)],
});
return {
packageJson: json,
migrations: migrationFile,
packageGroup: migrationsConfig.packageGroup,
};
}
catch (_a) {
return {
packageJson: json,
migrations: null,
packageGroup: migrationsConfig.packageGroup,
};
}
}
function createMigrationsFile(root, migrations) {
(0, fileutils_1.writeJsonFile)((0, path_1.join)(root, 'migrations.json'), { migrations });
}
function updatePackageJson(root, updatedPackages) {
const packageJsonPath = (0, path_1.join)(root, 'package.json');
const parseOptions = {};
const json = (0, fileutils_1.readJsonFile)(packageJsonPath, parseOptions);
Object.keys(updatedPackages).forEach((p) => {
var _a, _b, _c;
if ((_a = json.devDependencies) === null || _a === void 0 ? void 0 : _a[p]) {
json.devDependencies[p] = updatedPackages[p].version;
return;
}
if ((_b = json.dependencies) === null || _b === void 0 ? void 0 : _b[p]) {
json.dependencies[p] = updatedPackages[p].version;
return;
}
const dependencyType = updatedPackages[p].addToPackageJson;
if (typeof dependencyType === 'string') {
(_c = json[dependencyType]) !== null && _c !== void 0 ? _c : (json[dependencyType] = {});
json[dependencyType][p] = updatedPackages[p].version;
}
});
(0, fileutils_1.writeJsonFile)(packageJsonPath, json, {
appendNewLine: parseOptions.endsWithNewline,
});
}
function isMigratingToNewMajor(from, to) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
from = normalizeVersion(from);
to = ['latest', 'next'].includes(to) ? to : normalizeVersion(to);
if (!(0, semver_1.valid)(from)) {
from = yield (0, package_manager_1.resolvePackageVersionUsingRegistry)('nx', from);
}
if (!(0, semver_1.valid)(to)) {
to = yield (0, package_manager_1.resolvePackageVersionUsingRegistry)('nx', to);
}
return (0, semver_1.major)(from) < (0, semver_1.major)(to);
});
}
function readNxVersion(packageJson) {
var _a, _b, _c, _d, _e, _f, _g;
return ((_f = (_d = (_b = (_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.devDependencies) === null || _a === void 0 ? void 0 : _a['nx']) !== null && _b !== void 0 ? _b : (_c = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _c === void 0 ? void 0 : _c['nx']) !== null && _d !== void 0 ? _d : (_e = packageJson === null || packageJson === void 0 ? void 0 : packageJson.devDependencies) === null || _e === void 0 ? void 0 : _e['@nrwl/workspace']) !== null && _f !== void 0 ? _f : (_g = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _g === void 0 ? void 0 : _g['@nrwl/workspace']);
}
function generateMigrationsJsonAndUpdatePackageJson(root, opts) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const pmc = (0, package_manager_1.getPackageManagerCommand)();
try {
let originalPackageJson = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, 'package.json'));
try {
if (['nx', '@nrwl/workspace'].includes(opts.targetPackage) &&
(yield isMigratingToNewMajor(readNxVersion(originalPackageJson), opts.targetVersion))) {
yield (0, connect_to_nx_cloud_1.connectToNxCloudCommand)('We noticed you are migrating to a new major version, but are not taking advantage of Nx Cloud. Nx Cloud can make your CI up to 10 times faster. Learn more about it here: nx.app. Would you like to add it?');
originalPackageJson = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, 'package.json'));
}
}
catch (_a) {
// The above code is to remind folks when updating to a new major and not currently using Nx cloud.
// If for some reason it fails, it shouldn't affect the overall migration process
}
logger_1.logger.info(`Fetching meta data about packages.`);
logger_1.logger.info(`It may take a few minutes.`);
const migrator = new Migrator({
packageJson: originalPackageJson,
versions: versions(root, opts.from),
fetch: createFetcher(),
to: opts.to,
});
const { migrations, packageJson } = yield migrator.updatePackageJson(opts.targetPackage, opts.targetVersion);
updatePackageJson(root, packageJson);
if (migrations.length > 0) {
createMigrationsFile(root, migrations);
}
output_1.output.success({
title: `The migrate command has run successfully.`,
bodyLines: [
`- Package.json has been updated.`,
migrations.length > 0
? `- Migrations.json has been generated.`
: `- There are no migrations to run, so migrations.json has not been created.`,
],
});
output_1.output.log({
title: 'Next steps:',
bodyLines: [
`- Make sure package.json changes make sense and then run '${pmc.install}',`,
...(migrations.length > 0
? [`- Run '${pmc.exec} nx migrate --run-migrations'`]
: []),
`- To learn more go to https://nx.dev/using-nx/updating-nx`,
...(showConnectToCloudMessage()
? [
`- You may run '${pmc.run('nx', 'connect-to-nx-cloud')}' to get faster builds, GitHub integration, and more. Check out https://nx.app`,
]
: []),
],
});
}
catch (e) {
output_1.output.error({
title: `The migrate command failed.`,
});
throw e;
}
});
}
function showConnectToCloudMessage() {
try {
const nxJson = (0, fileutils_1.readJsonFile)('nx.json');
const defaultRunnerIsUsed = !nxJson.tasksRunnerOptions ||
Object.values(nxJson.tasksRunnerOptions).find((r) => r.runner == '@nrwl/workspace/tasks-runners/default' ||
r.runner == 'nx/tasks-runners/default');
return !!defaultRunnerIsUsed;
}
catch (_a) {
return false;
}
}
function runInstall() {
const pmCommands = (0, package_manager_1.getPackageManagerCommand)();
output_1.output.log({
title: `Running '${pmCommands.install}' to make sure necessary packages are installed`,
});
(0, child_process_1.execSync)(pmCommands.install, { stdio: [0, 1, 2] });
}
function executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const depsBeforeMigrations = getStringifiedPackageJsonDeps(root);
const migrationsWithNoChanges = [];
for (const m of migrations) {
try {
if (m.cli === 'nx') {
const changes = yield runNxMigration(root, m.package, m.name);
if (changes.length < 1) {
migrationsWithNoChanges.push(m);
// If no changes are made, continue on without printing anything
continue;
}
logger_1.logger.info(`Ran ${m.name} from ${m.package}`);
logger_1.logger.info(` ${m.description}\n`);
(0, tree_1.printChanges)(changes, ' ');
}
else {
const { madeChanges, loggingQueue } = yield (yield Promise.resolve().then(() => require('../adapter/ngcli-adapter'))).runMigration(root, m.package, m.name, isVerbose);
if (!madeChanges) {
migrationsWithNoChanges.push(m);
// If no changes are made, continue on without printing anything
continue;
}
logger_1.logger.info(`Ran ${m.name} from ${m.package}`);
logger_1.logger.info(` ${m.description}\n`);
loggingQueue.forEach((log) => logger_1.logger.info(' ' + log));
}
if (shouldCreateCommits) {
const commitMessage = `${commitPrefix}${m.name}`;
try {
const committedSha = commitChanges(commitMessage);
if (committedSha) {
logger_1.logger.info(chalk.dim(`- Commit created for changes: ${committedSha}`));
}
else {
logger_1.logger.info(chalk.red(`- A commit could not be created/retrieved for an unknown reason`));
}
}
catch (e) {
logger_1.logger.info(chalk.red(`- ${e.message}`));
}
}
logger_1.logger.info(`---------------------------------------------------------`);
}
catch (e) {
output_1.output.error({
title: `Failed to run ${m.name} from ${m.package}. This workspace is NOT up to date!`,
});
throw e;
}
}
const depsAfterMigrations = getStringifiedPackageJsonDeps(root);
if (depsBeforeMigrations !== depsAfterMigrations) {
runInstall();
}
return migrationsWithNoChanges;
});
}
exports.executeMigrations = executeMigrations;
function runMigrations(root, opts, isVerbose, shouldCreateCommits = false, commitPrefix) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!process.env.NX_MIGRATE_SKIP_INSTALL) {
runInstall();
}
output_1.output.log({
title: `Running migrations from '${opts.runMigrations}'` +
(shouldCreateCommits ? ', with each applied in a dedicated commit' : ''),
});
const migrations = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, opts.runMigrations)).migrations;
const migrationsWithNoChanges = yield executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix);
if (migrationsWithNoChanges.length < migrations.length) {
output_1.output.success({
title: `Successfully finished running migrations from '${opts.runMigrations}'. This workspace is up to date!`,
});
}
else {
output_1.output.success({
title: `No changes were made from running '${opts.runMigrations}'. This workspace is up to date!`,
});
}
});
}
function getStringifiedPackageJsonDeps(root) {
const { dependencies, devDependencies } = (0, fileutils_1.readJsonFile)((0, path_1.join)(root, 'package.json'));
return JSON.stringify([dependencies, devDependencies]);
}
function commitChanges(commitMessage) {
try {
(0, child_process_1.execSync)('git add -A', { encoding: 'utf8', stdio: 'pipe' });
(0, child_process_1.execSync)('git commit --no-verify -F -', {
encoding: 'utf8',
stdio: 'pipe',
input: commitMessage,
});
}
catch (err) {
throw new Error(`Error committing changes:\n${err.stderr}`);
}
return getLatestCommitSha();
}
function getLatestCommitSha() {
try {
return (0, child_process_1.execSync)('git rev-parse HEAD', {
encoding: 'utf8',
stdio: 'pipe',
}).trim();
}
catch (_a) {
return null;
}
}
function runNxMigration(root, packageName, name) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const collectionPath = readPackageMigrationConfig(packageName, root).migrations;
const collection = (0, fileutils_1.readJsonFile)(collectionPath);
const g = collection.generators || collection.schematics;
if (!g[name]) {
const source = collection.generators ? 'generators' : 'schematics';
throw new Error(`Unable to determine implementation path for "${collectionPath}:${name}" using collection.${source}`);
}
const implRelativePath = g[name].implementation || g[name].factory;
let implPath;
try {
implPath = require.resolve(implRelativePath, {
paths: [(0, path_1.dirname)(collectionPath)],
});
}
catch (e) {
// workaround for a bug in node 12
implPath = require.resolve(`${(0, path_1.dirname)(collectionPath)}/${implRelativePath}`);
}
const fn = require(implPath).default;
const host = new tree_1.FsTree(root, false);
yield fn(host, {});
const changes = host.listChanges();
(0, tree_1.flushChanges)(root, changes);
return changes;
});
}
function migrate(root, args) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
return (0, params_1.handleErrors)(args['verbose'], () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const opts = parseMigrationsOptions(args);
if (opts.type === 'generateMigrations') {
yield generateMigrationsJsonAndUpdatePackageJson(root, opts);
}
else {
yield runMigrations(root, opts, args['verbose'], args['createCommits'], args['commitPrefix']);
}
}));
});
}
exports.migrate = migrate;
//# sourceMappingURL=migrate.js.map
;