use std::fmt::Write as _;
use std::path::Path;
use trusty_mpm::core::component_labels::workspace_crate_labels_checked;
use trusty_mpm::core::policy_labels::policy_labels_configured;
use trusty_mpm::core::trusty_tools_config::ResolvedTicketing;
use super::standard_live::one_line;
use crate::commands::ticket::labels::{RepoLabel, gh_list_repo_labels};
use crate::commands::ticket::runner::CommandRunner;
pub(crate) fn render_component_labels(
ticketing: &ResolvedTicketing,
session: Option<&str>,
start_dir: Option<&Path>,
runner: &dyn CommandRunner,
) -> String {
let seeded = policy_labels_configured(ticketing, session);
let derived = workspace_crate_labels_checked(start_dir);
let live = gh_list_repo_labels(runner);
let mut names: Vec<String> = seeded.iter().map(|l| l.name.clone()).collect();
for name in derived.iter().flatten() {
if !names.iter().any(|existing| existing == name) {
names.push(name.clone());
}
}
let mut out = String::new();
let _ = writeln!(
out,
"\ncomponent labels ({}) — the seeded labels plus every workspace crate,\n\
\x20 cross-checked against the repository's live labels:",
names.len()
);
if let Err(reason) = &derived {
let _ = writeln!(
out,
" crate labels: unavailable ({reason})\n\
\x20 the list below is the SEEDED set only, not this workspace's components"
);
}
if let Err(e) = &live {
let _ = writeln!(
out,
" gh label list: unavailable ({})\n\
\x20 no line below is confirmed to exist on the repository",
one_line(e)
);
}
for name in &names {
let _ = writeln!(
out,
" {name} {}{}",
detail(name, &seeded, &live),
status(name, &live)
);
}
out
}
fn detail(name: &str, seeded: &[RepoLabel], live: &anyhow::Result<Vec<RepoLabel>>) -> String {
seeded
.iter()
.find(|l| l.name == name)
.or_else(|| live.as_ref().ok()?.iter().find(|l| l.name == name))
.map_or_else(
|| "(not on the repository)".to_string(),
|l| format!("#{} {}", l.color, l.description),
)
}
fn status(name: &str, live: &anyhow::Result<Vec<RepoLabel>>) -> &'static str {
match live {
Err(_) => " [presence unknown]",
Ok(labels) if labels.iter().any(|l| l.name == name) => "",
Ok(_) => " MISSING — `gh label create` it before an issue names it",
}
}
#[cfg(test)]
#[path = "standard_components_tests.rs"]
mod tests;