Skip to content

Commit 68cef2d

Browse files
committed
Added version coercion to the module and CLI.
1 parent ec6f97a commit 68cef2d

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

bin/semver

+12-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var argv = process.argv.slice(2)
1212
, inc = null
1313
, version = require("../package.json").version
1414
, loose = false
15+
, coerce = false
1516
, identifier = undefined
1617
, semver = require("../semver")
1718
, reverse = false
@@ -54,6 +55,9 @@ function main () {
5455
case "-r": case "--range":
5556
range.push(argv.shift())
5657
break
58+
case "-c": case "--coerce":
59+
coerce = true
60+
break
5761
case "-h": case "--help": case "-?":
5862
return help()
5963
default:
@@ -62,8 +66,10 @@ function main () {
6266
}
6367
}
6468

65-
versions = versions.filter(function (v) {
66-
return semver.valid(v, loose)
69+
versions = versions.map(function (v) {
70+
return coerce ? (semver.coerce(v) || {version: v}).version : v
71+
}).filter(function (v) {
72+
return semver.valid(v)
6773
})
6874
if (!versions.length) return fail()
6975
if (inc && (versions.length !== 1 || range.length))
@@ -122,6 +128,10 @@ function help () {
122128
,"-l --loose"
123129
," Interpret versions and ranges loosely"
124130
,""
131+
,"-c --coerce"
132+
," Coerce a string into SemVer if possible"
133+
," (does not imply --loose)"
134+
,""
125135
,"Program exits successfully if any valid version satisfies"
126136
,"all supplied ranges, and prints all satisfying versions."
127137
,""

semver.js

+21
Original file line numberDiff line numberDiff line change
@@ -1294,3 +1294,24 @@ function intersects(r1, r2, loose) {
12941294
r2 = new Range(r2, loose)
12951295
return r1.intersects(r2)
12961296
}
1297+
1298+
exports.coerce = coerce;
1299+
function coerce(version) {
1300+
if (version instanceof SemVer)
1301+
return version
1302+
1303+
if (typeof version !== 'string')
1304+
return null
1305+
1306+
if (version.length > MAX_LENGTH)
1307+
return null;
1308+
1309+
var match = version.match(/([vV]?\d+(?:[.]\d+)*)/)
1310+
if (match == null)
1311+
return null
1312+
1313+
var parts = match[0].split(/[.]/)
1314+
var semver = ['0', '0', '0'].map(function (ph, idx) { return parts[idx] || ph } ).join('.')
1315+
1316+
return parse(semver)
1317+
}

test/coerce.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
var tap = require('tap');
2+
var test = tap.test;
3+
var semver = require('../semver.js');
4+
var coerce = semver.coerce;
5+
6+
test('\ncoerce tests', function(t) {
7+
var tooLong = '123' + '.1'.repeat(127);
8+
var justRight = '12' + '.1'.repeat(127);
9+
10+
// Expected to be null (cannot be coerced).
11+
[
12+
null,
13+
{version: '1.2.3'},
14+
function () { return '1.2.3'; },
15+
'',
16+
'.',
17+
tooLong
18+
].forEach(function (input) {
19+
var msg = 'coerce(' + input + ') should be null'
20+
t.same(coerce(input), null, msg)
21+
});
22+
23+
// Expected to be the same.
24+
[
25+
[semver.parse('1.2.3'), '1.2.3'],
26+
['.1', '1.0.0'],
27+
['.1.', '1.0.0'],
28+
['..1', '1.0.0'],
29+
['.1.1', '1.1.0'],
30+
['1.', '1.0.0'],
31+
['1.0', '1.0.0'],
32+
['1.0.0', '1.0.0'],
33+
['0', '0.0.0'],
34+
['0.0', '0.0.0'],
35+
['0.0.0', '0.0.0'],
36+
['0.1', '0.1.0'],
37+
['0.0.1', '0.0.1'],
38+
['0.1.1', '0.1.1'],
39+
['1', '1.0.0'],
40+
['1.2', '1.2.0'],
41+
['1.2.3', '1.2.3'],
42+
['1.2.3.4', '1.2.3'],
43+
['13', '13.0.0'],
44+
['35.12', '35.12.0'],
45+
['35.12.18', '35.12.18'],
46+
['35.12.18.24', '35.12.18'],
47+
['v1', '1.0.0'],
48+
['v1.2', '1.2.0'],
49+
['v1.2.3', '1.2.3'],
50+
['v1.2.3.4', '1.2.3'],
51+
['1 0', '1.0.0'],
52+
['1 1', '1.0.0'],
53+
['1.1 1', '1.1.0'],
54+
['1.1-1', '1.1.0'],
55+
['1.1-1', '1.1.0'],
56+
['a1', '1.0.0'],
57+
['a1a', '1.0.0'],
58+
['1a', '1.0.0'],
59+
['version 1', '1.0.0'],
60+
['version1', '1.0.0'],
61+
['version1.0', '1.0.0'],
62+
['version1.1', '1.1.0'],
63+
[justRight, '12.1.1']
64+
].forEach(function (tuple) {
65+
var input = tuple[0]
66+
var expected = tuple[1]
67+
var msg = 'coerce(' + input + ') should become ' + expected
68+
t.same((coerce(input) || {}).version, expected, msg)
69+
});
70+
71+
t.done();
72+
});

0 commit comments

Comments
 (0)