Skip to content

Commit 4bc6150

Browse files
authored
Merge pull request #15268 from nikmilson/fix-semver-ranges-parsing
accept whitespaces after semver range operators
2 parents f593d98 + 3b55455 commit 4bc6150

2 files changed

Lines changed: 38 additions & 16 deletions

File tree

lib/util/semver.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ exports.versionLt = versionLt;
8989
*/
9090
exports.parseRange = str => {
9191
const splitAndConvert = str => {
92-
return str.split(".").map(item => (`${+item}` === item ? +item : item));
92+
return str
93+
.split(".")
94+
.map(item => (item !== "NaN" && `${+item}` === item ? +item : item));
9395
};
9496
// see https://docs.npmjs.com/misc/semver#range-grammar for grammar
9597
const parsePartial = str => {
@@ -131,13 +133,15 @@ exports.parseRange = str => {
131133
return [-range[0] - 1, ...range.slice(1)];
132134
};
133135
const parseSimple = str => {
134-
// simple ::= primitive | partial | tilde | caret
135-
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
136-
// tilde ::= '~' partial
137-
// caret ::= '^' partial
136+
// simple ::= primitive | partial | tilde | caret
137+
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | '!' ) ( ' ' ) * partial
138+
// tilde ::= '~' ( ' ' ) * partial
139+
// caret ::= '^' ( ' ' ) * partial
138140
const match = /^(\^|~|<=|<|>=|>|=|v|!)/.exec(str);
139141
const start = match ? match[0] : "";
140-
const remainder = parsePartial(str.slice(start.length));
142+
const remainder = parsePartial(
143+
start.length ? str.slice(start.length).trim() : str.trim()
144+
);
141145
switch (start) {
142146
case "^":
143147
if (remainder.length > 1 && remainder[1] === 0) {
@@ -191,11 +195,14 @@ exports.parseRange = str => {
191195
return [, ...arr, ...items.slice(1).map(() => fn)];
192196
};
193197
const parseRange = str => {
194-
// range ::= hyphen | simple ( ' ' simple ) * | ''
195-
// hyphen ::= partial ' - ' partial
196-
const items = str.split(" - ");
198+
// range ::= hyphen | simple ( ' ' ( ' ' ) * simple ) * | ''
199+
// hyphen ::= partial ( ' ' ) * ' - ' ( ' ' ) * partial
200+
const items = str.split(/\s+-\s+/);
197201
if (items.length === 1) {
198-
const items = str.trim().split(/\s+/g).map(parseSimple);
202+
const items = str
203+
.trim()
204+
.split(/(?<=[-0-9A-Za-z])\s+/g)
205+
.map(parseSimple);
199206
return combine(items, 2);
200207
}
201208
const a = parsePartial(items[0]);

test/SemVer.unittest.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,27 @@ describe("SemVer", () => {
129129

130130
describe("parseRange", () => {
131131
const cases = {
132-
"=3": ["3", "v3", "3.x", "3.X", "3.x.x", "3.*", "3.*.*", "^3", "^3.x"],
133-
"=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0"],
134-
"^3.4": ["^3.4.*"],
135-
"3.4 - 6.5": [">=3.4 <=6.5"],
136-
"<=3.4": ["<3.4 || =3.4"],
137-
">3.4": [">=3.4 !3.4"]
132+
"5 || 6 || 7.x.x": ["5.x.x || 6.x || 7"],
133+
"1 - 2": ["1 - 2"],
134+
"=3": [
135+
"3",
136+
"v3",
137+
"3.x",
138+
"3.X",
139+
"3.x.x",
140+
"3.*",
141+
"3.*.*",
142+
"^3",
143+
"^3.x",
144+
"= 3"
145+
],
146+
"=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0", "= 3.0"],
147+
"^3.4": ["^3.4.*", "^ 3.4"],
148+
"3.4 - 6.5": [">=3.4 <=6.5", ">= 3.4 <= 6.5"],
149+
"<=3.4": ["<3.4 || =3.4", "<= 3.4"],
150+
">3.4": [">=3.4 !3.4", "> 3.4"],
151+
"1.2.3-alpha.x.x": ["1.2.3-alpha", "1.2.3-alpha+build.25"],
152+
"1.2.3-NaN": ["1.2.3-NaN"]
138153
};
139154
for (const key of Object.keys(cases)) {
140155
describe(key, () => {

0 commit comments

Comments
 (0)