From 61508be3d81d6d02e9034889e76a132ac3e5749e Mon Sep 17 00:00:00 2001 From: Cno Date: Sun, 14 Jul 2024 00:19:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E8=B7=AF=E5=BE=84=E5=8C=85=E6=97=B6=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E5=87=BA=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/matcher.rs | 56 ++++++++++++++++++++++++++++++++++++++++---- src/utils/path.rs | 8 +++---- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/types/matcher.rs b/src/types/matcher.rs index be84e3a4..d3ae9a98 100644 --- a/src/types/matcher.rs +++ b/src/types/matcher.rs @@ -1,9 +1,11 @@ +use std::path::Path; + use regex::Regex; use semver::VersionReq; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Ok, Result}; -use crate::utils::is_url; +use crate::utils::{format_path, is_url}; lazy_static! { static ref PACKAGE_MATCHER_REGEX: Regex = @@ -86,17 +88,26 @@ pub enum PackageInputEnum { impl PackageInputEnum { pub fn parse(text: String, deny_mirror: bool, deny_version_matcher: bool) -> Result { - // 使用正则匹配 + // 判断是否为 URL if is_url(&text) { return Ok(PackageInputEnum::Url(text)); } + + // 如果本地存在该路径,则作为路径处理 + let p = Path::new(&text); + if p.exists() { + return Ok(PackageInputEnum::LocalPath(format_path(&text))); + } + + // 使用正则匹配 PackageMatcher if PACKAGE_MATCHER_REGEX.is_match(&text) { let m = PackageMatcher::parse(&text, deny_mirror, deny_version_matcher)?; return Ok(PackageInputEnum::PackageMatcher(m)); } - // 兜底,作为本地路径 - Ok(PackageInputEnum::LocalPath(text)) + Err(anyhow!( + "Error:Failed to parse '{text}' as valid package input" + )) } } @@ -148,3 +159,38 @@ fn test_parse_package_matcher() { assert!(PackageMatcher::parse(&"Official/Microsoft/VSCode".to_string(), true, false).is_err()); assert!(PackageMatcher::parse(&"VSCode@\">=0.1.0\"".to_string(), false, true).is_err()); } + +#[test] +fn test_parse_package_input_enum() { + assert_eq!( + PackageInputEnum::parse( + "https://nep.edgeless.top/static/test.nep".to_string(), + false, + false + ) + .unwrap(), + PackageInputEnum::Url("https://nep.edgeless.top/static/test.nep".to_string()) + ); + assert_eq!( + PackageInputEnum::parse(".\\Cargo.lock".to_string(), false, false).unwrap(), + PackageInputEnum::LocalPath("Cargo.lock".to_string()) + ); + assert_eq!( + PackageInputEnum::parse("VSCode".to_string(), false, false).unwrap(), + PackageInputEnum::PackageMatcher(PackageMatcher { + name: "VSCode".to_string(), + scope: None, + mirror: None, + version_req: None + }) + ); + assert_eq!( + PackageInputEnum::parse("VSCode@1.1.4".to_string(), false, false).unwrap(), + PackageInputEnum::PackageMatcher(PackageMatcher { + name: "VSCode".to_string(), + scope: None, + mirror: None, + version_req: Some(VersionReq::parse("1.1.4").unwrap()) + }) + ); +} diff --git a/src/utils/path.rs b/src/utils/path.rs index e85e9ee1..b7965322 100644 --- a/src/utils/path.rs +++ b/src/utils/path.rs @@ -77,9 +77,9 @@ fn find_scope_with_name_locally(name: &String, scope: Option) -> Result< } Err(if let Some(s) = scope { - anyhow!("Error:Can't locate '{name}' with scope '{s}'") + anyhow!("Error:Can't locate '{name}' with scope '{s}' locally") } else { - anyhow!("Error:Can't find scope for '{name}'") + anyhow!("Error:Can't find scope for '{name}' locally") }) } @@ -102,9 +102,9 @@ fn find_scope_with_name_online(name: &String, scope: Option) -> Result<( } } Err(if let Some(s) = scope { - anyhow!("Error:Can't locate '{name}' with scope '{s}'") + anyhow!("Error:Can't locate '{name}' with scope '{s}' online") } else { - anyhow!("Error:Can't find scope for '{name}'") + anyhow!("Error:Can't find scope for '{name}' online") }) }