mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
fix(npm): support loose node semver ranges like >= ^x.x.x
(#17037)
This commit is contained in:
parent
12626b11f7
commit
878590b773
1 changed files with 89 additions and 5 deletions
|
@ -394,15 +394,13 @@ fn skip_whitespace_or_v(input: &str) -> ParseResult<()> {
|
|||
|
||||
// simple ::= primitive | partial | tilde | caret
|
||||
fn simple(input: &str) -> ParseResult<VersionRange> {
|
||||
let tilde = pair(or(tag("~>"), tag("~")), skip_whitespace_or_v);
|
||||
or4(
|
||||
map(preceded(tilde, partial), |partial| {
|
||||
partial.as_tilde_version_range()
|
||||
}),
|
||||
map(
|
||||
preceded(pair(ch('^'), skip_whitespace_or_v), partial),
|
||||
|partial| partial.as_caret_version_range(),
|
||||
),
|
||||
map(preceded(caret, partial), |partial| {
|
||||
partial.as_caret_version_range()
|
||||
}),
|
||||
map(primitive, |primitive| {
|
||||
let partial = primitive.partial;
|
||||
match primitive.kind {
|
||||
|
@ -425,6 +423,28 @@ fn simple(input: &str) -> ParseResult<VersionRange> {
|
|||
)(input)
|
||||
}
|
||||
|
||||
fn tilde(input: &str) -> ParseResult<()> {
|
||||
fn raw_tilde(input: &str) -> ParseResult<()> {
|
||||
map(pair(or(tag("~>"), tag("~")), skip_whitespace_or_v), |_| ())(input)
|
||||
}
|
||||
|
||||
or(
|
||||
preceded(terminated(primitive_kind, whitespace), raw_tilde),
|
||||
raw_tilde,
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn caret(input: &str) -> ParseResult<()> {
|
||||
fn raw_caret(input: &str) -> ParseResult<()> {
|
||||
map(pair(ch('^'), skip_whitespace_or_v), |_| ())(input)
|
||||
}
|
||||
|
||||
or(
|
||||
preceded(terminated(primitive_kind, whitespace), raw_caret),
|
||||
raw_caret,
|
||||
)(input)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum PrimitiveKind {
|
||||
GreaterThan,
|
||||
|
@ -1069,4 +1089,68 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_primitive_kind_beside_caret_or_tilde_with_whitespace() {
|
||||
// node semver should have enforced strictness, but it didn't
|
||||
// and so we end up with a system that acts this way
|
||||
let fixtures = &[
|
||||
(">= ^1.2.3", "1.2.3", true),
|
||||
(">= ^1.2.3", "1.2.4", true),
|
||||
(">= ^1.2.3", "1.9.3", true),
|
||||
(">= ^1.2.3", "2.0.0", false),
|
||||
(">= ^1.2.3", "1.2.2", false),
|
||||
// this is considered the same as the above by node semver
|
||||
("> ^1.2.3", "1.2.3", true),
|
||||
("> ^1.2.3", "1.2.4", true),
|
||||
("> ^1.2.3", "1.9.3", true),
|
||||
("> ^1.2.3", "2.0.0", false),
|
||||
("> ^1.2.3", "1.2.2", false),
|
||||
// this is also considered the same
|
||||
("< ^1.2.3", "1.2.3", true),
|
||||
("< ^1.2.3", "1.2.4", true),
|
||||
("< ^1.2.3", "1.9.3", true),
|
||||
("< ^1.2.3", "2.0.0", false),
|
||||
("< ^1.2.3", "1.2.2", false),
|
||||
// same with this
|
||||
("<= ^1.2.3", "1.2.3", true),
|
||||
("<= ^1.2.3", "1.2.4", true),
|
||||
("<= ^1.2.3", "1.9.3", true),
|
||||
("<= ^1.2.3", "2.0.0", false),
|
||||
("<= ^1.2.3", "1.2.2", false),
|
||||
// now try a ~, which should work the same as above, but for ~
|
||||
("<= ~1.2.3", "1.2.3", true),
|
||||
("<= ~1.2.3", "1.2.4", true),
|
||||
("<= ~1.2.3", "1.9.3", false),
|
||||
("<= ~1.2.3", "2.0.0", false),
|
||||
("<= ~1.2.3", "1.2.2", false),
|
||||
];
|
||||
|
||||
for (req_text, version_text, satisfies) in fixtures {
|
||||
let req = NpmVersionReq::parse(req_text).unwrap();
|
||||
let version = NpmVersion::parse(version_text).unwrap();
|
||||
assert_eq!(
|
||||
req.matches(&version),
|
||||
*satisfies,
|
||||
"Checking {} {} satisfies {}",
|
||||
req_text,
|
||||
if *satisfies { "true" } else { "false" },
|
||||
version_text
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_primitive_kind_beside_caret_or_tilde_no_whitespace() {
|
||||
let fixtures = &[
|
||||
">=^1.2.3", ">^1.2.3", "<^1.2.3", "<=^1.2.3", ">=~1.2.3", ">~1.2.3",
|
||||
"<~1.2.3", "<=~1.2.3",
|
||||
];
|
||||
|
||||
for req_text in fixtures {
|
||||
// when it has no space, this is considered invalid
|
||||
// by node semver so we should error
|
||||
assert!(NpmVersionReq::parse(req_text).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue