mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 02:54:21 +08:00
fix(@schematics/angular): Allow skipping existing dependencies in E2E schematic
The E2E schematic will now (as it did previously) skip adding dependencies if they already exist within the `package.json` regardless of the specifier. This is accomplished with the `existing` option for the `addDependency` rule which allows defining the behavior for when a dependency already exists. Currently the two option behaviors are skip and replace with replace being the default to retain behavior for existing rule usages.
This commit is contained in:
parent
08ce5670d8
commit
c9b2aa41da
@ -20,6 +20,7 @@ import {
|
||||
import {
|
||||
AngularBuilder,
|
||||
DependencyType,
|
||||
ExistingBehavior,
|
||||
addDependency,
|
||||
updateWorkspace,
|
||||
} from '@schematics/angular/utility';
|
||||
@ -92,7 +93,10 @@ export default function (options: E2eOptions): Rule {
|
||||
]),
|
||||
),
|
||||
...E2E_DEV_DEPENDENCIES.map((name) =>
|
||||
addDependency(name, latestVersions[name], { type: DependencyType.Dev }),
|
||||
addDependency(name, latestVersions[name], {
|
||||
type: DependencyType.Dev,
|
||||
existing: ExistingBehavior.Skip,
|
||||
}),
|
||||
),
|
||||
addScriptsToPackageJson(),
|
||||
]);
|
||||
|
@ -52,6 +52,24 @@ export enum InstallBehavior {
|
||||
Always,
|
||||
}
|
||||
|
||||
/**
|
||||
* An enum used to specify the existing dependency behavior for the {@link addDependency}
|
||||
* schematics rule. The existing behavior affects whether the named dependency will be added
|
||||
* to the `package.json` when the dependency is already present with a differing specifier.
|
||||
*/
|
||||
export enum ExistingBehavior {
|
||||
/**
|
||||
* The dependency will not be added or otherwise changed if it already exists.
|
||||
*/
|
||||
Skip,
|
||||
/**
|
||||
* The dependency's existing specifier will be replaced with the specifier provided in the
|
||||
* {@link addDependency} call. A warning will also be shown during schematic execution to
|
||||
* notify the user of the replacement.
|
||||
*/
|
||||
Replace,
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a package as a dependency to a `package.json`. By default the `package.json` located
|
||||
* at the schematic's root will be used. The `manifestPath` option can be used to explicitly specify
|
||||
@ -88,12 +106,18 @@ export function addDependency(
|
||||
* Defaults to {@link InstallBehavior.Auto}.
|
||||
*/
|
||||
install?: InstallBehavior;
|
||||
/**
|
||||
* The behavior to use when the dependency already exists within the `package.json`.
|
||||
* Defaults to {@link ExistingBehavior.Replace}.
|
||||
*/
|
||||
existing?: ExistingBehavior;
|
||||
} = {},
|
||||
): Rule {
|
||||
const {
|
||||
type = DependencyType.Default,
|
||||
packageJsonPath = '/package.json',
|
||||
install = InstallBehavior.Auto,
|
||||
existing = ExistingBehavior.Replace,
|
||||
} = options;
|
||||
|
||||
return (tree, context) => {
|
||||
@ -113,7 +137,12 @@ export function addDependency(
|
||||
|
||||
if (existingSpecifier) {
|
||||
// Already present but different specifier
|
||||
// This warning may become an error in the future
|
||||
|
||||
if (existing === ExistingBehavior.Skip) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ExistingBehavior.Replace is the only other behavior currently
|
||||
context.logger.warn(
|
||||
`Package dependency "${name}" already exists with a different specifier. ` +
|
||||
`"${existingSpecifier}" will be replaced with "${specifier}".`,
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
callRule,
|
||||
chain,
|
||||
} from '@angular-devkit/schematics';
|
||||
import { DependencyType, InstallBehavior, addDependency } from './dependency';
|
||||
import { DependencyType, ExistingBehavior, InstallBehavior, addDependency } from './dependency';
|
||||
|
||||
interface LogEntry {
|
||||
type: 'warn';
|
||||
@ -63,7 +63,7 @@ describe('addDependency', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('warns if a package is already present with a different specifier', async () => {
|
||||
it('warns if a package is already present with a different specifier by default', async () => {
|
||||
const tree = new EmptyTree();
|
||||
tree.create(
|
||||
'/package.json',
|
||||
@ -85,6 +85,64 @@ describe('addDependency', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('warns if a package is already present with a different specifier with replace behavior', async () => {
|
||||
const tree = new EmptyTree();
|
||||
tree.create(
|
||||
'/package.json',
|
||||
JSON.stringify({
|
||||
dependencies: { '@angular/core': '^13.0.0' },
|
||||
}),
|
||||
);
|
||||
|
||||
const rule = addDependency('@angular/core', '^14.0.0', { existing: ExistingBehavior.Replace });
|
||||
|
||||
const { logs } = await testRule(rule, tree);
|
||||
expect(logs).toContain(
|
||||
jasmine.objectContaining({
|
||||
type: 'warn',
|
||||
message:
|
||||
'Package dependency "@angular/core" already exists with a different specifier. ' +
|
||||
'"^13.0.0" will be replaced with "^14.0.0".',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces the specifier if a package is already present with a different specifier with replace behavior', async () => {
|
||||
const tree = new EmptyTree();
|
||||
tree.create(
|
||||
'/package.json',
|
||||
JSON.stringify({
|
||||
dependencies: { '@angular/core': '^13.0.0' },
|
||||
}),
|
||||
);
|
||||
|
||||
const rule = addDependency('@angular/core', '^14.0.0', { existing: ExistingBehavior.Replace });
|
||||
|
||||
await testRule(rule, tree);
|
||||
|
||||
expect(tree.readJson('/package.json')).toEqual({
|
||||
dependencies: { '@angular/core': '^14.0.0' },
|
||||
});
|
||||
});
|
||||
|
||||
it('does not replace the specifier if a package is already present with a different specifier with skip behavior', async () => {
|
||||
const tree = new EmptyTree();
|
||||
tree.create(
|
||||
'/package.json',
|
||||
JSON.stringify({
|
||||
dependencies: { '@angular/core': '^13.0.0' },
|
||||
}),
|
||||
);
|
||||
|
||||
const rule = addDependency('@angular/core', '^14.0.0', { existing: ExistingBehavior.Skip });
|
||||
|
||||
await testRule(rule, tree);
|
||||
|
||||
expect(tree.readJson('/package.json')).toEqual({
|
||||
dependencies: { '@angular/core': '^13.0.0' },
|
||||
});
|
||||
});
|
||||
|
||||
it('adds a package version with other packages in alphabetical order', async () => {
|
||||
const tree = new EmptyTree();
|
||||
tree.create(
|
||||
|
@ -18,4 +18,4 @@ export {
|
||||
export { Builders as AngularBuilder } from './workspace-models';
|
||||
|
||||
// Package dependency related rules and types
|
||||
export { DependencyType, InstallBehavior, addDependency } from './dependency';
|
||||
export { DependencyType, ExistingBehavior, InstallBehavior, addDependency } from './dependency';
|
||||
|
Loading…
x
Reference in New Issue
Block a user