From 08f73cc8f28a0802412fac2158eaaff9010cb206 Mon Sep 17 00:00:00 2001 From: dm9pZCAq <46228973+dm9pZCAq@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:54:26 +0300 Subject: [PATCH] feat: yazi-cli: support different Git hosting services --- yazi-cli/src/package/deploy.rs | 2 +- yazi-cli/src/package/package.rs | 52 +++++++++++++++++++++------------ yazi-cli/src/package/parser.rs | 15 +++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/yazi-cli/src/package/deploy.rs b/yazi-cli/src/package/deploy.rs index 6bdc10564..a3b71103f 100644 --- a/yazi-cli/src/package/deploy.rs +++ b/yazi-cli/src/package/deploy.rs @@ -8,7 +8,7 @@ const TRACKER: &str = "DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY"; impl Package { pub(super) async fn deploy(&mut self) -> Result<()> { - let Some(name) = self.name().map(ToOwned::to_owned) else { bail!("Invalid package url") }; + let name = self.name().to_owned(); let from = self.local().join(&self.child); self.header("Deploying package `{name}`")?; diff --git a/yazi-cli/src/package/package.rs b/yazi-cli/src/package/package.rs index 5a8034cf6..d500f0ff9 100644 --- a/yazi-cli/src/package/package.rs +++ b/yazi-cli/src/package/package.rs @@ -1,49 +1,64 @@ use std::{borrow::Cow, io::BufWriter, path::PathBuf}; -use anyhow::Result; +use anyhow::{Context, Result}; use md5::{Digest, Md5}; use yazi_shared::Xdg; pub(crate) struct Package { - pub(crate) repo: String, + pub(crate) host: String, + pub(crate) owner: String, + pub(crate) repo_name: String, pub(crate) child: String, pub(crate) rev: String, pub(super) is_flavor: bool, } impl Package { - pub(super) fn new(url: &str, rev: Option<&str>) -> Self { + pub(super) fn new(url: &str, rev: Option<&str>) -> Result { let mut parts = url.splitn(2, ':'); - let mut repo = parts.next().unwrap_or_default().to_owned(); + let mut repo_part = parts.next().unwrap_or_default().to_owned(); let child = if let Some(s) = parts.next() { format!("{s}.yazi") } else { - repo.push_str(".yazi"); + repo_part.push_str(".yazi"); String::new() }; - Self { repo, child, rev: rev.unwrap_or_default().to_owned(), is_flavor: false } + let mut repo = repo_part.rsplit('/'); + let repo_name = repo.next().context("failed to get repo name")?.to_owned(); + let owner = repo.next().context("failed to get repo owner")?.to_owned(); + let host = repo.next().unwrap_or("github.com").to_owned(); + + Ok(Self { + repo_name, + owner, + host, + child, + rev: rev.unwrap_or_default().to_owned(), + is_flavor: false, + }) } #[inline] pub(super) fn use_(&self) -> Cow { if self.child.is_empty() { - self.repo.trim_end_matches(".yazi").into() + format!("{}/{}/{}", self.host, self.owner, self.repo_name.trim_end_matches(".yazi")).into() } else { - format!("{}:{}", self.repo, self.child.trim_end_matches(".yazi")).into() + format!( + "{}/{}/{}:{}", + self.host, + self.owner, + self.repo_name, + self.child.trim_end_matches(".yazi") + ) + .into() } } #[inline] - pub(super) fn name(&self) -> Option<&str> { - let s = if self.child.is_empty() { - self.repo.split('/').last().filter(|s| !s.is_empty()) - } else { - Some(self.child.as_str()) - }; - - s.filter(|s| s.bytes().all(|b| matches!(b, b'0'..=b'9' | b'a'..=b'z' | b'-' | b'.'))) + pub(super) fn name(&self) -> &str { + if self.child.is_empty() { self.repo_name.as_str() } else { self.child.as_str() } } #[inline] @@ -55,8 +70,7 @@ impl Package { #[inline] pub(super) fn remote(&self) -> String { - // Support more Git hosting services in the future - format!("https://github.com/{}.git", self.repo) + format!("https://{}/{}/{}.git", self.host, self.owner, self.repo_name) } pub(super) fn header(&self, s: &str) -> Result<()> { @@ -68,7 +82,7 @@ impl Package { SetAttributes(Attribute::Reverse.into()), SetAttributes(Attribute::Bold.into()), Print(" "), - Print(s.replacen("{name}", self.name().unwrap_or_default(), 1)), + Print(s.replacen("{name}", self.name(), 1)), Print(" "), SetAttributes(Attribute::Reset.into()), Print("\n\n"), diff --git a/yazi-cli/src/package/parser.rs b/yazi-cli/src/package/parser.rs index c58020e89..68e8d065b 100644 --- a/yazi-cli/src/package/parser.rs +++ b/yazi-cli/src/package/parser.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Result, bail}; +use anyhow::{bail, Context, Result}; use tokio::fs; use toml_edit::{Array, DocumentMut, InlineTable, Item, Value}; use yazi_shared::Xdg; @@ -34,8 +34,8 @@ impl Package { } pub(crate) async fn add_to_config(use_: &str) -> Result<()> { - let mut package = Self::new(use_, None); - let Some(name) = package.name() else { bail!("Invalid package `use`") }; + let mut package = Self::new(use_, None).context("Invalid package `use`")?; + let name = package.name(); let path = Xdg::config_dir().join("package.toml"); let mut doc = Self::ensure_config(&fs::read_to_string(&path).await.unwrap_or_default())?; @@ -76,7 +76,7 @@ impl Package { let use_ = dep.get("use").and_then(|d| d.as_str()).context("Missing `use` field")?; let rev = dep.get("rev").and_then(|d| d.as_str()); - let mut package = Package::new(use_, rev); + let mut package = Package::new(use_, rev)?; if upgrade { package.upgrade().await?; } else { @@ -144,10 +144,9 @@ impl Package { fn ensure_unique(doc: &DocumentMut, name: &str) -> Result<()> { #[inline] fn same(v: &Value, name: &str) -> bool { - v.as_inline_table() - .and_then(|t| t.get("use")) - .and_then(|v| v.as_str()) - .is_some_and(|s| Package::new(s, None).name() == Some(name)) + v.as_inline_table().and_then(|t| t.get("use")).and_then(|v| v.as_str()).is_some_and(|s| { + if let Ok(pkg) = Package::new(s, None) { pkg.name() == name } else { false } + }) } if doc["plugin"]["deps"].as_array().unwrap().into_iter().any(|v| same(v, name)) {