Skip to content

Commit a18b40d

Browse files
committed
feat(@schematics/update): add packageGroup version map support
Fixes #13015
1 parent a3e3bb2 commit a18b40d

File tree

5 files changed

+111
-14
lines changed

5 files changed

+111
-14
lines changed

packages/schematics/update/update/index.ts

+40-14
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ interface PackageInfo {
7676
}
7777

7878
interface UpdateMetadata {
79-
packageGroup: string[];
79+
packageGroupName?: string;
80+
packageGroup: { [ packageName: string ]: string };
8081
requirements: { [packageName: string]: string };
8182
migrations?: string;
8283
}
@@ -88,9 +89,9 @@ function _updatePeerVersion(infoMap: Map<string, PackageInfo>, name: string, ran
8889
return range;
8990
}
9091
if (maybePackageInfo.target) {
91-
name = maybePackageInfo.target.updateMetadata.packageGroup[0] || name;
92+
name = maybePackageInfo.target.updateMetadata.packageGroupName || name;
9293
} else {
93-
name = maybePackageInfo.installed.updateMetadata.packageGroup[0] || name;
94+
name = maybePackageInfo.installed.updateMetadata.packageGroupName || name;
9495
}
9596

9697
const maybeTransform = peerCompatibleWhitelist[name];
@@ -353,7 +354,7 @@ function _getUpdateMetadata(
353354
const metadata = packageJson['ng-update'];
354355

355356
const result: UpdateMetadata = {
356-
packageGroup: [],
357+
packageGroup: {},
357358
requirements: {},
358359
};
359360

@@ -363,17 +364,30 @@ function _getUpdateMetadata(
363364

364365
if (metadata['packageGroup']) {
365366
const packageGroup = metadata['packageGroup'];
366-
// Verify that packageGroup is an array of strings. This is not an error but we still warn
367-
// the user and ignore the packageGroup keys.
368-
if (!Array.isArray(packageGroup) || packageGroup.some(x => typeof x != 'string')) {
367+
// Verify that packageGroup is an array of strings or an map of versions. This is not an error
368+
// but we still warn the user and ignore the packageGroup keys.
369+
if (Array.isArray(packageGroup) && packageGroup.every(x => typeof x == 'string')) {
370+
result.packageGroup = packageGroup.reduce((group, name) => {
371+
group[name] = packageJson.version;
372+
373+
return group;
374+
}, result.packageGroup);
375+
} else if (typeof packageGroup == 'object' && packageGroup
376+
&& Object.values(packageGroup).every(x => typeof x == 'string')) {
377+
result.packageGroup = packageGroup;
378+
} else {
369379
logger.warn(
370380
`packageGroup metadata of package ${packageJson.name} is malformed. Ignoring.`,
371381
);
372-
} else {
373-
result.packageGroup = packageGroup;
374382
}
375383
}
376384

385+
if (typeof metadata['packageGroupName'] == 'string') {
386+
result.packageGroupName = metadata['packageGroupName'];
387+
} else {
388+
result.packageGroupName = Object.keys(result.packageGroup)[0];
389+
}
390+
377391
if (metadata['requirements']) {
378392
const requirements = metadata['requirements'];
379393
// Verify that requirements are
@@ -654,22 +668,34 @@ function _addPackageGroup(
654668
return;
655669
}
656670

657-
const packageGroup = ngUpdateMetadata['packageGroup'];
671+
let packageGroup = ngUpdateMetadata['packageGroup'];
658672
if (!packageGroup) {
659673
return;
660674
}
661-
if (!Array.isArray(packageGroup) || packageGroup.some(x => typeof x != 'string')) {
675+
if (Array.isArray(packageGroup) && !packageGroup.some(x => typeof x != 'string')) {
676+
packageGroup = packageGroup.reduce((acc, curr) => {
677+
acc[curr] = maybePackage;
678+
679+
return acc;
680+
}, {} as { [name: string]: string });
681+
}
682+
683+
// Only need to check if it's an object because we set it right the time before.
684+
if (typeof packageGroup != 'object'
685+
|| packageGroup === null
686+
|| Object.values(packageGroup).some(v => typeof v != 'string')
687+
) {
662688
logger.warn(`packageGroup metadata of package ${npmPackageJson.name} is malformed.`);
663689

664690
return;
665691
}
666692

667-
packageGroup
693+
Object.keys(packageGroup)
668694
.filter(name => !packages.has(name)) // Don't override names from the command line.
669695
.filter(name => allDependencies.has(name)) // Remove packages that aren't installed.
670696
.forEach(name => {
671-
packages.set(name, maybePackage);
672-
});
697+
packages.set(name, packageGroup[name]);
698+
});
673699
}
674700

675701
/**

packages/schematics/update/update/index_spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// tslint:disable:no-big-function
99

1010
import { normalize, virtualFs } from '@angular-devkit/core';
11+
import { createConsoleLogger } from '@angular-devkit/core/node';
1112
import { HostTree } from '@angular-devkit/schematics';
1213
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
1314
import { map } from 'rxjs/operators';
@@ -222,6 +223,40 @@ describe('@schematics/update', () => {
222223
).toPromise().then(done, done.fail);
223224
}, 45000);
224225

226+
it('uses packageGroup for versioning', async () => {
227+
// Add the basic migration package.
228+
const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json')));
229+
const packageJson = JSON.parse(content);
230+
const dependencies = packageJson['dependencies'];
231+
dependencies['@angular-devkit-tests/update-package-group-1'] = '1.0.0';
232+
dependencies['@angular-devkit-tests/update-package-group-2'] = '1.0.0';
233+
host.sync.write(
234+
normalize('/package.json'),
235+
virtualFs.stringToFileBuffer(JSON.stringify(packageJson)),
236+
);
237+
238+
await schematicRunner.runSchematicAsync('update', {
239+
packages: ['@angular-devkit-tests/update-package-group-1'],
240+
}, appTree).pipe(
241+
map(tree => {
242+
const packageJson = JSON.parse(tree.readContent('/package.json'));
243+
const deps = packageJson['dependencies'];
244+
expect(deps['@angular-devkit-tests/update-package-group-1']).toBe('1.2.0');
245+
expect(deps['@angular-devkit-tests/update-package-group-2']).toBe('2.0.0');
246+
247+
// Check install task.
248+
expect(schematicRunner.tasks).toEqual([
249+
{
250+
name: 'node-package',
251+
options: jasmine.objectContaining({
252+
command: 'install',
253+
}),
254+
},
255+
]);
256+
}),
257+
).toPromise();
258+
}, 45000);
259+
225260
it('can migrate only', done => {
226261
// Add the basic migration package.
227262
const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json')));
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
## Update Package Group packages
3+
4+
* `[email protected]` -> `update-package-group2@^1`
5+
6+
----
7+
8+
* `[email protected]` -> `update-package-group2@^1`
9+
10+
----
11+
12+
* `[email protected]` -> `update-package-group2@^2`
13+
* `[email protected]` -> `update-package-group1@^1`
14+
----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@angular-devkit-tests/update-package-group-1",
3+
"version": "1.2.0",
4+
"description": "Tests",
5+
"ng-update": {
6+
"packageGroup": {
7+
"@angular-devkit-tests/update-package-group-1": "",
8+
"@angular-devkit-tests/update-package-group-2": "^2"
9+
}
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@angular-devkit-tests/update-package-group-2",
3+
"version": "2.0.0",
4+
"description": "Tests",
5+
"ng-update": {
6+
"packageGroup": {
7+
"@angular-devkit-tests/update-package-group-1": "^1",
8+
"@angular-devkit-tests/update-package-group-2": ""
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)