diff --git a/Cargo.lock b/Cargo.lock index 32818939..af195860 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2868,6 +2868,7 @@ dependencies = [ "serde_json", "tokio", "toml_edit", + "url", "vergen-gitcl", "yazi-boot", "yazi-dds", diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 805c3c41..c9db7014 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -21,6 +21,7 @@ md-5 = "0.10.6" serde_json = "1.0.120" tokio = { version = "1.38.1", features = [ "full" ] } toml_edit = "0.22.16" +url = "2.5.2" [build-dependencies] anyhow = "1.0.86" diff --git a/yazi-cli/src/package/add.rs b/yazi-cli/src/package/add.rs index a4de93ec..4394d007 100644 --- a/yazi-cli/src/package/add.rs +++ b/yazi-cli/src/package/add.rs @@ -9,7 +9,7 @@ impl Package { let path = self.local(); if !must_exists(&path).await { - Git::clone(&self.remote(), &path).await?; + Git::clone(&self.remote, &path).await?; } else { Git::pull(&path).await?; }; diff --git a/yazi-cli/src/package/install.rs b/yazi-cli/src/package/install.rs index a770fc79..181ba172 100644 --- a/yazi-cli/src/package/install.rs +++ b/yazi-cli/src/package/install.rs @@ -9,7 +9,7 @@ impl Package { let path = self.local(); if !must_exists(&path).await { - Git::clone(&self.remote(), &path).await?; + Git::clone(&self.remote, &path).await?; } else { Git::fetch(&path).await?; }; diff --git a/yazi-cli/src/package/package.rs b/yazi-cli/src/package/package.rs index bee1db87..d4c34e24 100644 --- a/yazi-cli/src/package/package.rs +++ b/yazi-cli/src/package/package.rs @@ -2,28 +2,58 @@ use std::{borrow::Cow, io::BufWriter, path::PathBuf}; use anyhow::Result; use md5::{Digest, Md5}; +use url::Url; use yazi_shared::Xdg; pub(crate) struct Package { pub(crate) repo: String, pub(crate) child: String, + pub(crate) remote: String, pub(crate) commit: String, pub(super) is_flavor: bool, } impl Package { pub(super) fn new(url: &str, commit: Option<&str>) -> Self { - let mut parts = url.splitn(2, '#'); + match Url::parse(url) { + Ok(url) => { + let repo = url.path().trim_start_matches('/').to_string(); + let child = match url.fragment() { + Some(fragment) => format!("{fragment}.yazi"), + None => String::new(), + }; + let remote = url.to_string(); - let mut repo = parts.next().unwrap_or_default().to_owned(); - let child = if let Some(s) = parts.next() { - format!("{s}.yazi") - } else { - repo.push_str(".yazi"); - String::new() - }; + return Self { + repo, + child, + remote, + commit: commit.unwrap_or_default().to_owned(), + is_flavor: false, + }; + } + Err(_) => { + let mut parts = url.splitn(2, '#'); - Self { repo, child, commit: commit.unwrap_or_default().to_owned(), is_flavor: false } + let mut repo = parts.next().unwrap_or_default().to_owned(); + let child = if let Some(s) = parts.next() { + format!("{s}.yazi") + } else { + repo.push_str(".yazi"); + String::new() + }; + + let remote = format!("https://github.com/{}.git", repo); + + return Self { + repo, + child, + remote, + commit: commit.unwrap_or_default().to_owned(), + is_flavor: false, + }; + } + } } #[inline] @@ -50,13 +80,7 @@ impl Package { pub(super) fn local(&self) -> PathBuf { Xdg::state_dir() .join("packages") - .join(format!("{:x}", Md5::new_with_prefix(self.remote()).finalize())) - } - - #[inline] - pub(super) fn remote(&self) -> String { - // Support more Git hosting services in the future - format!("https://github.com/{}.git", self.repo) + .join(format!("{:x}", Md5::new_with_prefix(&self.remote).finalize())) } pub(super) fn output(&self, s: &str) -> Result<()> {