Skip to content

Commit b81c7cd

Browse files
committed
feat(core): update semver in git urls, aliases etc
Closes #213
1 parent 4af3b33 commit b81c7cd

File tree

9 files changed

+128
-16
lines changed

9 files changed

+128
-16
lines changed

src/dependency.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ impl Dependency {
125125
.instances
126126
.borrow()
127127
.iter()
128-
.filter(|instance| instance.descriptor.specifier.is_basic_semver())
128+
.filter(|instance| instance.descriptor.specifier.get_node_version().is_some())
129129
.map(|instance| instance.descriptor.specifier.clone())
130130
.fold(None, |preferred, specifier| match preferred {
131131
None => Some(specifier),
132132
Some(preferred) => {
133-
if specifier.cmp(&preferred) == preferred_order {
133+
if specifier.get_node_version().cmp(&preferred.get_node_version()) == preferred_order {
134134
Some(specifier)
135135
} else {
136136
Some(preferred)

src/specifier.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ impl Specifier {
218218
}
219219
}
220220

221-
fn get_node_version(&self) -> Option<&Version> {
221+
pub fn get_node_version(&self) -> Option<&Version> {
222222
match self {
223223
Self::Alias(inner) => inner.semver.as_ref().map(|semver| &semver.node_version),
224224
Self::BasicSemver(inner) => Some(&inner.node_version),
@@ -233,20 +233,38 @@ impl Specifier {
233233
self.get_semver().map(|semver| &semver.range_variant)
234234
}
235235

236-
/// Replace a new instance with the given semver range applied to it when it
237-
/// is possible to do so, otherwise the same instance is returned
236+
/// Return a new `Specifier` with the given semver range applied to it when it
237+
/// is possible to do so, otherwise the same `Specifier` is returned
238238
pub fn with_range(self, range: &SemverRange) -> Self {
239239
match self {
240-
Self::Alias(inner) => Self::Alias(inner.with_range(range)),
241-
Self::BasicSemver(inner) => Self::BasicSemver(inner.with_range(range)),
242-
Self::ComplexSemver(inner) => Self::ComplexSemver(inner.with_range(range)),
243-
Self::File(inner) => Self::File(inner.with_range(range)),
244-
Self::Git(inner) => Self::Git(inner.with_range(range)),
240+
Self::Alias(s) => Self::Alias(s.with_range(range)),
241+
Self::BasicSemver(s) => Self::BasicSemver(s.with_range(range)),
242+
Self::ComplexSemver(s) => Self::ComplexSemver(s.with_range(range)),
243+
Self::File(s) => Self::File(s.with_range(range)),
244+
Self::Git(s) => Self::Git(s.with_range(range)),
245245
Self::None => Self::None,
246-
Self::Tag(inner) => Self::Tag(inner.with_range(range)),
247-
Self::Unsupported(inner) => Self::Unsupported(inner.with_range(range)),
248-
Self::Url(inner) => Self::Url(inner.with_range(range)),
249-
Self::WorkspaceProtocol(inner) => Self::WorkspaceProtocol(inner.with_range(range)),
246+
Self::Tag(s) => Self::Tag(s.with_range(range)),
247+
Self::Unsupported(s) => Self::Unsupported(s.with_range(range)),
248+
Self::Url(s) => Self::Url(s.with_range(range)),
249+
Self::WorkspaceProtocol(s) => Self::WorkspaceProtocol(s.with_range(range)),
250+
}
251+
}
252+
253+
/// Return a new `Specifier` with the given semver version number applied to
254+
/// it when it is possible to do so, otherwise the same `Specifier` is
255+
/// returned. The range is also changed.
256+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
257+
match self {
258+
Self::Alias(s) => Self::Alias(s.with_semver(semver)),
259+
Self::BasicSemver(s) => Self::BasicSemver(s.with_semver(semver)),
260+
Self::ComplexSemver(s) => Self::ComplexSemver(s.with_semver(semver)),
261+
Self::File(s) => Self::File(s.with_semver(semver)),
262+
Self::Git(s) => Self::Git(s.with_semver(semver)),
263+
Self::None => Self::None,
264+
Self::Tag(s) => Self::Tag(s.with_semver(semver)),
265+
Self::Unsupported(s) => Self::Unsupported(s.with_semver(semver)),
266+
Self::Url(s) => Self::Url(s.with_semver(semver)),
267+
Self::WorkspaceProtocol(s) => Self::WorkspaceProtocol(s.with_semver(semver)),
250268
}
251269
}
252270

src/specifier/alias.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,12 @@ impl Alias {
3535
self
3636
}
3737
}
38+
39+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
40+
Self {
41+
raw: format!("npm:{}@{}", self.name, semver.raw),
42+
name: self.name,
43+
semver: Some(semver.clone()),
44+
}
45+
}
3846
}

src/specifier/basic_semver.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,8 @@ impl BasicSemver {
148148
}
149149
}
150150
}
151+
152+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
153+
semver.clone()
154+
}
151155
}

