initial implementation

This commit is contained in:
figsoda 2022-12-29 21:04:19 -05:00
parent cfdf4e6a68
commit eafb9ebb32
12 changed files with 786 additions and 4 deletions

View File

@ -1 +1,5 @@
# Changelog
## v0.1.0 - 2022-12-29
First release

470
Cargo.lock generated
View File

@ -2,6 +2,476 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
[[package]]
name = "clap"
version = "4.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
dependencies = [
"bitflags",
"clap_derive",
"clap_lex",
"is-terminal",
"once_cell",
"strsim",
"termcolor",
"terminal_size",
"unicase",
"unicode-width",
]
[[package]]
name = "clap_derive"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "form_urlencoded"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
"percent-encoding",
]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indoc"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2d6f23ffea9d7e76c53eee25dfb67bcd8fde7f1198b0855350698c9f07c780"
[[package]]
name = "io-lifetimes"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "is-terminal"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "nurl"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"indoc",
"serde",
"serde_json",
"url",
]
[[package]]
name = "once_cell"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "os_str_bytes"
version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustix"
version = "0.36.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "ryu"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "serde"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907"
dependencies = [
"rustix",
"windows-sys",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"

View File

@ -3,15 +3,24 @@ name = "nurl"
version = "0.1.0"
authors = ["figsoda <figsoda@pm.me>"]
edition = "2021"
description = ""
description = "Generate Nix fetcher calls from repository URLs"
readme = "README.md"
homepage = "https://github.com/nix-community/nurl"
repository = "https://github.com/nix-community/nurl"
license = "MPL-2.0"
keywords = []
categories = []
keywords = ["cli", "fetch", "git", "nix", "prefetch"]
categories = ["command-line-utilities"]
[dependencies]
anyhow = "1.0.68"
indoc = "1.0.8"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.91"
url = "2.3.1"
[dependencies.clap]
version = "4.0.32"
features = ["cargo", "derive", "unicode", "wrap_help"]
[profile.release]
lto = true

View File

@ -6,6 +6,8 @@
[![license](https://img.shields.io/badge/license-MPL--2.0-blue?style=flat-square)](https://www.mozilla.org/en-US/MPL/2.0)
[![ci](https://img.shields.io/github/actions/workflow/status/nix-community/nurl/ci.yml?label=ci&logo=github-actions&style=flat-square)](https://github.com/nix-community/nurl/actions?query=workflow:ci)
Generate Nix fetcher calls from repository URLs
## Installation
@ -27,6 +29,23 @@ cargo build --release
## Usage
```
Generate Nix fetcher calls from repository URLs
https://github.com/nix-community/nurl
Usage: nurl [OPTIONS] <URL> <REV>
Arguments:
<URL> URL to the repository to be fetched
<REV> the revision or reference to be fetched
Options:
-f, --fetcher <FETCHER> specify the fetcher function instead of inferring from the URL [possible values: fetchFromGitHub, fetchFromGitLab, fetchFromSourcehut, fetchgit, fetchhg]
-i, --indent <INDENT> extra indentation (in number of spaces) [default: 0]
-h, --help Print help information
-V, --version Print version information
```
## Changelog
See [CHANGELOG.md](CHANGELOG.md)

32
src/cli.rs Normal file
View File

@ -0,0 +1,32 @@
use clap::{Parser, ValueEnum};
use url::Url;
/// Generate Nix fetcher calls from repository URLs
/// https://github.com/nix-community/nurl
#[derive(Parser)]
#[command(version, verbatim_doc_comment)]
pub struct Opts {
/// URL to the repository to be fetched
pub url: Url,
/// the revision or reference to be fetched
pub rev: String,
/// specify the fetcher function instead of inferring from the URL
#[arg(short, long)]
pub fetcher: Option<Fetcher>,
/// extra indentation (in number of spaces)
#[arg(short, long, default_value_t = 0)]
pub indent: usize,
}
#[derive(Clone, ValueEnum)]
#[clap(rename_all = "camelCase")]
pub enum Fetcher {
FetchFromGitHub,
FetchFromGitLab,
FetchFromSourcehut,
Fetchgit,
Fetchhg,
}

8
src/fetcher/git.rs Normal file
View File

@ -0,0 +1,8 @@
use crate::fetcher::UrlFlakeFetcher;
pub struct Fetchgit;
impl UrlFlakeFetcher for Fetchgit {
const NAME: &'static str = "fetchgit";
const FLAKE_TYPE: &'static str = "git";
}

12
src/fetcher/github.rs Normal file
View File

@ -0,0 +1,12 @@
use crate::fetcher::SimpleFlakeFetcher;
pub struct FetchFromGitHub<'a>(pub Option<&'a str>);
impl<'a> SimpleFlakeFetcher<'a> for FetchFromGitHub<'a> {
const FLAKE_TYPE: &'static str = "github";
const NAME: &'static str = "fetchFromGitHub";
fn host(&self) -> Option<&'a str> {
self.0
}
}

12
src/fetcher/gitlab.rs Normal file
View File

@ -0,0 +1,12 @@
use crate::fetcher::SimpleFlakeFetcher;
pub struct FetchFromGitLab<'a>(pub Option<&'a str>);
impl<'a> SimpleFlakeFetcher<'a> for FetchFromGitLab<'a> {
const FLAKE_TYPE: &'static str = "gitlab";
const NAME: &'static str = "fetchFromGitLab";
fn host(&self) -> Option<&'a str> {
self.0
}
}

