Skip to content

Commit 3464fd1

Browse files
committed
feat: Add node semver compatibility implementaion and tests
1 parent 7b4ad61 commit 3464fd1

7 files changed

Lines changed: 679 additions & 395 deletions

File tree

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ jobs:
5353
env:
5454
RUSTFLAGS: --cfg test_node_semver ${{env.RUSTFLAGS}}
5555

56+
mirror_node_matches_prerelease:
57+
name: mirror_node_matches_prerelease
58+
needs: pre_ci
59+
if: needs.pre_ci.outputs.continue
60+
runs-on: ubuntu-latest
61+
timeout-minutes: 45
62+
steps:
63+
- uses: actions/checkout@v4
64+
- uses: dtolnay/rust-toolchain@stable
65+
- run: cargo test --package semver --test test_matches_prerelease --features "mirror_node_matches_prerelease"
66+
5667
minimal:
5768
name: Minimal versions
5869
needs: pre_ci

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ rust-version = "1.31"
1313

1414
[features]
1515
default = ["std"]
16+
mirror_node_matches_prerelease = []
1617
std = []
1718

1819
[dependencies]

src/eval.rs

Lines changed: 5 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::{Comparator, Op, Prerelease, Version, VersionReq};
1+
use crate::{eval_ext, Comparator, Op, Version, VersionReq};
22

