fetchFromGitea and codeberg support

This commit is contained in:
figsoda 2022-12-31 14:39:33 -05:00
parent 409ae12a11
commit bc21735656
9 changed files with 114 additions and 12 deletions

View File

@ -50,6 +50,7 @@ pub struct Opts {
#[derive(Clone, Debug, ValueEnum)]
#[clap(rename_all = "camelCase")]
pub enum FetcherFunction {
FetchFromGitea,
FetchFromGitHub,
FetchFromGitLab,
FetchFromSourcehut,

View File

@ -2,7 +2,7 @@ mod cvs;
mod simple;
pub use cvs::{CvsFetcher, CvsFlakeFetcher, CvsFodFetcher};
pub use simple::{SimpleFetcher, SimpleFlakeFetcher, SimpleFodFetcher};
pub use simple::{SimpleFetcher, SimpleFlakeFetcher, SimpleFodFetcher, SimpleUrlFetcher};
use anyhow::{anyhow, bail, Result};
use serde::Deserialize;
@ -44,6 +44,30 @@ pub fn flake_prefetch(flake_ref: String) -> Result<String> {
.hash)
}
pub fn url_prefetch(url: String) -> Result<String> {
eprintln!("nix-prefetch-url --unpack {url}");
let hash = String::from_utf8(
Command::new("nix-prefetch-url")
.arg("--unpack")
.arg(url)
.get_stdout()?,
)?;
let hash = hash.trim_end();
eprintln!("nix hash to-sri --type sha256 {hash}");
Ok(String::from_utf8(
Command::new("nix")
.arg("hash")
.arg("to-sri")
.arg("--type")
.arg("sha256")
.arg(hash)
.get_stdout()?,
)?
.trim_end()
.into())
}
pub fn fod_prefetch(expr: String) -> Result<String> {
eprintln!("$ nix build --impure --no-link --expr '{expr}'");

View File

@ -5,13 +5,13 @@ use url::Url;
use std::{fmt::Write as _, io::Write};
use crate::common::{flake_prefetch, fod_prefetch};
use crate::common::{flake_prefetch, fod_prefetch, url_prefetch};
pub trait SimpleFetcher<'a> {
const HOST_KEY: &'static str = "domain";
const NAME: &'static str;
fn host(&'a self) -> &'a Option<String>;
fn host(&'a self) -> Option<&'a str>;
fn get_repo(&self, url: &Url) -> Option<(String, String)> {
let mut xs = url.path_segments()?;
@ -195,3 +195,47 @@ pub trait SimpleFlakeFetcher<'a>: SimpleFetcher<'a> {
self.write_json(out, owner, repo, rev, hash, args)
}
}
pub trait SimpleUrlFetcher<'a>: SimpleFetcher<'a> {
fn get_url(&self, owner: &str, repo: &str, rev: &str) -> String;
fn fetch(&'a self, url: &Url, rev: &str) -> Result<(String, String, String)> {
let (owner, repo) = self
.get_repo(url)
.with_context(|| format!("failed to parse {url}"))?;
let hash = url_prefetch(self.get_url(&owner, &repo, rev))?;
Ok((owner, repo, hash))
}
fn fetch_nix_impl(
&'a self,
out: &mut impl Write,
url: Url,
rev: String,
args: Vec<(String, String)>,
indent: String,
) -> Result<()> {
let (owner, repo, hash) = if args.is_empty() {
self.fetch(&url, &rev)?
} else {
self.fetch_fod(&url, &rev, &args)?
};
self.write_nix(out, owner, repo, rev, hash, args, indent)
}
fn fetch_json_impl(
&'a self,
out: &mut impl Write,
url: Url,
rev: String,
args: Vec<(String, String)>,
) -> Result<()> {
let (owner, repo, hash) = if args.is_empty() {
self.fetch(&url, &rev)?
} else {
self.fetch_fod(&url, &rev, &args)?
};
self.write_json(out, owner, repo, rev, hash, args)
}
}

21
src/fetcher/gitea.rs Normal file
View File

@ -0,0 +1,21 @@
use crate::{
common::{SimpleFetcher, SimpleUrlFetcher},
impl_fetcher,
};
pub struct FetchFromGitea(pub String);
impl_fetcher!(FetchFromGitea);
impl<'a> SimpleFetcher<'a> for FetchFromGitea {
const NAME: &'static str = "fetchFromGitea";
fn host(&'a self) -> Option<&'a str> {
Some(&self.0)
}
}
impl<'a> SimpleUrlFetcher<'a> for FetchFromGitea {
fn get_url(&self, owner: &str, repo: &str, rev: &str) -> String {
format!("https://{}/{owner}/{repo}/archive/{rev}.tar.gz", self.0)
}
}

View File

@ -10,8 +10,8 @@ impl<'a> SimpleFetcher<'a> for FetchFromGitHub {
const HOST_KEY: &'static str = "githubBase";
const NAME: &'static str = "fetchFromGitHub";
fn host(&'a self) -> &'a Option<String> {
&self.0
fn host(&'a self) -> Option<&'a str> {
self.0.as_deref()
}
}

View File

@ -9,8 +9,8 @@ impl_fetcher!(FetchFromGitLab);
impl<'a> SimpleFetcher<'a> for FetchFromGitLab {
const NAME: &'static str = "fetchFromGitLab";
fn host(&'a self) -> &'a Option<String> {
&self.0
fn host(&'a self) -> Option<&'a str> {
self.0.as_deref()
}
}

View File

@ -1,10 +1,12 @@
mod git;
mod gitea;
mod github;
mod gitlab;
mod hg;
mod sourcehut;
pub use git::Fetchgit;
pub use gitea::FetchFromGitea;
pub use github::FetchFromGitHub;
pub use gitlab::FetchFromGitLab;
pub use hg::Fetchhg;
@ -37,6 +39,7 @@ pub trait Fetcher {
#[enum_dispatch(Fetcher)]
pub enum FetcherDispatch {
FetchFromGitea(FetchFromGitea),
FetchFromGitHub(FetchFromGitHub),
FetchFromGitLab(FetchFromGitLab),
FetchFromSourcehut(FetchFromSourcehut),

View File

@ -9,8 +9,8 @@ impl_fetcher!(FetchFromSourcehut);
impl<'a> SimpleFetcher<'a> for FetchFromSourcehut {
const NAME: &'static str = "fetchFromSourcehut";
fn host(&'a self) -> &'a Option<String> {
&self.0
fn host(&'a self) -> Option<&'a str> {
self.0.as_deref()
}
}

View File

@ -12,8 +12,8 @@ use url::Host;
use crate::{
cli::{FetcherFunction, Opts},
fetcher::{
FetchFromGitHub, FetchFromGitLab, FetchFromSourcehut, Fetcher, FetcherDispatch, Fetchgit,
Fetchhg,
FetchFromGitHub, FetchFromGitLab, FetchFromGitea, FetchFromSourcehut, Fetcher,
FetcherDispatch, Fetchgit, Fetchhg,
},
};
@ -36,6 +36,14 @@ fn main() -> Result<()> {
}
let fetcher: FetcherDispatch = match (opts.fetcher, opts.url.host()) {
(
None | Some(FetcherFunction::FetchFromGitea),
Some(Host::Domain(host @ "codeberg.org")),
) => FetchFromGitea(host.into()).into(),
(Some(FetcherFunction::FetchFromGitea), Some(host)) => {
FetchFromGitea(host.to_string()).into()
}
(None | Some(FetcherFunction::FetchFromGitHub), Some(Host::Domain("github.com"))) => {
FetchFromGitHub(None).into()
}
@ -62,7 +70,8 @@ fn main() -> Result<()> {
(
Some(
fetcher @ (FetcherFunction::FetchFromGitHub
fetcher @ (FetcherFunction::FetchFromGitea
| FetcherFunction::FetchFromGitHub
| FetcherFunction::FetchFromGitLab
| FetcherFunction::FetchFromSourcehut),
),