Skip to content

Commit ba3d031

Browse files
committed
fix(@schematics/update): fix logic to coerce the version number
And add unit tests for it.
1 parent b6e638c commit ba3d031

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

packages/schematics/update/migrate/index.ts

+35-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,36 @@ import * as semver from 'semver';
1818
import { PostUpdateSchema } from './schema';
1919

2020

21+
/**
22+
* Cleans up "short" version numbers so they become valid semver. For example;
23+
* 1 => 1.0.0
24+
* 1.2 => 1.2.0
25+
* 1-beta => 1.0.0-beta
26+
*
27+
* Exported for testing only.
28+
* @internal
29+
*/
30+
export function _coerceVersionNumber(version: string): string | null {
31+
if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}/)) {
32+
const match = version.match(/^\d{1,30}(\.\d{1,30})*/);
33+
34+
if (!match) {
35+
return null;
36+
}
37+
38+
if (!match[1]) {
39+
version = version.substr(0, match[0].length) + '.0.0' + version.substr(match[0].length);
40+
} else if (!match[2]) {
41+
version = version.substr(0, match[0].length) + '.0' + version.substr(match[0].length);
42+
} else {
43+
return null;
44+
}
45+
}
46+
47+
return semver.valid(version);
48+
}
49+
50+
2151
export default function(options: PostUpdateSchema): Rule {
2252
return (tree: Tree, context: SchematicContext) => {
2353
const schematicsToRun: { name: string; version: string; }[] = [];
@@ -28,16 +58,12 @@ export default function(options: PostUpdateSchema): Rule {
2858
const schematic = collection.createSchematic(name, true);
2959

3060
const description: JsonObject = schematic.description as JsonObject;
61+
let version = description['version'];
3162

32-
if (typeof description['version'] == 'string') {
33-
let version = description['version'] as string;
34-
if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}$/)) {
35-
version += '.0';
36-
}
37-
if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}$/)) {
38-
version += '.0';
39-
}
40-
if (!semver.valid(version)) {
63+
if (typeof version == 'string') {
64+
version = _coerceVersionNumber(version);
65+
66+
if (!version) {
4167
throw new SchematicsException(
4268
`Invalid migration version: ${JSON.stringify(description['version'])}`,
4369
);

packages/schematics/update/migrate/index_spec.ts

+27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { virtualFs } from '@angular-devkit/core';
99
import { HostTree } from '@angular-devkit/schematics';
1010
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
1111
import { map } from 'rxjs/operators';
12+
import { _coerceVersionNumber } from './index';
1213

1314

1415
describe('@schematics/update:migrate', () => {
@@ -56,3 +57,29 @@ describe('@schematics/update:migrate', () => {
5657
).toPromise().then(done, done.fail);
5758
});
5859
});
60+
61+
62+
describe('_coerceVersionNumber', () => {
63+
const testCases: { [expected: string]: string | null } = {
64+
'1': '1.0.0',
65+
'1.2': '1.2.0',
66+
'1.2.3': '1.2.3',
67+
'1-beta.0': '1.0.0-beta.0',
68+
'1.2-beta.0': '1.2.0-beta.0',
69+
'1.2.3-beta.0': '1.2.3-beta.0',
70+
'a': null,
71+
'1.a': null,
72+
'1a': null,
73+
'1.': null,
74+
'1.-beta.0': null,
75+
};
76+
77+
Object.keys(testCases).forEach(input => {
78+
const expected = testCases[input];
79+
it(`${JSON.stringify(input)} => ${JSON.stringify(expected)}`, () => {
80+
const actual = _coerceVersionNumber(input);
81+
82+
expect(actual).toBe(expected);
83+
});
84+
});
85+
});

0 commit comments

Comments
 (0)