Skip to content

Commit f61b2be

Browse files
committed
fix(@schematics/update): respect caret and tilde ranges
Fix #10356
1 parent e335e5d commit f61b2be

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

packages/schematics/update/update/index.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { map, mergeMap, reduce, switchMap } from 'rxjs/operators';
1919
import * as semver from 'semver';
2020
import { getNpmPackageJson } from './npm';
2121
import { NpmRepositoryPackageJson } from './npm-package-json';
22-
import { JsonSchemaForNpmPackageJsonFiles } from './package-json';
22+
import { Dependency, JsonSchemaForNpmPackageJsonFiles } from './package-json';
2323
import { UpdateSchema } from './schema';
2424

2525
type VersionRange = string & { __VERSION_RANGE: void; };
@@ -220,6 +220,13 @@ function _performUpdate(
220220
throw new SchematicsException('package.json could not be parsed: ' + e.message);
221221
}
222222

223+
const updateDependency = (deps: Dependency, name: string, newVersion: string) => {
224+
const oldVersion = deps[name];
225+
// We only respect caret and tilde ranges on update.
226+
const execResult = /^[\^~]/.exec(oldVersion);
227+
deps[name] = `${execResult ? execResult[0] : ''}${newVersion}`;
228+
};
229+
223230
const toInstall = [...infoMap.values()]
224231
.map(x => [x.name, x.target, x.installed])
225232
// tslint:disable-next-line:non-null-operator
@@ -234,7 +241,7 @@ function _performUpdate(
234241
);
235242

236243
if (packageJson.dependencies && packageJson.dependencies[name]) {
237-
packageJson.dependencies[name] = target.version;
244+
updateDependency(packageJson.dependencies, name, target.version);
238245

239246
if (packageJson.devDependencies && packageJson.devDependencies[name]) {
240247
delete packageJson.devDependencies[name];
@@ -243,13 +250,13 @@ function _performUpdate(
243250
delete packageJson.peerDependencies[name];
244251
}
245252
} else if (packageJson.devDependencies && packageJson.devDependencies[name]) {
246-
packageJson.devDependencies[name] = target.version;
253+
updateDependency(packageJson.devDependencies, name, target.version);
247254

248255
if (packageJson.peerDependencies && packageJson.peerDependencies[name]) {
249256
delete packageJson.peerDependencies[name];
250257
}
251258
} else if (packageJson.peerDependencies && packageJson.peerDependencies[name]) {
252-
packageJson.peerDependencies[name] = target.version;
259+
updateDependency(packageJson.peerDependencies, name, target.version);
253260
} else {
254261
logger.warn(`Package ${name} was not found in dependencies.`);
255262
}

packages/schematics/update/update/index_spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ describe('@schematics/update', () => {
5252
).subscribe(undefined, done.fail, done);
5353
}, 45000);
5454

55+
it('respects existing tilde and caret ranges', done => {
56+
// Add ranges.
57+
const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json')));
58+
const packageJson = JSON.parse(content);
59+
packageJson['dependencies']['@angular-devkit-tests/update-base'] = '^1.0.0';
60+
packageJson['dependencies']['@angular-devkit-tests/update-migrations'] = '~1.0.0';
61+
host.sync.write(
62+
normalize('/package.json'),
63+
virtualFs.stringToFileBuffer(JSON.stringify(packageJson)),
64+
);
65+
66+
schematicRunner.runSchematicAsync('update', { all: true }, appTree).pipe(
67+
map(tree => {
68+
const packageJson = JSON.parse(tree.readContent('/package.json'));
69+
// This one should not change because 1.1.0 was already satisfied by ^1.0.0.
70+
expect(packageJson['dependencies']['@angular-devkit-tests/update-base']).toBe('^1.0.0');
71+
expect(packageJson['dependencies']['@angular-devkit-tests/update-migrations'])
72+
.toBe('~1.6.0');
73+
}),
74+
).subscribe(undefined, done.fail, done);
75+
}, 45000);
76+
5577
it('calls migration tasks', done => {
5678
// Add the basic migration package.
5779
const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json')));

0 commit comments

Comments
 (0)