33
pub(crate) fn matches_req(req: &VersionReq, ver: &Version, prerelease_matches: bool) -> bool {
44
for cmp in &req.comparators {
55
if prerelease_matches {
6-
if !matches_prerelease_impl(cmp, ver) {
6+
if !eval_ext::matches_prerelease_impl(cmp, ver) {
77
return false;
88
}
99
} else if !matches_impl(cmp, ver) {
@@ -30,41 +30,6 @@ pub(crate) fn matches_req(req: &VersionReq, ver: &Version, prerelease_matches: b
3030
pub(crate) fn matches_comparator(cmp: &Comparator, ver: &Version) -> bool {
3131
matches_impl(cmp, ver) && (ver.pre.is_empty() || pre_is_compatible(cmp, ver))
3232
}
33-
// If VersionReq missing Minor, Patch, then filling them with 0
34-
fn fill_partial_req(cmp: &Comparator) -> Comparator {
35-
let mut cmp = cmp.clone();
36-
if cmp.minor.is_none() {
37-
cmp.minor = Some(0);
38-
cmp.patch = Some(0);
39-
} else if cmp.patch.is_none() {
40-
cmp.patch = Some(0);
41-
}
42-
cmp
43-
}
44-
45-
fn matches_prerelease_impl(cmp: &Comparator, ver: &Version) -> bool {
46-
match cmp.op {
47-
Op::Exact | Op::Wildcard => matches_exact_prerelease(cmp, ver),
48-
Op::Greater => matches_greater(cmp, ver),
49-
Op::GreaterEq => {
50-
if matches_exact_prerelease(cmp, ver) {
51-
return true;
52-
}
53-
matches_greater(cmp, ver)
54-
}
55-
Op::Less => matches_less(&fill_partial_req(cmp), ver),
56-
Op::LessEq => {
57-
if matches_exact_prerelease(cmp, ver) {
58-
return true;
59-
}
60-
matches_less(&fill_partial_req(cmp), ver)
61-
}
62-
Op::Tilde => matches_tilde_prerelease(cmp, ver),
63-
Op::Caret => matches_caret_prerelease(cmp, ver),
64-
#[cfg(no_non_exhaustive)]
65-
Op::__NonExhaustive => unreachable!(),
66-
}
67-
}
6833

6934
fn matches_impl(cmp: &Comparator, ver: &Version) -> bool {
7035
match cmp.op {
@@ -80,49 +45,7 @@ fn matches_impl(cmp: &Comparator, ver: &Version) -> bool {
8045
}
8146
}
8247

83-
fn matches_exact_prerelease(cmp: &Comparator, ver: &Version) -> bool {
84-
if matches_exact(cmp, ver) {
85-
return true;
86-
}
87-
88-
// If the comparator has a prerelease tag like =3.0.0-alpha.24,
89-
// then it shoud be only exactly match 3.0.0-alpha.24.
90-
if !cmp.pre.is_empty() {
91-
return false;
92-
}
93-
94-
if !matches_greater(&fill_partial_req(cmp), ver) {
95-
return false;
96-
}
97-
98-
let mut upper = Comparator {
99-
op: Op::Less,
100-
pre: Prerelease::new("0").unwrap(),
101-
..cmp.clone()
102-
};
103-
104-
match (upper.minor.is_some(), upper.patch.is_some()) {
105-
(true, true) => {
106-
upper.patch = Some(upper.patch.unwrap() + 1);
107-
}
108-
(true, false) => {
109-
// Partial Exact VersionReq eg. =0.24
110-
upper.minor = Some(upper.minor.unwrap() + 1);
111-
upper.patch = Some(0);
112-
}
113-
(false, false) => {
114-
// Partial Exact VersionReq eg. =0
115-
upper.major += 1;
116-
upper.minor = Some(0);
117-
upper.patch = Some(0);
118-
}
119-
_ => {}
120-
}
121-
122-
matches_less(&upper, ver)
123-
}
124-
125-
fn matches_exact(cmp: &Comparator, ver: &Version) -> bool {
48+
pub(super) fn matches_exact(cmp: &Comparator, ver: &Version) -> bool {
12649
if ver.major != cmp.major {
12750
return false;
12851
}
@@ -142,7 +65,7 @@ fn matches_exact(cmp: &Comparator, ver: &Version) -> bool {
14265
ver.pre == cmp.pre
14366
}
14467

145-
fn matches_greater(cmp: &Comparator, ver: &Version) -> bool {
68+
pub(super) fn matches_greater(cmp: &Comparator, ver: &Version) -> bool {
14669
if ver.major != cmp.major {
14770
return ver.major > cmp.major;
14871
}
@@ -168,7 +91,7 @@ fn matches_greater(cmp: &Comparator, ver: &Version) -> bool {
16891
ver.pre > cmp.pre
16992
}
17093

171-
fn matches_less(cmp: &Comparator, ver: &Version) -> bool {
94+
pub(super) fn matches_less(cmp: &Comparator, ver: &Version) -> bool {
17295
if ver.major != cmp.major {
17396
return ver.major < cmp.major;
17497
}
@@ -194,37 +117,6 @@ fn matches_less(cmp: &Comparator, ver: &Version) -> bool {
194117
ver.pre < cmp.pre
195118
}
196119

197-
fn matches_tilde_prerelease(cmp: &Comparator, ver: &Version) -> bool {
198-
if matches_exact(cmp, ver) {
199-
return true;
200-
}
201-
202-
if !matches_greater(&fill_partial_req(cmp), ver) {
203-
return false;
204-
}
205-
206-
let mut upper = Comparator {
207-
op: Op::Less,
208-
pre: Prerelease::new("0").unwrap(),
209-
..cmp.clone()
210-
};
211-
212-
match (upper.minor.is_some(), upper.patch.is_some()) {
213-
(true, _) => {
214-
upper.minor = Some(upper.minor.unwrap() + 1);
215-
upper.patch = Some(0);
216-
}
217-
(false, false) => {
218-
upper.major += 1;
219-
upper.minor = Some(0);
220-
upper.patch = Some(0);
221-
}
222-
_ => {}
223-
}
224-
225-
matches_less(&upper, ver)
226-
}
227-
228120
fn matches_tilde(cmp: &Comparator, ver: &Version) -> bool {
229121
if ver.major != cmp.major {
230122
return false;
@@ -245,52 +137,6 @@ fn matches_tilde(cmp: &Comparator, ver: &Version) -> bool {
245137
ver.pre >= cmp.pre
246138
}
247139

248-
fn matches_caret_prerelease(cmp: &Comparator, ver: &Version) -> bool {
249-
if matches_exact(cmp, ver) {
250-
return true;
251-
}
252-
253-
if !matches_greater(&fill_partial_req(cmp), ver) {
254-
return false;
255-
}
256-
257-
let mut upper = Comparator {
258-
op: Op::Less,
259-
pre: Prerelease::new("0").unwrap(),
260-
..cmp.clone()
261-
};
262-
263-
match (
264-
upper.major > 0,
265-
upper.minor.is_some(),
266-
upper.patch.is_some(),
267-
) {
268-
(true, _, _) | (_, false, false) => {
269-
upper.major += 1;
270-
upper.minor = Some(0);
271-
upper.patch = Some(0);
272-
}
273-
(_, true, false) => {
274-
upper.minor = Some(upper.minor.unwrap() + 1);
275-
upper.patch = Some(0);
276-
}
277-
(_, true, _) if upper.minor.unwrap() > 0 => {
278-
upper.minor = Some(upper.minor.unwrap() + 1);
279-
upper.patch = Some(0);
280-
}
281-
(_, true, _) if upper.minor.unwrap() == 0 => {
282-
if upper.patch.is_none() {
283-
upper.patch = Some(1);
284-
} else {
285-
upper.patch = Some(upper.patch.unwrap() + 1);
286-
}
287-
}
288-
_ => {}
289-
}
290-
291-
matches_less(&upper, ver)
292-
}
293-
294140
fn matches_caret(cmp: &Comparator, ver: &Version) -> bool {
295141
if ver.major != cmp.major {
296142
return false;

0 commit comments

Comments
 (0)