summaryrefslogtreecommitdiff
path: root/cli/npm/resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/npm/resolution.rs')
-rw-r--r--cli/npm/resolution.rs75
1 files changed, 74 insertions, 1 deletions
diff --git a/cli/npm/resolution.rs b/cli/npm/resolution.rs
index 4f46bbed4..8fac92716 100644
--- a/cli/npm/resolution.rs
+++ b/cli/npm/resolution.rs
@@ -19,9 +19,10 @@ use super::semver::NpmVersion;
use super::semver::SpecifierVersionReq;
/// The version matcher used for npm schemed urls is more strict than
-/// the one used by npm packages.
+/// the one used by npm packages and so we represent either via a trait.
pub trait NpmVersionMatcher {
fn matches(&self, version: &NpmVersion) -> bool;
+ fn is_latest(&self) -> bool;
fn version_text(&self) -> String;
}
@@ -112,6 +113,10 @@ impl NpmVersionMatcher for NpmPackageReq {
}
}
+ fn is_latest(&self) -> bool {
+ self.version_req.is_none()
+ }
+
fn version_text(&self) -> String {
self
.version_req
@@ -484,6 +489,25 @@ fn get_resolved_package_version_and_info(
parent: Option<&NpmPackageId>,
) -> Result<VersionAndInfo, AnyError> {
let mut maybe_best_version: Option<VersionAndInfo> = None;
+ if version_matcher.is_latest() {
+ if let Some(version) = info.dist_tags.get("latest") {
+ match info.versions.get(version) {
+ Some(info) => {
+ return Ok(VersionAndInfo {
+ version: NpmVersion::parse(version)?,
+ info: info.clone(),
+ });
+ }
+ None => {
+ bail!(
+ "Could not find version '{}' referenced in dist-tag 'latest'.",
+ version,
+ )
+ }
+ }
+ }
+ }
+
for (_, version_info) in info.versions.into_iter() {
let version = NpmVersion::parse(&version_info.version)?;
if version_matcher.matches(&version) {
@@ -651,4 +675,53 @@ mod tests {
assert_eq!(name_without_path("@foo/bar/baz"), "@foo/bar");
assert_eq!(name_without_path("@hello"), "@hello");
}
+
+ #[test]
+ fn test_get_resolved_package_version_and_info() {
+ // dist tag where version doesn't exist
+ let package_ref = NpmPackageReference::from_str("npm:test").unwrap();
+ let result = get_resolved_package_version_and_info(
+ "test",
+ &package_ref.req,
+ NpmPackageInfo {
+ name: "test".to_string(),
+ versions: HashMap::new(),
+ dist_tags: HashMap::from([(
+ "latest".to_string(),
+ "1.0.0-alpha".to_string(),
+ )]),
+ },
+ None,
+ );
+ assert_eq!(
+ result.err().unwrap().to_string(),
+ "Could not find version '1.0.0-alpha' referenced in dist-tag 'latest'."
+ );
+
+ // dist tag where version is a pre-release
+ let package_ref = NpmPackageReference::from_str("npm:test").unwrap();
+ let result = get_resolved_package_version_and_info(
+ "test",
+ &package_ref.req,
+ NpmPackageInfo {
+ name: "test".to_string(),
+ versions: HashMap::from([
+ ("0.1.0".to_string(), NpmPackageVersionInfo::default()),
+ (
+ "1.0.0-alpha".to_string(),
+ NpmPackageVersionInfo {
+ version: "0.1.0-alpha".to_string(),
+ ..Default::default()
+ },
+ ),
+ ]),
+ dist_tags: HashMap::from([(
+ "latest".to_string(),
+ "1.0.0-alpha".to_string(),
+ )]),
+ },
+ None,
+ );
+ assert_eq!(result.unwrap().version.to_string(), "1.0.0-alpha");
+ }
}