The forge clamps page_size to 50. branches, pr reviews, the review bodies merged into `comments <pr>`, and view's comment list each sent one request, so anything past the first page was dropped silently. labels::repo_labels did loop, but asked for 100/page and stopped on `len < 100`, so a clamped full page of 50 ended the walk. Add verbs::all_pages: requests 50/page until a short page, capped at 50 pages with a stderr warning when the cap is hit. Use it in all of the above; repo-labels now calls labels::repo_labels instead of its own copy of the loop. list --json now prints the same "N of M shown" stderr trailer as the pretty output; its paging and stdout shape are unchanged. Closes #5051
48 lines
1.6 KiB
Rust
48 lines
1.6 KiB
Rust
//! `repo-labels [pattern]` — list the active repo's full label set
|
|
//! (project-wide), not the labels on one issue/PR (that's `labels
|
|
//! <number>`). Useful for triage / labelling to discover the valid label
|
|
//! names + what each means before applying them.
|
|
|
|
use anyhow::Result;
|
|
use clap::Args as ClapArgs;
|
|
use forgejo_api::structs::Label;
|
|
|
|
use crate::client::Client;
|
|
use crate::verbs::{labels, print_json};
|
|
|
|
#[derive(ClapArgs)]
|
|
pub struct Args {
|
|
/// Substring pattern to filter label names (case-sensitive).
|
|
pattern: Option<String>,
|
|
}
|
|
|
|
pub fn run(client: &Client, args: Args) -> Result<()> {
|
|
let labels = labels::repo_labels(client)?;
|
|
let filtered: Vec<&Label> = labels
|
|
.iter()
|
|
.filter(|l| {
|
|
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(&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 label_name = l.name.as_deref().unwrap_or_default();
|
|
let desc = l.description.as_deref().unwrap_or_default();
|
|
if desc.is_empty() {
|
|
println!("{label_name}");
|
|
} else {
|
|
println!("{label_name}\t{desc}");
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|