8
src/fetcher/hg.rs Normal file
View File

@ -0,0 +1,8 @@
use crate::fetcher::UrlFlakeFetcher;
pub struct Fetchhg;
impl UrlFlakeFetcher for Fetchhg {
const FLAKE_TYPE: &'static str = "hg";
const NAME: &'static str = "fetchhg";
}

130
src/fetcher/mod.rs Normal file
View File

@ -0,0 +1,130 @@
mod git;
mod github;
mod gitlab;
mod hg;
mod sourcehut;
pub use git::Fetchgit;
pub use github::FetchFromGitHub;
pub use gitlab::FetchFromGitLab;
pub use hg::Fetchhg;
use indoc::writedoc;
pub use sourcehut::FetchFromSourcehut;
use anyhow::{bail, Context, Result};
use serde::Deserialize;
use url::Url;
use std::{
io::Write,
process::{Command, Output, Stdio},
};
pub trait Fetcher {
fn fetch_nix(&self, out: &mut impl Write, url: &Url, rev: String, indent: &str) -> Result<()>;
}
trait GetStdout {
fn get_stdout(&mut self) -> Result<Vec<u8>>;
}
impl GetStdout for Command {
fn get_stdout(&mut self) -> Result<Vec<u8>> {
let Output { stdout, status, .. } = self.stderr(Stdio::inherit()).output()?;
if !status.success() {
bail!("command exited with exit code {}", status);
}
Ok(stdout)
}
}
pub fn flake_prefetch(flake_ref: String) -> Result<String> {
#[derive(Deserialize)]
struct PrefetchOutput {
hash: String,
}
eprintln!("$ nix flake prefetch --json {flake_ref}");
Ok(serde_json::from_slice::<PrefetchOutput>(
&Command::new("nix")
.arg("flake")
.arg("prefetch")
.arg("--json")
.arg(flake_ref)
.get_stdout()?,
)?
.hash)
}
pub trait SimpleFlakeFetcher<'a> {
const NAME: &'static str;
const FLAKE_TYPE: &'static str;
fn host(&self) -> Option<&'a str>;
fn get_repo(&self, url: &Url) -> Option<(String, String)> {
let mut xs = url.path_segments()?;
let owner = xs.next()?;
let repo = xs.next()?;
Some((
owner.into(),
repo.strip_suffix(".git").unwrap_or(repo).into(),
))
}
fn fetch_nix(&self, out: &mut impl Write, url: &Url, rev: String, indent: &str) -> Result<()> {
let (owner, repo) = self
.get_repo(url)
.with_context(|| format!("failed to parse {url} as a {} url", Self::FLAKE_TYPE))?;
let hash = flake_prefetch(if let Some(host) = self.host() {
format!("{}:{owner}/{repo}/{rev}?host={}", Self::FLAKE_TYPE, host)
} else {
format!("{}:{owner}/{repo}/{rev}", Self::FLAKE_TYPE)
})?;
writeln!(out, "{} {{", Self::NAME)?;
if let Some(domain) = self.host() {
writeln!(out, r#"{indent} domain = "{domain}";"#)?;
}
writedoc!(
out,
r#"
{indent} owner = "{owner}";
{indent} repo = "{repo}";
{indent} rev = "{rev}";
{indent} hash = "{hash}";
{indent}}}"#,
)?;
Ok(())
}
}
pub(crate) trait UrlFlakeFetcher {
const NAME: &'static str;
const FLAKE_TYPE: &'static str;
fn fetch_nix(&self, out: &mut impl Write, url: &Url, rev: String, indent: &str) -> Result<()> {
let hash = flake_prefetch(format!(
"{}+{url}?{}={rev}",
Self::FLAKE_TYPE,
if rev.len() == 40 { "rev" } else { "ref" },
))?;
writedoc!(
out,
r#"
{} {{
{indent} url = "{url}";
{indent} rev = "{rev}";
{indent} hash = "{hash}";
{indent}}}"#,
Self::NAME,
)?;
Ok(())
}
}

