From 708ca82d5fe9e153c2802c6d302c20e29f874d1f Mon Sep 17 00:00:00 2001 From: figsoda Date: Thu, 12 Jan 2023 15:03:27 -0500 Subject: [PATCH] add --parse --- src/cli.rs | 6 ++++++ src/fetcher/mod.rs | 43 ++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ tests/cmd/parse.stdout | 1 + tests/cmd/parse.toml | 1 + tests/integration.rs | 2 +- 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/cmd/parse.stdout create mode 100644 tests/cmd/parse.toml diff --git a/src/cli.rs b/src/cli.rs index cac4996..6bcddab 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -33,6 +33,12 @@ pub struct Opts { #[arg(short, long, group = "format")] pub json: bool, + /// parse the url without fetching the hash, similar to --json + /// + /// note that --arg(-str) and --overwrite(-str) will be ignored silently + #[arg(short, long, group = "format")] + pub parse: bool, + /// additional arguments to pass to the fetcher #[arg(short, long = "arg", num_args = 2, value_names = ["NAME", "EXPR"])] pub args: Vec, diff --git a/src/fetcher/mod.rs b/src/fetcher/mod.rs index 4c53506..026e5d7 100644 --- a/src/fetcher/mod.rs +++ b/src/fetcher/mod.rs @@ -59,6 +59,13 @@ pub trait Fetcher<'a> { overwrites: Vec<(String, String)>, overwrites_str: Vec<(String, String)>, ) -> Result<()>; + + fn to_json( + &'a self, + out: &mut impl ::std::io::Write, + url: &'a ::url::Url, + rev: Option, + ) -> ::anyhow::Result<()>; } #[enum_dispatch(Fetcher)] @@ -164,6 +171,42 @@ macro_rules! impl_fetcher { overwrites_str, ) } + + fn to_json( + &'a self, + out: &mut impl ::std::io::Write, + url: &'a ::url::Url, + rev: Option, + ) -> ::anyhow::Result<()> { + use anyhow::Context; + use serde_json::{json, Value}; + + let values = self + .get_values(url) + .with_context(|| format!("failed to parse {url}"))?; + + let mut fetcher_args = Value::from_iter(Self::KEYS.into_iter().zip(values)); + + if let Some(host) = self.host() { + fetcher_args[Self::HOST_KEY] = json!(host); + } + if let Some(group) = self.group() { + fetcher_args["group"] = json!(group); + } + if let Some(rev) = rev { + fetcher_args["rev"] = json!(rev); + } + + serde_json::to_writer( + out, + &json!({ + "fetcher": Self::NAME, + "args": fetcher_args, + }), + )?; + + Ok(()) + } } }; } diff --git a/src/main.rs b/src/main.rs index d746d8b..d77403a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -152,6 +152,8 @@ fn main() -> Result<()> { opts.overwrites.into_iter().tuples().collect(), opts.overwrites_str.into_iter().tuples().collect(), ) + } else if opts.parse { + fetcher.to_json(out, &opts.url, opts.rev) } else { let mut overwrites: FxHashMap<_, _> = opts.overwrites.into_iter().tuples().collect(); diff --git a/tests/cmd/parse.stdout b/tests/cmd/parse.stdout new file mode 100644 index 0000000..f152586 --- /dev/null +++ b/tests/cmd/parse.stdout @@ -0,0 +1 @@ +{"args":{"owner":"nix-community","repo":"nurl","rev":"v0.3.0"},"fetcher":"fetchFromGitHub"} \ No newline at end of file diff --git a/tests/cmd/parse.toml b/tests/cmd/parse.toml new file mode 100644 index 0000000..bab8949 --- /dev/null +++ b/tests/cmd/parse.toml @@ -0,0 +1 @@ +args = ["https://github.com/nix-community/nurl", "v0.3.0", "--parse"] diff --git a/tests/integration.rs b/tests/integration.rs index 5c51414..5eb851f 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -23,7 +23,7 @@ fn verify_outputs() { .strip_suffix(".stdout") .unwrap(); - if matches!(name, "hash" | "json") { + if matches!(name, "hash" | "json" | "parse") { eprintln!("skipping {}", path.display()); continue; }