Skip to main content

sandogasa_cli/
lib.rs

1// SPDX-License-Identifier: MPL-2.0
2
3//! Shared CLI utilities for sandogasa tools.
4
5use std::process::{Command, Stdio};
6
7/// Check that an external tool is available in `$PATH`.
8///
9/// Runs `<name> --version` and returns `Ok(())` if it exits
10/// successfully, or an error message with the install hint.
11///
12/// # Example
13///
14/// ```no_run
15/// sandogasa_cli::require_tool("fedrq", "sudo dnf install fedrq").unwrap();
16/// ```
17pub fn require_tool(name: &str, install_hint: &str) -> Result<(), String> {
18    match Command::new(name)
19        .arg("--version")
20        .stdout(Stdio::null())
21        .stderr(Stdio::null())
22        .status()
23    {
24        Ok(s) if s.success() => Ok(()),
25        Ok(s) => Err(format!(
26            "{name} exited with {s}; is it installed correctly? \
27             Install it with: {install_hint}"
28        )),
29        Err(_) => Err(format!("{name} not found. Install it with: {install_hint}")),
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn require_missing_tool() {
39        let result = require_tool("nonexistent_tool_xyz_123", "magic install");
40        assert!(result.is_err());
41        let msg = result.unwrap_err();
42        assert!(msg.contains("nonexistent_tool_xyz_123"));
43        assert!(msg.contains("magic install"));
44    }
45
46    #[test]
47    fn require_available_tool() {
48        // `true` is a standard Unix utility that always succeeds.
49        // It doesn't support --version but some impls exit 0 anyway.
50        // Use `sh` which reliably exists and handles --version.
51        let result = require_tool("sh", "should already be installed");
52        // sh --version may or may not succeed depending on implementation,
53        // so just verify it doesn't panic.
54        let _ = result;
55    }
56}