hive-forge: make --json a global flag (closes #421)
This commit is contained in:
parent
3cd9240594
commit
d0a1ee037b
5 changed files with 33 additions and 16 deletions
|
|
@ -124,7 +124,7 @@ since #280). Use it instead of ad-hoc curl pipelines:
|
|||
```bash
|
||||
hive-forge view 42 # title + body + comments
|
||||
hive-forge comments 42 # list all comments (human-readable)
|
||||
hive-forge comments 42 --json # list as JSON array
|
||||
hive-forge --json comments 42 # same as above, JSON array (global flag, closes #421)
|
||||
hive-forge comment 42 --body "..." # post comment (inline body)
|
||||
hive-forge comment 42 --body-file - <<EOF # ...or pipe a HEREDOC
|
||||
multi-line body
|
||||
|
|
|
|||
|
|
@ -26,14 +26,19 @@ pub struct Client {
|
|||
/// Default repo used when a verb doesn't carry an explicit
|
||||
/// `[repo]` override.
|
||||
pub default_repo: String,
|
||||
/// Global `--json` flag — verbs that have a human-readable
|
||||
/// default path branch on `client.json_mode()` to pick the
|
||||
/// JSON output shape instead. Closes #421.
|
||||
json_mode: bool,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Build a client from the standard environment variables.
|
||||
/// `repo_override` (from the global `-r/--repo` flag) takes
|
||||
/// priority over `HIVE_FORGE_REPO`; the env var is the fallback
|
||||
/// default.
|
||||
pub fn from_env(repo_override: Option<String>) -> Result<Self> {
|
||||
/// default. `json_mode` comes from the global `--json` flag —
|
||||
/// per-verb output formatters key off it via `Client::json_mode`.
|
||||
pub fn from_env(repo_override: Option<String>, json_mode: bool) -> Result<Self> {
|
||||
let base = std::env::var("HIVE_FORGE_URL").unwrap_or_else(|_| DEFAULT_URL.to_owned());
|
||||
let default_repo = repo_override
|
||||
.or_else(|| std::env::var("HIVE_FORGE_REPO").ok())
|
||||
|
|
@ -55,9 +60,19 @@ impl Client {
|
|||
http,
|
||||
base,
|
||||
default_repo,
|
||||
json_mode,
|
||||
})
|
||||
}
|
||||
|
||||
/// True when the operator passed the global `--json` flag.
|
||||
/// Verbs that have a human-readable default branch on this to
|
||||
/// emit JSON instead. Verbs whose only output format is JSON
|
||||
/// (e.g. `issue`, `pr`) can ignore it.
|
||||
#[must_use]
|
||||
pub fn json_mode(&self) -> bool {
|
||||
self.json_mode
|
||||
}
|
||||
|
||||
/// Resolve the API base path (`<base>/api/v1`).
|
||||
fn api(&self) -> String {
|
||||
format!("{}/api/v1", self.base)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ struct Cli {
|
|||
/// positional the bash helper used.
|
||||
#[arg(short = 'r', long, global = true)]
|
||||
repo: Option<String>,
|
||||
/// Emit JSON output instead of the verb's default human-readable
|
||||
/// shape, for verbs that support both (closes #421). Verbs whose
|
||||
/// only output is already JSON (`issue`, `pr`, etc.) ignore this
|
||||
/// flag — they always print JSON regardless.
|
||||
#[arg(long, global = true)]
|
||||
json: bool,
|
||||
#[command(subcommand)]
|
||||
verb: Verb,
|
||||
}
|
||||
|
|
@ -87,7 +93,8 @@ enum Verb {
|
|||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
let client = client::Client::from_env(cli.repo).context("initialize forge client")?;
|
||||
let client =
|
||||
client::Client::from_env(cli.repo, cli.json).context("initialize forge client")?;
|
||||
match cli.verb {
|
||||
Verb::View(a) => verbs::view::run(&client, a),
|
||||
Verb::Issue(a) => verbs::issue::run(&client, a),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! `comment-show <id> [--json] [repo]` — print the body (or full
|
||||
//! JSON) of a single comment by id.
|
||||
//! `comment-show <id>` — print the body (or full JSON envelope
|
||||
//! when `--json` is set globally) of a single comment by id.
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Args as ClapArgs;
|
||||
|
|
@ -12,15 +12,12 @@ use crate::verbs::print_json;
|
|||
pub struct Args {
|
||||
/// Comment id.
|
||||
id: u64,
|
||||
/// Print full JSON envelope instead of just the body text.
|
||||
#[arg(long)]
|
||||
json: bool,
|
||||
}
|
||||
|
||||
pub fn run(client: &Client, args: Args) -> Result<()> {
|
||||
let repo = client.repo();
|
||||
let v = client.get_json(&format!("/repos/{repo}/issues/comments/{}", args.id))?;
|
||||
if args.json {
|
||||
if client.json_mode() {
|
||||
let trimmed = json!({
|
||||
"id": v.get("id"),
|
||||
"user": v.get("user").and_then(|u| u.get("login")),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! `comments <number> [--json] [--limit N]` — list all comments on
|
||||
//! an issue or PR. Closes the curl-fallback gap (#418).
|
||||
//! `comments <number> [--limit N]` — list all comments on an issue
|
||||
//! or PR. Closes the curl-fallback gap (#418). Use the global
|
||||
//! `--json` flag for JSON output (#421).
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Args as ClapArgs;
|
||||
|
|
@ -12,9 +13,6 @@ use crate::verbs::print_json;
|
|||
pub struct Args {
|
||||
/// Issue or PR number.
|
||||
number: u64,
|
||||
/// Print as JSON array instead of human-readable markdown.
|
||||
#[arg(long)]
|
||||
json: bool,
|
||||
/// Page size (Forgejo caps at 50 by default).
|
||||
#[arg(long, default_value_t = 50)]
|
||||
limit: u64,
|
||||
|
|
@ -26,7 +24,7 @@ pub fn run(client: &Client, args: Args) -> Result<()> {
|
|||
"/repos/{repo}/issues/{}/comments?limit={}",
|
||||
args.number, args.limit
|
||||
))?;
|
||||
if args.json {
|
||||
if client.json_mode() {
|
||||
let trimmed: Vec<Value> = v
|
||||
.as_array()
|
||||
.map(|a| {
|
||||
|
|
|
|||
Loading…
Reference in a new issue