12
src/fetcher/sourcehut.rs Normal file
View File

@ -0,0 +1,12 @@
use crate::fetcher::SimpleFlakeFetcher;
pub struct FetchFromSourcehut<'a>(pub Option<&'a str>);
impl<'a> SimpleFlakeFetcher<'a> for FetchFromSourcehut<'a> {
const FLAKE_TYPE: &'static str = "sourcehut";
const NAME: &'static str = "fetchFromSourcehut";
fn host(&self) -> Option<&'a str> {
self.0
}
}

View File

@ -1 +1,67 @@
fn main() {}
mod cli;
mod fetcher;
use anyhow::{bail, Result};
use clap::Parser;
use url::Host;
use crate::{
cli::{Fetcher, Opts},
fetcher::{
FetchFromGitHub, FetchFromGitLab, FetchFromSourcehut, Fetchgit, Fetchhg,
SimpleFlakeFetcher, UrlFlakeFetcher,
},
};
use std::io::stdout;
fn main() -> Result<()> {
let opts = Opts::parse();
let out = &mut stdout().lock();
let indent = &" ".repeat(opts.indent);
match (opts.fetcher, opts.url.host()) {
(Some(Fetcher::FetchFromGitHub), Some(host)) => {
FetchFromGitHub((host != Host::Domain("github.com")).then_some(&host.to_string()))
.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(None, Some(Host::Domain("github.com"))) => {
FetchFromGitHub(None).fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(Some(Fetcher::FetchFromGitLab), Some(host)) => {
FetchFromGitLab((host != Host::Domain("github.com")).then_some(&host.to_string()))
.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(None, Some(Host::Domain(host))) if host.starts_with("gitlab.") => {
FetchFromGitLab((host != "gitlab.com").then_some(host))
.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(Some(Fetcher::FetchFromSourcehut), Some(host)) => {
FetchFromSourcehut((host != Host::Domain("git.sr.ht")).then_some(&host.to_string()))
.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(None, Some(Host::Domain("git.sr.ht"))) => {
FetchFromSourcehut(None).fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(
Some(Fetcher::FetchFromGitHub | Fetcher::FetchFromGitLab | Fetcher::FetchFromSourcehut),
None,
) => {
bail!("bad");
}
(Some(Fetcher::Fetchgit), _) | (None, _) => {
Fetchgit.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
(Some(Fetcher::Fetchhg), _) => {
Fetchhg.fetch_nix(out, &opts.url, opts.rev, indent)?;
}
}
Ok(())
}