Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions packages/angular/cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ RUNTIME_ASSETS = glob(
include = [
"bin/**/*",
"src/**/*.md",
"src/**/*.json",
],
exclude = [
"lib/config/workspace-schema.json",
Expand All @@ -53,7 +52,6 @@ ts_project(
) + [
# These files are generated from the JSON schema
"//packages/angular/cli:lib/config/workspace-schema.ts",
"//packages/angular/cli:src/commands/update/schematic/schema.ts",
],
data = RUNTIME_ASSETS,
deps = [
Expand Down Expand Up @@ -105,11 +103,6 @@ ts_json_schema(
data = CLI_SCHEMA_DATA,
)

ts_json_schema(
name = "update_schematic_schema",
src = "src/commands/update/schematic/schema.json",
)

ts_project(
name = "angular-cli_test_lib",
testonly = True,
Expand Down
251 changes: 115 additions & 136 deletions packages/angular/cli/src/commands/update/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import type { InstalledPackage, PackageManager, PackageManifest } from '../../pa
import { colors } from '../../utilities/color';
import { disableVersionCheck } from '../../utilities/environment-options';
import { assertIsError } from '../../utilities/error';
import {
UpdatePlan,
applyUpdatePlan,
findPackageJson,
printUpdateUsageMessage,
resolveUserUpdatePlan,
} from './update-resolver';
import {
checkCLIVersion,
coerceVersionNumber,
Expand All @@ -32,12 +39,7 @@ import {
} from './utilities/cli-version';
import { ANGULAR_PACKAGES_REGEXP } from './utilities/constants';
import { checkCleanGit } from './utilities/git';
import {
commitChanges,
executeMigration,
executeMigrations,
executeSchematic,
} from './utilities/migration';
import { commitChanges, executeMigration, executeMigrations } from './utilities/migration';

interface UpdateCommandArgs {
packages?: string[];
Expand All @@ -54,8 +56,6 @@ interface UpdateCommandArgs {

class CommandError extends Error {}

const UPDATE_SCHEMATIC_COLLECTION = path.join(__dirname, 'schematic/collection.json');

export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs> {
override scope = CommandScope.In;
protected override shouldReportAnalytics = false;
Expand Down Expand Up @@ -244,23 +244,28 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
});

if (packages.length === 0) {
// Show status
const { success } = await executeSchematic(
workflow,
logger,
UPDATE_SCHEMATIC_COLLECTION,
'update',
{
force: options.force,
next: options.next,
verbose: options.verbose,
packageManager: packageManager.name,
packages: [],
workspaceRoot: this.context.root,
},
);
try {
const plan = await resolveUserUpdatePlan(
{
force: options.force,
next: options.next,
verbose: options.verbose,
packageManager: packageManager.name,
packages: [],
workspaceRoot: this.context.root,
},
logger,
);

printUpdateUsageMessage(plan.packageInfoMap, logger, options.next);

return success ? 0 : 1;
return 0;
} catch (error) {
assertIsError(error);
logger.error(error.message);

return 1;
}
}

return options.migrateOnly
Expand Down Expand Up @@ -509,128 +514,113 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
return 0;
}

const { success } = await executeSchematic(
workflow,
logger,
UPDATE_SCHEMATIC_COLLECTION,
'update',
{
verbose: options.verbose,
force: options.force,
next: options.next,
packageManager: this.context.packageManager.name,
packages: packagesToUpdate,
workspaceRoot: this.context.root,
},
);

if (success) {
const { root: commandRoot } = this.context;
const ignorePeerDependencies = await shouldForcePackageManager(
packageManager,
let plan: UpdatePlan;
try {
plan = await resolveUserUpdatePlan(
{
packages: packagesToUpdate,
force: options.force,
next: options.next,
packageManager: packageManager.name,
verbose: options.verbose,
workspaceRoot: this.context.root,
},
logger,
options.verbose,
);
const tasks = new Listr([
{
title: 'Cleaning node modules directory',
async task(_, task) {
try {
await fs.rm(path.join(commandRoot, 'node_modules'), {
force: true,
recursive: true,
maxRetries: 3,
});
} catch (e) {
assertIsError(e);
if (e.code === 'ENOENT') {
task.skip('Cleaning not required. Node modules directory not found.');
}
} catch (error) {
assertIsError(error);
logger.error(error.message);

return 1;
}

try {
await applyUpdatePlan(this.context.root, plan, logger);
} catch (error) {
assertIsError(error);
logger.error(`Error updating package.json: ${error.message}`);

return 1;
}

const { root: commandRoot } = this.context;
const ignorePeerDependencies = await shouldForcePackageManager(
packageManager,
logger,
options.verbose,
);
const tasks = new Listr([
{
title: 'Cleaning node modules directory',
async task(_, task) {
try {
await fs.rm(path.join(commandRoot, 'node_modules'), {
force: true,
recursive: true,
maxRetries: 3,
});
} catch (e) {
assertIsError(e);
if (e.code === 'ENOENT') {
task.skip('Cleaning not required. Node modules directory not found.');
}
},
}
},
{
title: 'Installing packages',
async task() {
try {
await packageManager.install({
ignorePeerDependencies,
});
} catch (e) {
throw new CommandError('Unable to install packages');
}
},
},
{
title: 'Installing packages',
async task() {
try {
await packageManager.install({
ignorePeerDependencies,
});
} catch (e) {
throw new CommandError('Unable to install packages');
}
},
]);
try {
await tasks.run();
} catch (e) {
if (e instanceof CommandError) {
return 1;
}

throw e;
},
]);
try {
await tasks.run();
// Clear Node's module resolution path cache to prevent stale lookups
// when resolving migration package paths.
const Module = require('node:module');
if (Module && Module._pathCache) {
Module._pathCache = Object.create(null);
}
} catch (e) {
if (e instanceof CommandError) {
return 1;
}

throw e;
}

if (success && options.createCommits) {
if (options.createCommits) {
if (
!commitChanges(logger, `Angular CLI update for packages - ${packagesToUpdate.join(', ')}`)
) {
return 1;
}
}

// This is a temporary workaround to allow data to be passed back from the update schematic
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const migrations = (global as any).externalMigrations as {
package: string;
collection: string;
from: string;
to: string;
}[];

if (success && migrations) {
const rootRequire = createRequire(this.context.root + '/');
const migrations = plan.migrationsToRun;

if (migrations) {
for (const migration of migrations) {
// Resolve the package from the workspace root, as otherwise it will be resolved from the temp
// installed CLI version.
let packagePath;
logVerbose(
`Resolving migration package '${migration.package}' from '${this.context.root}'...`,
);
try {
try {
packagePath = path.dirname(
// This may fail if the `package.json` is not exported as an entry point
rootRequire.resolve(path.join(migration.package, 'package.json')),
);
} catch (e) {
assertIsError(e);
if (e.code === 'MODULE_NOT_FOUND') {
// Fallback to trying to resolve the package's main entry point
packagePath = rootRequire.resolve(migration.package);
} else {
throw e;
}
}
} catch (e) {
assertIsError(e);
if (e.code === 'MODULE_NOT_FOUND') {
logVerbose(e.toString());
logger.error(
`Migrations for package (${migration.package}) were not found.` +
' The package could not be found in the workspace.',
);
} else {
logger.error(
`Unable to resolve migrations for package (${migration.package}). [${e.message}]`,
);
}
const packageJsonPath = findPackageJson(this.context.root, migration.package);
if (!packageJsonPath) {
logger.error(
`Migrations for package (${migration.package}) were not found.` +
' The package could not be found in the workspace.',
);

return 1;
}

const packagePath = path.dirname(packageJsonPath);
let migrations;
Comment thread
clydin marked this conversation as resolved.

// Check if it is a package-local location
Expand Down Expand Up @@ -673,7 +663,7 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
}
}

return success ? 0 : 1;
return 0;
}
}

Expand All @@ -686,14 +676,3 @@ async function readPackageManifest(manifestPath: string): Promise<PackageManifes
return undefined;
}
}

function findPackageJson(workspaceDir: string, packageName: string): string | undefined {
try {
const projectRequire = createRequire(path.join(workspaceDir, 'package.json'));
const packageJsonPath = projectRequire.resolve(`${packageName}/package.json`);

return packageJsonPath;
} catch {
return undefined;
}
}

This file was deleted.

Loading
Loading