pub mod diff;
use std::io::IsTerminal;
use owo_colors::OwoColorize;
use crate::modes::{OutcomeKind, PlanKind};
pub fn color_enabled(no_color: bool) -> bool {
if no_color || std::env::var_os("NO_COLOR").is_some() {
return false;
}
std::io::stdout().is_terminal()
}
pub fn print_outcome(dst: &str, kind: OutcomeKind, no_color: bool) {
let (label, plain) = match kind {
OutcomeKind::Wrote => ("wrote", "wrote "),
OutcomeKind::Unchanged => ("unchanged", "unchanged "),
OutcomeKind::Skipped => ("skipped", "skipped "),
OutcomeKind::Failed => ("failed", "failed "),
};
let _ = label;
if color_enabled(no_color) {
match kind {
OutcomeKind::Wrote => println!(" {} {}", "wrote ".green().bold(), dst),
OutcomeKind::Unchanged => println!(" {} {}", "unchanged".dimmed(), dst),
OutcomeKind::Skipped => println!(" {} {}", "skipped ".yellow(), dst),
OutcomeKind::Failed => println!(" {} {}", "failed ".red().bold(), dst),
}
} else {
println!(" {plain}{dst}");
}
}
pub fn print_plan(dst: &str, kind: PlanKind, no_color: bool) {
let label = match kind {
PlanKind::Create => "create",
PlanKind::Update => "update",
PlanKind::Unchanged => "ok",
PlanKind::SkippedWhen => "skip(when)",
PlanKind::SkippedOnce => "skip(once)",
PlanKind::Diverged => "diverged",
};
if color_enabled(no_color) {
let coloured = match kind {
PlanKind::Create => format!("{:<10}", label).green().bold().to_string(),
PlanKind::Update => format!("{:<10}", label).cyan().bold().to_string(),
PlanKind::Unchanged => format!("{:<10}", label).dimmed().to_string(),
PlanKind::SkippedWhen | PlanKind::SkippedOnce => {
format!("{:<10}", label).yellow().to_string()
}
PlanKind::Diverged => format!("{:<10}", label).red().bold().to_string(),
};
println!(" {} {}", coloured, dst);
} else {
println!(" {:<10} {}", label, dst);
}
}
pub fn print_pj_header(name: &str, path: &str, no_color: bool) {
if color_enabled(no_color) {
println!("\n{} {}", name.bold(), format!("({path})").dimmed());
} else {
println!("\n{name} ({path})");
}
}
pub fn print_table_header(cells: &[(&str, usize)], no_color: bool) {
let parts: Vec<String> = cells
.iter()
.map(|(label, width)| {
let cell = if *width == 0 {
(*label).to_string()
} else {
format!("{:<w$}", label, w = *width)
};
if color_enabled(no_color) {
cell.bold().to_string()
} else {
cell
}
})
.collect();
println!("{}", parts.join(" "));
}
pub fn format_status_cell(s: &str, no_color: bool) -> String {
if !color_enabled(no_color) {
return s.to_string();
}
match s {
"ok" => s.green().to_string(),
"drift" => s.yellow().bold().to_string(),
"not init'd" => s.cyan().to_string(),
s if s.starts_with("error") || s == "missing dir" => s.red().bold().to_string(),
_ => s.to_string(),
}
}
pub fn format_drift_cell(s: &str, width: usize, no_color: bool) -> String {
let padded = format!("{:<w$}", s, w = width);
if !color_enabled(no_color) {
return padded;
}
if s == "clean" {
padded.green().to_string()
} else if s.contains("drifted") {
padded.yellow().to_string()
} else {
padded
}
}