refactor(hive-forge): port CLI verbs to forgejo-api
This commit is contained in:
parent
b8a3927c43
commit
4636987469
36 changed files with 1463 additions and 1153 deletions
|
|
@ -5,11 +5,17 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use clap::Args as ClapArgs;
|
||||
use serde_json::{Value, json};
|
||||
use forgejo_api::structs::{IssueListLabelsQuery, Label};
|
||||
|
||||
use crate::client::Client;
|
||||
use crate::verbs::print_json;
|
||||
|
||||
/// Page size on the label list endpoint.
|
||||
const PAGE_SIZE: u32 = 50;
|
||||
|
||||
/// Runaway cap on label pagination — same ceiling the raw client used.
|
||||
const MAX_PAGES: u32 = 10;
|
||||
|
||||
#[derive(ClapArgs)]
|
||||
pub struct Args {
|
||||
/// Substring pattern to filter label names (case-sensitive).
|
||||
|
|
@ -17,34 +23,46 @@ pub struct Args {
|
|||
}
|
||||
|
||||
pub fn run(client: &Client, args: Args) -> Result<()> {
|
||||
let repo = client.repo();
|
||||
let (owner, name) = client.owner_repo()?;
|
||||
// Repos can carry more than one page of labels; paginate so the list
|
||||
// is complete rather than capped at the first page.
|
||||
let labels = client.get_json_all(&format!("/repos/{repo}/labels"), 10)?;
|
||||
let filtered: Vec<&Value> = labels
|
||||
let mut labels: Vec<Label> = Vec::new();
|
||||
for page in 1..=MAX_PAGES {
|
||||
let (_, batch) = client
|
||||
.api()
|
||||
.issue_list_labels(owner, name, IssueListLabelsQuery::default())
|
||||
.page(page)
|
||||
.page_size(PAGE_SIZE)
|
||||
.send()?;
|
||||
let short = batch.len() < PAGE_SIZE as usize;
|
||||
labels.extend(batch);
|
||||
if short {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let filtered: Vec<&Label> = labels
|
||||
.iter()
|
||||
.filter(|l| {
|
||||
let name = l.get("name").and_then(Value::as_str).unwrap_or_default();
|
||||
args.pattern.as_deref().is_none_or(|p| name.contains(p))
|
||||
let label_name = l.name.as_deref().unwrap_or_default();
|
||||
args.pattern
|
||||
.as_deref()
|
||||
.is_none_or(|p| label_name.contains(p))
|
||||
})
|
||||
.collect();
|
||||
|
||||
if client.json_mode() {
|
||||
// Full label objects (id, name, color, description) as a JSON array.
|
||||
print_json(&json!(filtered))?;
|
||||
print_json(&serde_json::to_value(&filtered)?)?;
|
||||
} else {
|
||||
// One label per line: `name`, plus its description (tab-separated)
|
||||
// when set, so triage can see what each label means at a glance.
|
||||
for l in filtered {
|
||||
let name = l.get("name").and_then(Value::as_str).unwrap_or_default();
|
||||
let desc = l
|
||||
.get("description")
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or_default();
|
||||
let label_name = l.name.as_deref().unwrap_or_default();
|
||||
let desc = l.description.as_deref().unwrap_or_default();
|
||||
if desc.is_empty() {
|
||||
println!("{name}");
|
||||
println!("{label_name}");
|
||||
} else {
|
||||
println!("{name}\t{desc}");
|
||||
println!("{label_name}\t{desc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue