From c3a1fb56522b70f17da3e8381c01d9438e9c6d6c Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 9 Dec 2024 12:17:25 -0500 Subject: [PATCH] fix: do not error for specifier with version requirement and @ symbol in path --- src/jsr.rs | 14 ++++++++++++++ src/npm.rs | 16 +++++++++++++++- src/package.rs | 30 ++++++++++++++++-------------- src/specifier.rs | 2 +- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/jsr.rs b/src/jsr.rs index 025d137..a66b913 100644 --- a/src/jsr.rs +++ b/src/jsr.rs @@ -262,6 +262,8 @@ impl JsrDepPackageReq { #[cfg(test)] mod test { + use crate::package::PackageReqReferenceInvalidWithVersionParseError; + use super::*; #[test] @@ -290,6 +292,18 @@ mod test { assert_eq!(req_ref.req().version_req.to_string(), "^1.0.0"); assert_eq!(req_ref.sub_path(), Some("mod.ts")); } + { + assert_eq!( + JsrPackageReqReference::from_str("jsr:@std/testing/bdd@1").unwrap_err(), + PackageReqReferenceParseError::InvalidPathWithVersion(Box::new( + PackageReqReferenceInvalidWithVersionParseError { + kind: PackageKind::Jsr, + current: "@std/testing/bdd@1".to_string(), + suggested: "@std/testing@1/bdd".to_string(), + } + )), + ); + } } #[test] diff --git a/src/npm.rs b/src/npm.rs index fe55447..96bbf30 100644 --- a/src/npm.rs +++ b/src/npm.rs @@ -84,7 +84,7 @@ pub fn parse_npm_version(text: &str) -> Result { .map_err(|err| NpmVersionParseError { source: err }) } -#[derive(Error, Debug, Clone, JsError)] +#[derive(Error, Debug, Clone, JsError, PartialEq, Eq)] #[class(type)] #[error("Invalid version requirement")] pub struct NpmVersionReqParseError { @@ -1374,6 +1374,20 @@ mod tests { )), _ => unreachable!(), } + + // path with `@` shouldn't error + assert_eq!( + NpmPackageReqReference::from_str("npm:package@^5.0.0-beta.35/@some/path") + .unwrap(), + NpmPackageReqReference::new(PackageReqReference { + req: PackageReq { + name: "package".to_string(), + version_req: VersionReq::parse_from_specifier("^5.0.0-beta.35") + .unwrap(), + }, + sub_path: Some("@some/path".to_string()), + }), + ); } #[test] diff --git a/src/package.rs b/src/package.rs index 648df42..df99a97 100644 --- a/src/package.rs +++ b/src/package.rs @@ -35,7 +35,7 @@ impl PackageKind { } } -#[derive(Error, Debug, Clone, JsError)] +#[derive(Error, Debug, Clone, JsError, PartialEq, Eq)] pub enum PackageReqReferenceParseError { #[class(type)] #[error("Not {} specifier", .0.scheme_with_colon())] @@ -48,7 +48,7 @@ pub enum PackageReqReferenceParseError { InvalidPathWithVersion(Box), } -#[derive(Error, Debug, Clone, JsError)] +#[derive(Error, Debug, Clone, JsError, PartialEq, Eq)] #[class(type)] #[error("Invalid package specifier '{specifier}'")] pub struct PackageReqReferenceInvalidParseError { @@ -57,9 +57,9 @@ pub struct PackageReqReferenceInvalidParseError { pub source: PackageReqPartsParseError, } -#[derive(Error, Debug, Clone, JsError)] +#[derive(Error, Debug, Clone, JsError, PartialEq, Eq)] #[class(type)] -#[error("Invalid package specifier '{0}{1}'. Did you mean to write '{0}{2}'?", .kind.scheme_with_colon(), current, suggested)] +#[error("Invalid package specifier '{0}{1}'. Did you mean to write '{0}{2}'? If not, add a version requirement to the specifier.", .kind.scheme_with_colon(), current, suggested)] pub struct PackageReqReferenceInvalidWithVersionParseError { pub kind: PackageKind, pub current: String, @@ -109,15 +109,17 @@ impl PackageReqReference { }; if let Some(sub_path) = &sub_path { - if let Some(at_index) = sub_path.rfind('@') { - let (new_sub_path, version) = sub_path.split_at(at_index); - return Err(PackageReqReferenceParseError::InvalidPathWithVersion( - Box::new(PackageReqReferenceInvalidWithVersionParseError { - kind, - current: format!("{req}/{sub_path}"), - suggested: format!("{req}{version}/{new_sub_path}"), - }), - )); + if req.version_req.version_text() == "*" { + if let Some(at_index) = sub_path.rfind('@') { + let (new_sub_path, version) = sub_path.split_at(at_index); + return Err(PackageReqReferenceParseError::InvalidPathWithVersion( + Box::new(PackageReqReferenceInvalidWithVersionParseError { + kind, + current: format!("{req}/{sub_path}"), + suggested: format!("{req}{version}/{new_sub_path}"), + }), + )); + } } } @@ -135,7 +137,7 @@ impl std::fmt::Display for PackageReqReference { } } -#[derive(Error, Debug, Clone, JsError)] +#[derive(Error, Debug, Clone, JsError, PartialEq, Eq)] pub enum PackageReqPartsParseError { #[class(type)] #[error("Did not contain a package name")] diff --git a/src/specifier.rs b/src/specifier.rs index 74687ef..f662184 100644 --- a/src/specifier.rs +++ b/src/specifier.rs @@ -12,7 +12,7 @@ use crate::VersionReq; use crate::is_valid_tag; -#[derive(Error, Debug, Clone, deno_error::JsError)] +#[derive(Error, Debug, Clone, deno_error::JsError, PartialEq, Eq)] #[class(type)] #[error("Invalid specifier version requirement")] pub struct VersionReqSpecifierParseError {