From d102bc36e6d62d6723d0302c9c44ad3907a58eff Mon Sep 17 00:00:00 2001 From: figsoda Date: Thu, 12 Jan 2023 16:49:14 -0500 Subject: [PATCH] fetchCrate support --- src/cli.rs | 1 + src/fetcher/crates_io.rs | 33 ++++++++++++++++++++++ src/fetcher/mod.rs | 5 +++- src/main.rs | 12 ++++++-- src/simple.rs | 22 +++++++-------- tests/cmd/fetcher/crates_io/basic.stdout | 5 ++++ tests/cmd/fetcher/crates_io/basic.toml | 1 + tests/cmd/fetcher/crates_io/install.stdout | 5 ++++ tests/cmd/fetcher/crates_io/install.toml | 1 + tests/cmd/fetcher/crates_io/lib_rs.stdout | 5 ++++ tests/cmd/fetcher/crates_io/lib_rs.toml | 1 + tests/cmd/fetcher/crates_io/short.stdout | 5 ++++ tests/cmd/fetcher/crates_io/short.toml | 1 + 13 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 src/fetcher/crates_io.rs create mode 100644 tests/cmd/fetcher/crates_io/basic.stdout create mode 100644 tests/cmd/fetcher/crates_io/basic.toml create mode 100644 tests/cmd/fetcher/crates_io/install.stdout create mode 100644 tests/cmd/fetcher/crates_io/install.toml create mode 100644 tests/cmd/fetcher/crates_io/lib_rs.stdout create mode 100644 tests/cmd/fetcher/crates_io/lib_rs.toml create mode 100644 tests/cmd/fetcher/crates_io/short.stdout create mode 100644 tests/cmd/fetcher/crates_io/short.toml diff --git a/src/cli.rs b/src/cli.rs index 6bcddab..90e3d72 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -90,6 +90,7 @@ pub struct Opts { #[derive(Clone, Debug, ValueEnum)] #[clap(rename_all = "camelCase")] pub enum FetcherFunction { + FetchCrate, FetchFromBitbucket, FetchFromGitHub, FetchFromGitLab, diff --git a/src/fetcher/crates_io.rs b/src/fetcher/crates_io.rs new file mode 100644 index 0000000..a5954b9 --- /dev/null +++ b/src/fetcher/crates_io.rs @@ -0,0 +1,33 @@ +use url::Url; + +use crate::{ + impl_fetcher, + simple::{SimpleFetcher, SimpleUrlFetcher}, +}; + +pub struct FetchCrate(pub bool); +impl_fetcher!(FetchCrate); + +impl<'a> SimpleFetcher<'a, 1> for FetchCrate { + const KEYS: [&'static str; 1] = ["pname"]; + const NAME: &'static str = "fetchCrate"; + const REV_KEY: &'static str = "version"; + + fn get_values(&self, url: &'a Url) -> Option<[&'a str; 1]> { + let mut xs = url.path_segments()?; + Some([if self.0 { + xs.nth(1)? + } else { + match xs.next()? { + "crates" | "install" => xs.next()?, + pname => pname, + } + }]) + } +} + +impl<'a> SimpleUrlFetcher<'a, 1> for FetchCrate { + fn get_url(&self, [pname]: &[&str; 1], version: &str) -> String { + format!("https://crates.io/api/v1/crates/{pname}/{version}/download") + } +} diff --git a/src/fetcher/mod.rs b/src/fetcher/mod.rs index 026e5d7..38d4756 100644 --- a/src/fetcher/mod.rs +++ b/src/fetcher/mod.rs @@ -1,4 +1,5 @@ mod bitbucket; +mod crates_io; mod git; mod gitea; mod github; @@ -10,6 +11,7 @@ mod sourcehut; mod svn; pub use bitbucket::FetchFromBitbucket; +pub use crates_io::FetchCrate; pub use git::Fetchgit; pub use gitea::FetchFromGitea; pub use github::FetchFromGitHub; @@ -70,6 +72,7 @@ pub trait Fetcher<'a> { #[enum_dispatch(Fetcher)] pub enum FetcherDispatch<'a> { + FetchCrate(FetchCrate), FetchFromBitbucket(FetchFromBitbucket), FetchFromGitHub(FetchFromGitHub<'a>), FetchFromGitLab(FetchFromGitLab<'a>), @@ -194,7 +197,7 @@ macro_rules! impl_fetcher { fetcher_args["group"] = json!(group); } if let Some(rev) = rev { - fetcher_args["rev"] = json!(rev); + fetcher_args[Self::REV_KEY] = json!(rev); } serde_json::to_writer( diff --git a/src/main.rs b/src/main.rs index d77403a..491d9eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,9 @@ use rustc_hash::FxHashMap; use crate::{ cli::{FetcherFunction, Opts}, fetcher::{ - FetchFromBitbucket, FetchFromGitHub, FetchFromGitLab, FetchFromGitea, FetchFromGitiles, - FetchFromRepoOrCz, FetchFromSourcehut, Fetcher, FetcherDispatch, Fetchgit, Fetchhg, - Fetchsvn, + FetchCrate, FetchFromBitbucket, FetchFromGitHub, FetchFromGitLab, FetchFromGitea, + FetchFromGitiles, FetchFromRepoOrCz, FetchFromSourcehut, Fetcher, FetcherDispatch, + Fetchgit, Fetchhg, Fetchsvn, }, }; @@ -54,6 +54,12 @@ fn main() -> Result<()> { } let fetcher: FetcherDispatch = match (opts.fetcher, opts.url.host_str(), opts.url.scheme()) { + (None | Some(FetcherFunction::FetchCrate), Some("crates.io"), _) => FetchCrate(true).into(), + (None | Some(FetcherFunction::FetchCrate), Some("lib.rs"), _) => FetchCrate(false).into(), + (Some(FetcherFunction::FetchCrate), ..) => { + bail!("fetchCrate only supports crates.io and lib.rs"); + } + (None | Some(FetcherFunction::FetchFromBitbucket), Some("bitbucket.org"), _) => { FetchFromBitbucket.into() } diff --git a/src/simple.rs b/src/simple.rs index 4e31252..d1cbdec 100644 --- a/src/simple.rs +++ b/src/simple.rs @@ -9,10 +9,11 @@ use std::{fmt::Write as _, io::Write}; use crate::prefetch::{flake_prefetch, fod_prefetch, url_prefetch}; pub trait SimpleFetcher<'a, const N: usize> { - const HOST_KEY: &'static str = "domain"; const HASH_KEY: &'static str = "hash"; + const HOST_KEY: &'static str = "domain"; const KEYS: [&'static str; N]; const NAME: &'static str; + const REV_KEY: &'static str = "rev"; fn host(&'a self) -> Option<&'a str> { None @@ -65,7 +66,8 @@ pub trait SimpleFetcher<'a, const N: usize> { write!( expr, - r#"rev="{rev}";{}="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";"#, + r#"{}="{rev}";{}="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";"#, + Self::REV_KEY, Self::HASH_KEY, )?; @@ -116,10 +118,10 @@ pub trait SimpleFetcher<'a, const N: usize> { } } - if let Some(rev) = overwrites.remove("rev") { - writeln!(out, "{indent} rev = {rev};")?; + if let Some(rev) = overwrites.remove(Self::REV_KEY) { + writeln!(out, "{indent} {} = {rev};", Self::REV_KEY)?; } else { - writeln!(out, r#"{indent} rev = "{rev}";"#)?; + writeln!(out, r#"{indent} {} = "{rev}";"#, Self::REV_KEY)?; } if let Some(hash) = overwrites.remove(Self::HASH_KEY) { writeln!(out, "{indent} {} = {hash};", Self::HASH_KEY)?; @@ -159,12 +161,10 @@ pub trait SimpleFetcher<'a, const N: usize> { overwrites: Vec<(String, String)>, overwrites_str: Vec<(String, String)>, ) -> Result<()> { - let mut fetcher_args = Value::from_iter( - Self::KEYS - .into_iter() - .zip(*values) - .chain([("rev", rev.as_ref()), (Self::HASH_KEY, hash.as_ref())]), - ); + let mut fetcher_args = Value::from_iter(Self::KEYS.into_iter().zip(*values).chain([ + (Self::REV_KEY, rev.as_ref()), + (Self::HASH_KEY, hash.as_ref()), + ])); if let Some(host) = self.host() { fetcher_args[Self::HOST_KEY] = json!(host); diff --git a/tests/cmd/fetcher/crates_io/basic.stdout b/tests/cmd/fetcher/crates_io/basic.stdout new file mode 100644 index 0000000..5c66182 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/basic.stdout @@ -0,0 +1,5 @@ +fetchCrate { + pname = "nurl"; + version = "0.3.0"; + hash = "sha256-B6T4DEhE2Jq3YSL+b//27gRkQlvqhynSMBCGdYD5Gog="; +} \ No newline at end of file diff --git a/tests/cmd/fetcher/crates_io/basic.toml b/tests/cmd/fetcher/crates_io/basic.toml new file mode 100644 index 0000000..2941fbb --- /dev/null +++ b/tests/cmd/fetcher/crates_io/basic.toml @@ -0,0 +1 @@ +args = ["https://crates.io/crates/nurl", "0.3.0"] diff --git a/tests/cmd/fetcher/crates_io/install.stdout b/tests/cmd/fetcher/crates_io/install.stdout new file mode 100644 index 0000000..5c66182 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/install.stdout @@ -0,0 +1,5 @@ +fetchCrate { + pname = "nurl"; + version = "0.3.0"; + hash = "sha256-B6T4DEhE2Jq3YSL+b//27gRkQlvqhynSMBCGdYD5Gog="; +} \ No newline at end of file diff --git a/tests/cmd/fetcher/crates_io/install.toml b/tests/cmd/fetcher/crates_io/install.toml new file mode 100644 index 0000000..2538ee6 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/install.toml @@ -0,0 +1 @@ +args = ["https://lib.rs/install/nurl", "0.3.0"] diff --git a/tests/cmd/fetcher/crates_io/lib_rs.stdout b/tests/cmd/fetcher/crates_io/lib_rs.stdout new file mode 100644 index 0000000..5c66182 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/lib_rs.stdout @@ -0,0 +1,5 @@ +fetchCrate { + pname = "nurl"; + version = "0.3.0"; + hash = "sha256-B6T4DEhE2Jq3YSL+b//27gRkQlvqhynSMBCGdYD5Gog="; +} \ No newline at end of file diff --git a/tests/cmd/fetcher/crates_io/lib_rs.toml b/tests/cmd/fetcher/crates_io/lib_rs.toml new file mode 100644 index 0000000..9bdcb08 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/lib_rs.toml @@ -0,0 +1 @@ +args = ["https://lib.rs/crates/nurl", "0.3.0"] diff --git a/tests/cmd/fetcher/crates_io/short.stdout b/tests/cmd/fetcher/crates_io/short.stdout new file mode 100644 index 0000000..5c66182 --- /dev/null +++ b/tests/cmd/fetcher/crates_io/short.stdout @@ -0,0 +1,5 @@ +fetchCrate { + pname = "nurl"; + version = "0.3.0"; + hash = "sha256-B6T4DEhE2Jq3YSL+b//27gRkQlvqhynSMBCGdYD5Gog="; +} \ No newline at end of file diff --git a/tests/cmd/fetcher/crates_io/short.toml b/tests/cmd/fetcher/crates_io/short.toml new file mode 100644 index 0000000..cc25dfa --- /dev/null +++ b/tests/cmd/fetcher/crates_io/short.toml @@ -0,0 +1 @@ +args = ["https://lib.rs/nurl", "0.3.0"]