mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 19:13:34 +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 {
|
import {
|
||||||
AngularBuilder,
|
AngularBuilder,
|
||||||
DependencyType,
|
DependencyType,
|
||||||
|
ExistingBehavior,
|
||||||
addDependency,
|
addDependency,
|
||||||
updateWorkspace,
|
updateWorkspace,
|
||||||
} from '@schematics/angular/utility';
|
} from '@schematics/angular/utility';
|
||||||
@ -92,7 +93,10 @@ export default function (options: E2eOptions): Rule {
|
|||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
...E2E_DEV_DEPENDENCIES.map((name) =>
|
...E2E_DEV_DEPENDENCIES.map((name) =>
|
||||||
addDependency(name, latestVersions[name], { type: DependencyType.Dev }),
|
addDependency(name, latestVersions[name], {
|
||||||
|
type: DependencyType.Dev,
|
||||||
|
existing: ExistingBehavior.Skip,
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
addScriptsToPackageJson(),
|
addScriptsToPackageJson(),
|
||||||
]);
|
]);
|
||||||
|
@ -52,6 +52,24 @@ export enum InstallBehavior {
|
|||||||
Always,
|
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
|
* 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
|
* 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}.
|
* Defaults to {@link InstallBehavior.Auto}.
|
||||||
*/
|
*/
|
||||||
install?: InstallBehavior;
|
install?: InstallBehavior;
|
||||||
|
/**
|
||||||
|
* The behavior to use when the dependency already exists within the `package.json`.
|
||||||
|
* Defaults to {@link ExistingBehavior.Replace}.
|
||||||
|
*/
|
||||||
|
existing?: ExistingBehavior;
|
||||||
} = {},
|
} = {},
|
||||||
): Rule {
|
): Rule {
|
||||||
const {
|
const {
|
||||||
type = DependencyType.Default,
|
type = DependencyType.Default,
|
||||||
packageJsonPath = '/package.json',
|
packageJsonPath = '/package.json',
|
||||||
install = InstallBehavior.Auto,
|
install = InstallBehavior.Auto,
|
||||||
|
existing = ExistingBehavior.Replace,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
return (tree, context) => {
|
return (tree, context) => {
|
||||||
@ -113,7 +137,12 @@ export function addDependency(
|
|||||||
|
|
||||||
if (existingSpecifier) {
|
if (existingSpecifier) {
|
||||||
// Already present but different specifier
|
// 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(
|
context.logger.warn(
|
||||||
`Package dependency "${name}" already exists with a different specifier. ` +
|
`Package dependency "${name}" already exists with a different specifier. ` +
|
||||||
`"${existingSpecifier}" will be replaced with "${specifier}".`,
|
`"${existingSpecifier}" will be replaced with "${specifier}".`,
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
callRule,
|
callRule,
|
||||||
chain,
|
chain,
|
||||||
} from '@angular-devkit/schematics';
|
} from '@angular-devkit/schematics';
|
||||||
import { DependencyType, InstallBehavior, addDependency } from './dependency';
|
import { DependencyType, ExistingBehavior, InstallBehavior, addDependency } from './dependency';
|
||||||
|
|
||||||
interface LogEntry {
|
interface LogEntry {
|
||||||
type: 'warn';
|
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();
|
const tree = new EmptyTree();
|
||||||
tree.create(
|
tree.create(
|
||||||
'/package.json',
|
'/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 () => {
|
it('adds a package version with other packages in alphabetical order', async () => {
|
||||||
const tree = new EmptyTree();
|
const tree = new EmptyTree();
|
||||||
tree.create(
|
tree.create(
|
||||||
|
@ -18,4 +18,4 @@ export {
|
|||||||
export { Builders as AngularBuilder } from './workspace-models';
|
export { Builders as AngularBuilder } from './workspace-models';
|
||||||
|
|
||||||
// Package dependency related rules and types
|
// 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