use std::process::Command;
use super::{NumericVersion, ToolError};
#[derive(Debug, Clone, Copy)]
pub(crate) enum Tool {
Rustc,
Cargo,
Node,
Pnpm,
}
impl Tool {
pub(crate) fn program(self) -> &'static str {
match self {
Self::Rustc => "rustc",
Self::Cargo => "cargo",
Self::Node => "node",
Self::Pnpm => "pnpm",
}
}
pub(crate) fn executable(self) -> &'static str {
if cfg!(windows) && matches!(self, Self::Pnpm) {
"pnpm.cmd"
} else {
self.program()
}
}
}
pub(crate) fn probe(tool: Tool) -> Result<NumericVersion, ToolError> {
let program = tool.program();
let output = Command::new(tool.executable())
.arg("--version")
.output()
.map_err(|source| ToolError::Missing { program, source })?;
if !output.status.success() {
return Err(ToolError::ProbeFailed {
program,
status: output.status,
});
}
let text = String::from_utf8_lossy(&output.stdout);
NumericVersion::parse(&text).ok_or(ToolError::InvalidOutput { program })
}