use crate::error::ScriptResult;
use crate::sync::CommandBuilder;
pub fn which(name: &str) -> ScriptResult<Option<std::path::PathBuf>> {
#[cfg(windows)]
{
let result = CommandBuilder::new("where")
.arg(name)
.capture_output()
.execute()?;
if result.success() {
let path = result
.stdout_str()
.lines()
.next()
.map(std::path::PathBuf::from);
Ok(path)
} else {
Ok(None)
}
}
#[cfg(not(windows))]
{
let result = CommandBuilder::new("which")
.arg(name)
.capture_output()
.execute()?;
if result.success() {
let path = result
.stdout_str()
.trim()
.lines()
.next()
.map(std::path::PathBuf::from);
Ok(path)
} else {
Ok(None)
}
}
}
pub fn command_exists(name: &str) -> ScriptResult<bool> {
Ok(which(name)?.is_some())
}
pub fn default_shell() -> &'static str {
#[cfg(windows)]
{
"cmd"
}
#[cfg(not(windows))]
{
"sh"
}
}
pub fn shell_exec_flag() -> &'static str {
#[cfg(windows)]
{
"/C"
}
#[cfg(not(windows))]
{
"-c"
}
}
pub fn eval(command: &str) -> ScriptResult<crate::output::Output> {
CommandBuilder::new(default_shell())
.arg(shell_exec_flag())
.arg(command)
.capture_output()
.execute()
}
pub fn get_env(var: &str) -> Option<std::ffi::OsString> {
std::env::var(var).ok().map(std::ffi::OsString::from)
}
pub fn is_windows() -> bool {
cfg!(windows)
}
pub fn is_unix() -> bool {
cfg!(unix)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_shell() {
let shell = default_shell();
assert!(!shell.is_empty());
}
#[test]
fn test_shell_exec_flag() {
let flag = shell_exec_flag();
assert!(!flag.is_empty());
}
#[test]
fn test_platform_checks() {
let is_win = is_windows();
let is_nix = is_unix();
assert!(is_win || is_nix);
assert!(!(is_win && is_nix));
}
}