diff --git a/src/cli.rs b/src/cli.rs index 90e3d72..d606487 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -98,6 +98,7 @@ pub enum FetcherFunction { FetchFromGitiles, FetchFromRepoOrCz, FetchFromSourcehut, + FetchHex, Fetchgit, Fetchhg, Fetchsvn, diff --git a/src/fetcher/hex.rs b/src/fetcher/hex.rs new file mode 100644 index 0000000..f8646ea --- /dev/null +++ b/src/fetcher/hex.rs @@ -0,0 +1,28 @@ +use url::Url; + +use crate::{ + impl_fetcher, + simple::{SimpleFetcher, SimpleUrlFetcher}, +}; + +pub struct FetchHex; +impl_fetcher!(FetchHex); + +impl<'a> SimpleFetcher<'a, 1> for FetchHex { + const HASH_KEY: &'static str = "sha256"; + const KEYS: [&'static str; 1] = ["pkg"]; + const NAME: &'static str = "fetchHex"; + const REV_KEY: &'static str = "version"; + + fn get_values(&self, url: &'a Url) -> Option<[&'a str; 1]> { + Some([url.path_segments()?.nth(1)?]) + } +} + +impl<'a> SimpleUrlFetcher<'a, 1> for FetchHex { + const UNPACK: bool = false; + + fn get_url(&self, [pkg]: &[&str; 1], version: &str) -> String { + format!("https://repo.hex.pm/tarballs/{pkg}-{version}.tar") + } +} diff --git a/src/fetcher/mod.rs b/src/fetcher/mod.rs index 38d4756..bd593aa 100644 --- a/src/fetcher/mod.rs +++ b/src/fetcher/mod.rs @@ -5,6 +5,7 @@ mod gitea; mod github; mod gitiles; mod gitlab; +mod hex; mod hg; mod repo_or_cz; mod sourcehut; @@ -17,6 +18,7 @@ pub use gitea::FetchFromGitea; pub use github::FetchFromGitHub; pub use gitiles::FetchFromGitiles; pub use gitlab::FetchFromGitLab; +pub use hex::FetchHex; pub use hg::Fetchhg; pub use repo_or_cz::FetchFromRepoOrCz; pub use sourcehut::FetchFromSourcehut; @@ -80,6 +82,7 @@ pub enum FetcherDispatch<'a> { FetchFromGitiles(FetchFromGitiles), FetchFromRepoOrCz(FetchFromRepoOrCz), FetchFromSourcehut(FetchFromSourcehut<'a>), + FetchHex(FetchHex), Fetchgit(Fetchgit), Fetchhg(Fetchhg), Fetchsvn(Fetchsvn), diff --git a/src/main.rs b/src/main.rs index 491d9eb..3d6ba28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,8 @@ use crate::{ cli::{FetcherFunction, Opts}, fetcher::{ FetchCrate, FetchFromBitbucket, FetchFromGitHub, FetchFromGitLab, FetchFromGitea, - FetchFromGitiles, FetchFromRepoOrCz, FetchFromSourcehut, Fetcher, FetcherDispatch, - Fetchgit, Fetchhg, Fetchsvn, + FetchFromGitiles, FetchFromRepoOrCz, FetchFromSourcehut, FetchHex, Fetcher, + FetcherDispatch, Fetchgit, Fetchhg, Fetchsvn, }, }; @@ -126,6 +126,11 @@ fn main() -> Result<()> { bail!("{fetcher:?} does not support URLs without a host"); } + (None | Some(FetcherFunction::FetchHex), Some("hex.pm"), _) => FetchHex.into(), + (Some(FetcherFunction::FetchHex), ..) => { + bail!("fetchHex only supports hex.pm"); + } + (None | Some(FetcherFunction::Fetchgit), _, "git") => Fetchgit(GitScheme::Yes).into(), (None | Some(FetcherFunction::Fetchgit), _, scheme) if scheme.starts_with("git+") => { Fetchgit(GitScheme::Plus).into() diff --git a/src/prefetch.rs b/src/prefetch.rs index a79dfb0..b8d5b69 100644 --- a/src/prefetch.rs +++ b/src/prefetch.rs @@ -51,14 +51,17 @@ pub fn flake_prefetch(flake_ref: String) -> Result { .hash) } -pub fn url_prefetch(url: String) -> Result { - info!("$ nix-prefetch-url --unpack {url}"); - let hash = String::from_utf8( - Command::new("nix-prefetch-url") - .arg("--unpack") - .arg(url) - .get_stdout()?, - )?; +pub fn url_prefetch(url: String, unpack: bool) -> Result { + let mut cmd = Command::new("nix-prefetch-url"); + if unpack { + cmd.arg("--unpack"); + info!("$ nix-prefetch-url --unpack {url}"); + } else { + info!("$ nix-prefetch-url {url}"); + } + cmd.arg(url); + + let hash = String::from_utf8(cmd.get_stdout()?)?; let hash = hash.trim_end(); info!("$ nix hash to-sri --experimental-features nix-command --type sha256 {hash}"); diff --git a/src/simple.rs b/src/simple.rs index d1cbdec..7e1ccdd 100644 --- a/src/simple.rs +++ b/src/simple.rs @@ -237,6 +237,8 @@ pub trait SimpleFlakeFetcher<'a, const N: usize>: SimpleFetcher<'a, N> { } pub trait SimpleUrlFetcher<'a, const N: usize>: SimpleFetcher<'a, N> { + const UNPACK: bool = true; + fn get_url(&self, values: &[&str; N], rev: &str) -> String; fn fetch( @@ -247,7 +249,7 @@ pub trait SimpleUrlFetcher<'a, const N: usize>: SimpleFetcher<'a, N> { args_str: &[(String, String)], ) -> Result { if args.is_empty() && args_str.is_empty() { - url_prefetch(self.get_url(values, rev)) + url_prefetch(self.get_url(values, rev), Self::UNPACK) } else { self.fetch_fod(values, rev, args, args_str) } diff --git a/tests/cmd/fetcher/hex.stdout b/tests/cmd/fetcher/hex.stdout new file mode 100644 index 0000000..9945144 --- /dev/null +++ b/tests/cmd/fetcher/hex.stdout @@ -0,0 +1,5 @@ +fetchHex { + pkg = "phoenix"; + version = "1.6.0"; + sha256 = "sha256-Uv/dMfLa6zmbLh61fUaPmaGtbu5djqGdI1NJLwbJ/JY="; +} \ No newline at end of file diff --git a/tests/cmd/fetcher/hex.toml b/tests/cmd/fetcher/hex.toml new file mode 100644 index 0000000..527bf27 --- /dev/null +++ b/tests/cmd/fetcher/hex.toml @@ -0,0 +1 @@ +args = ["https://hex.pm/packages/phoenix", "1.6.0"]