src/specifier/complex_semver.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use {super::semver_range::SemverRange, log::debug, node_semver::Range};
1+
use {
2+
super::{basic_semver::BasicSemver, semver_range::SemverRange},
3+
log::debug,
4+
node_semver::Range,
5+
};
26

37
/// A specifier containing multiple ranges and/or versions
48
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
@@ -17,4 +21,9 @@ impl ComplexSemver {
1721
debug!("Cannot apply semver range '{:?}' to specifier '{}'", range, self.raw);
1822
self
1923
}
24+
25+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
26+
debug!("Cannot apply semver '{:?}' to specifier '{}'", semver, self.raw);
27+
self
28+
}
2029
}

src/specifier/git.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,20 @@ impl Git {
5151
self
5252
}
5353
}
54+
55+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
56+
if let Some(current_semver) = self.semver {
57+
Self {
58+
raw: self.raw.replace(&current_semver.node_version.to_string(), &semver.raw),
59+
origin: self.origin,
60+
semver: Some(semver.clone()),
61+
}
62+
} else {
63+
Self {
64+
raw: format!("{}#{}", self.origin, semver.raw),
65+
origin: self.origin,
66+
semver: Some(semver.clone()),
67+
}
68+
}
69+
}
5470
}

src/specifier/raw.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use {super::semver_range::SemverRange, log::debug};
1+
use {
2+
super::{basic_semver::BasicSemver, semver_range::SemverRange},
3+
log::debug,
4+
};
25

36
/// A specifier not containing semver so not much can be done with it
47
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
@@ -12,4 +15,9 @@ impl Raw {
1215
debug!("Cannot apply semver range '{:?}' to specifier '{}'", range, self.raw);
1316
self
1417
}
18+
19+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
20+
debug!("Cannot apply semver '{:?}' to specifier '{}'", semver, self.raw);
21+
self
22+
}
1523
}

src/specifier/workspace_protocol.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ impl WorkspaceProtocol {
2929
semver,
3030
}
3131
}
32+
33+
pub fn with_semver(self, semver: &BasicSemver) -> Self {
34+
Self {
35+
raw: format!("workspace:{}", semver.raw),
36+
local_version: self.local_version,
37+
semver: semver.clone(),
38+
}
39+
}
3240
}

src/specifier_test.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,12 @@ fn comparison() {
716716
("workspace:<=0.0.0", "<0.0.0", Ordering::Greater),
717717
("workspace:0.0.0", "0.0.0", Ordering::Equal),
718718
("workspace:~", "~1.2.3", Ordering::Equal),
719+
/* git with a semver tag is ignored and the semver is used */
720+
("github:org/repo#v0.0.0", "github:org/repo#v0.0.0", Ordering::Equal),
721+
("github:org/repo#v0.0.0", "github:org/repo#0.0.0", Ordering::Equal),
722+
("github:org/repo#v0.0.0", "0.0.0", Ordering::Equal),
723+
("github:org/repo#v0.0.1", "0.0.0", Ordering::Greater),
724+
("github:org/repo#0.0.1", "0.0.0", Ordering::Greater),
719725
];
720726
for (str_a, str_b, expected) in cases {
721727
let local_version = BasicSemver::new("1.2.3");
@@ -765,3 +771,38 @@ fn satisfies_all() {
765771
);
766772
}
767773
}
774+
775+
#[test]
776+
fn issue_213_git_tags_starting_with_v() {
777+
for git_url in git_urls() {
778+
let value = "github:uNetworking/uWebSockets.js#v20.43.0";
779+
match Specifier::new(value, None) {
780+
Specifier::Git(actual) => {
781+
assert_eq!(actual.raw, value);
782+
assert_eq!(actual.origin, "github:uNetworking/uWebSockets.js");
783+
let semver = actual.semver.as_ref().unwrap();
784+
assert_eq!(semver.raw, "20.43.0");
785+
assert_eq!(semver.variant, BasicSemverVariant::Patch);
786+
assert_eq!(semver.range_variant, SemverRange::Exact);
787+
assert_eq!(semver.node_version.major, 20);
788+
assert_eq!(semver.node_version.minor, 43);
789+
assert_eq!(semver.node_version.patch, 0);
790+
assert!(semver.node_version.pre_release.is_empty());
791+
792+
let next_semver = BasicSemver::new("1.2.3").unwrap();
793+
let edited = actual.with_semver(&next_semver);
794+
assert_eq!(edited.raw, "github:uNetworking/uWebSockets.js#v1.2.3");
795+
assert_eq!(edited.origin, "github:uNetworking/uWebSockets.js");
796+
let semver = edited.semver.unwrap();
797+
assert_eq!(semver.raw, "1.2.3");
798+
assert_eq!(semver.variant, BasicSemverVariant::Patch);
799+
assert_eq!(semver.range_variant, SemverRange::Exact);
800+
assert_eq!(semver.node_version.major, 1);
801+
assert_eq!(semver.node_version.minor, 2);
802+
assert_eq!(semver.node_version.patch, 3);
803+
assert!(semver.node_version.pre_release.is_empty());
804+
}
805+
_ => panic!("Expected Git"),
806+
};
807+
}
808+
}

0 commit comments

Comments
 (0)