diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2022-09-02 13:06:42 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-02 13:06:42 -0400 |
commit | 5262937285e72419c6576ae1595d43f23e0c7b9d (patch) | |
tree | 591e0732e9245a65232255954454682d510eea71 /cli/npm/resolution.rs | |
parent | 7d622a6643b3dddae4e2ff820f75ec67c8df7224 (diff) |
fix(npm): respect `latest` dist tag for getting current version (#15746)
Diffstat (limited to 'cli/npm/resolution.rs')
-rw-r--r-- | cli/npm/resolution.rs | 75 |
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"); + } } |