mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-07 08:27:12 +00:00
Enforce semantic color scheme across CLI output
Add magenta, underline, bold_green, and bold_red styles to Styles struct. Fix color semantics: server address uses cyan (info, not success), status lines use bold_green/bold_red, preflight verdict uses bold variants, and file paths are underlined instead of dim. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c2ea8b3084
commit
01ddeadaf0
3 changed files with 45 additions and 15 deletions
|
|
@ -137,7 +137,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
|
|||
"{}",
|
||||
styles.bold.apply_to(format!(
|
||||
"Arc server listening on {}",
|
||||
styles.green.apply_to(&addr)
|
||||
styles.cyan.apply_to(&addr)
|
||||
)),
|
||||
);
|
||||
if dry_run_mode {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ pub struct Styles {
|
|||
pub green: Style,
|
||||
pub yellow: Style,
|
||||
pub red: Style,
|
||||
pub magenta: Style,
|
||||
pub underline: Style,
|
||||
pub bold_dim: Style,
|
||||
pub bold_cyan: Style,
|
||||
pub bold_green: Style,
|
||||
pub bold_red: Style,
|
||||
}
|
||||
|
||||
impl Styles {
|
||||
|
|
@ -23,8 +27,12 @@ impl Styles {
|
|||
green: Style::new().green().force_styling(use_color),
|
||||
yellow: Style::new().yellow().force_styling(use_color),
|
||||
red: Style::new().red().force_styling(use_color),
|
||||
magenta: Style::new().magenta().force_styling(use_color),
|
||||
underline: Style::new().underlined().force_styling(use_color),
|
||||
bold_dim: Style::new().bold().dim().force_styling(use_color),
|
||||
bold_cyan: Style::new().bold().cyan().force_styling(use_color),
|
||||
bold_green: Style::new().bold().green().force_styling(use_color),
|
||||
bold_red: Style::new().bold().red().force_styling(use_color),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,6 +76,8 @@ mod tests {
|
|||
assert_eq!(format!("{}", s.green.apply_to("text")), "text");
|
||||
assert_eq!(format!("{}", s.yellow.apply_to("text")), "text");
|
||||
assert_eq!(format!("{}", s.red.apply_to("text")), "text");
|
||||
assert_eq!(format!("{}", s.magenta.apply_to("text")), "text");
|
||||
assert_eq!(format!("{}", s.underline.apply_to("text")), "text");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -80,6 +90,22 @@ mod tests {
|
|||
let output = format!("{}", s.bold_cyan.apply_to("tool"));
|
||||
assert!(output.contains("\x1b["), "bold_cyan should contain ANSI codes");
|
||||
assert!(output.contains("tool"));
|
||||
|
||||
let output = format!("{}", s.bold_green.apply_to("pass"));
|
||||
assert!(output.contains("\x1b["), "bold_green should contain ANSI codes");
|
||||
assert!(output.contains("pass"));
|
||||
|
||||
let output = format!("{}", s.bold_red.apply_to("fail"));
|
||||
assert!(output.contains("\x1b["), "bold_red should contain ANSI codes");
|
||||
assert!(output.contains("fail"));
|
||||
|
||||
let output = format!("{}", s.magenta.apply_to("medium"));
|
||||
assert!(output.contains("\x1b["), "magenta should contain ANSI codes");
|
||||
assert!(output.contains("medium"));
|
||||
|
||||
let output = format!("{}", s.underline.apply_to("path"));
|
||||
assert!(output.contains("\x1b["), "underline should contain ANSI codes");
|
||||
assert!(output.contains("path"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -269,8 +269,9 @@ pub async fn run_command(
|
|||
|
||||
if args.verbose {
|
||||
eprintln!(
|
||||
"{}",
|
||||
styles.dim.apply_to(format!("Logs: {}", logs_dir.display())),
|
||||
"{} {}",
|
||||
styles.dim.apply_to("Logs:"),
|
||||
styles.underline.apply_to(logs_dir.display()),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -711,8 +712,8 @@ pub async fn run_command(
|
|||
|
||||
let status_str = outcome.status.to_string().to_uppercase();
|
||||
let status_color = match outcome.status {
|
||||
StageStatus::Success | StageStatus::PartialSuccess => &styles.green,
|
||||
_ => &styles.red,
|
||||
StageStatus::Success | StageStatus::PartialSuccess => &styles.bold_green,
|
||||
_ => &styles.bold_red,
|
||||
};
|
||||
eprintln!(
|
||||
"Status: {}",
|
||||
|
|
@ -764,8 +765,9 @@ pub async fn run_command(
|
|||
);
|
||||
}
|
||||
eprintln!(
|
||||
"{}",
|
||||
styles.dim.apply_to(format!("Logs: {}", logs_dir.display())),
|
||||
"{} {}",
|
||||
styles.dim.apply_to("Logs:"),
|
||||
styles.underline.apply_to(logs_dir.display()),
|
||||
);
|
||||
|
||||
// 9. Exit code
|
||||
|
|
@ -1034,8 +1036,8 @@ async fn run_from_branch(
|
|||
);
|
||||
let status_str = outcome.status.to_string().to_uppercase();
|
||||
let status_color = match outcome.status {
|
||||
StageStatus::Success | StageStatus::PartialSuccess => &styles.green,
|
||||
_ => &styles.red,
|
||||
StageStatus::Success | StageStatus::PartialSuccess => &styles.bold_green,
|
||||
_ => &styles.bold_red,
|
||||
};
|
||||
eprintln!(
|
||||
"Status: {}",
|
||||
|
|
@ -1046,8 +1048,9 @@ async fn run_from_branch(
|
|||
super::format_duration_human(run_duration_ms)
|
||||
);
|
||||
eprintln!(
|
||||
"{}",
|
||||
styles.dim.apply_to(format!("Logs: {}", logs_dir.display())),
|
||||
"{} {}",
|
||||
styles.dim.apply_to("Logs:"),
|
||||
styles.underline.apply_to(logs_dir.display()),
|
||||
);
|
||||
|
||||
match outcome.status {
|
||||
|
|
@ -1192,13 +1195,13 @@ async fn run_preflight(
|
|||
if ok {
|
||||
eprintln!(
|
||||
"\n{}",
|
||||
styles.green.apply_to("Preflight: OK"),
|
||||
styles.bold_green.apply_to("Preflight: OK"),
|
||||
);
|
||||
Ok(())
|
||||
} else {
|
||||
eprintln!(
|
||||
"\n{}",
|
||||
styles.red.apply_to("Preflight: FAIL"),
|
||||
styles.bold_red.apply_to("Preflight: FAIL"),
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
|
@ -1273,8 +1276,9 @@ async fn generate_retro(
|
|||
match retro.save(logs_dir) {
|
||||
Ok(()) => {
|
||||
eprintln!(
|
||||
"{}",
|
||||
styles.dim.apply_to(format!("Retro saved to {}/retro.json", logs_dir.display())),
|
||||
"{} {}",
|
||||
styles.dim.apply_to("Retro saved to"),
|
||||
styles.underline.apply_to(format!("{}/retro.json", logs_dir.display())),
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue