diff --git a/xtask/src/screenshots.rs b/xtask/src/screenshots.rs index f87ce91..726174b 100644 --- a/xtask/src/screenshots.rs +++ b/xtask/src/screenshots.rs @@ -53,22 +53,42 @@ pub(crate) fn run(output: Option, chafa: Option, no_png: bool) } let png_requested = !no_png; - let mut chafa_binary: Option = None; - if png_requested { - if let Some(ref path) = chafa { + let mut png_skip_reason: Option = None; + let chafa_binary: Option = if png_requested { + let candidate = if let Some(ref path) = chafa { if path.exists() { - chafa_binary = Some(path.clone()); + Some(path.clone()) } else { bail!("specified chafa binary '{}' does not exist", path.display()); } - } else if let Ok(found) = which("chafa") { - chafa_binary = Some(found); } else { - eprintln!( - "warning: chafa not found in PATH; skipping PNG conversion (install `chafa` or rerun with --no-png)" - ); + which("chafa").ok() + }; + + if let Some(path) = candidate { + match chafa_supports_save(&path) { + Ok(true) => Some(path), + Ok(false) => { + png_skip_reason = Some(format!( + "chafa at '{}' lacks --save support; install chafa 1.14+ or rerun with --no-png", + path.display() + )); + None + } + Err(err) => { + eprintln!("warning: failed to probe chafa capabilities: {err}"); + png_skip_reason = Some("failed to verify chafa capabilities".to_string()); + None + } + } + } else { + png_skip_reason = + Some("chafa not found in PATH; install it or rerun with --no-png".to_string()); + None } - } + } else { + None + }; let runtime = Runtime::new().context("failed to create tokio runtime")?; @@ -86,7 +106,7 @@ pub(crate) fn run(output: Option, chafa: Option, no_png: bool) scene.height, &output_dir, scene.name, - Some(binary.as_path()), + binary.as_path(), ) { eprintln!("warning: {}", err); @@ -94,11 +114,13 @@ pub(crate) fn run(output: Option, chafa: Option, no_png: bool) } println!("Screenshots written to {}", output_dir.display()); - if png_requested { - if chafa_binary.is_none() { - println!("PNG conversion skipped (install `chafa` or pass --no-png to disable)"); + if png_requested && chafa_binary.is_none() { + if let Some(reason) = png_skip_reason { + println!("PNG conversion skipped ({reason})"); + } else { + println!("PNG conversion skipped"); } - } else { + } else if !png_requested { println!("PNG conversion skipped (use --no-png=false or omit flag to enable)"); } @@ -111,14 +133,10 @@ fn convert_to_png( height: u16, output_dir: &Path, name: &str, - chafa_path: Option<&Path>, + chafa_path: &Path, ) -> Result<()> { let png_path = output_dir.join(format!("{}.png", name)); - let mut command = if let Some(path) = chafa_path { - Command::new(path) - } else { - Command::new("chafa") - }; + let mut command = Command::new(chafa_path); let status = command .arg("--size") .arg(format!("{}x{}", width, height)) @@ -137,6 +155,20 @@ fn convert_to_png( Ok(()) } +fn chafa_supports_save(chafa_path: &Path) -> Result { + let output = Command::new(chafa_path) + .arg("--help") + .output() + .with_context(|| { + format!( + "failed to run '{}' to probe capabilities", + chafa_path.display() + ) + })?; + let help = String::from_utf8_lossy(&output.stdout); + Ok(help.contains("--save")) +} + fn scenes() -> &'static [SceneSpec] { &[ SceneSpec {