...
This commit is contained in:
104
src/os/fs.rs
104
src/os/fs.rs
@@ -14,6 +14,7 @@ pub enum FsError {
|
||||
CopyFailed(io::Error),
|
||||
DeleteFailed(io::Error),
|
||||
CommandFailed(String),
|
||||
CommandNotFound(String),
|
||||
CommandExecutionError(io::Error),
|
||||
InvalidGlobPattern(glob::PatternError),
|
||||
NotADirectory(String),
|
||||
@@ -36,6 +37,7 @@ impl fmt::Display for FsError {
|
||||
FsError::CopyFailed(e) => write!(f, "Failed to copy file: {}", e),
|
||||
FsError::DeleteFailed(e) => write!(f, "Failed to delete: {}", e),
|
||||
FsError::CommandFailed(e) => write!(f, "{}", e),
|
||||
FsError::CommandNotFound(e) => write!(f, "Command not found: {}", e),
|
||||
FsError::CommandExecutionError(e) => write!(f, "Failed to execute command: {}", e),
|
||||
FsError::InvalidGlobPattern(e) => write!(f, "Invalid glob pattern: {}", e),
|
||||
FsError::NotADirectory(path) => write!(f, "Path '{}' exists but is not a directory", path),
|
||||
@@ -740,3 +742,105 @@ pub fn file_write_append(path: &str, content: &str) -> Result<String, FsError> {
|
||||
|
||||
Ok(format!("Successfully appended to file '{}'", path))
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a command exists in the system PATH.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `command` - The command to check
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* * `String` - Empty string if the command doesn't exist, path to the command if it does
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```
|
||||
* let cmd_path = which("ls");
|
||||
* if cmd_path != "" {
|
||||
* println!("ls is available at: {}", cmd_path);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
pub fn which(command: &str) -> String {
|
||||
// Use the appropriate command based on the platform
|
||||
#[cfg(target_os = "windows")]
|
||||
let output = Command::new("where")
|
||||
.arg(command)
|
||||
.output();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let output = Command::new("which")
|
||||
.arg(command)
|
||||
.output();
|
||||
|
||||
match output {
|
||||
Ok(out) => {
|
||||
if out.status.success() {
|
||||
let path = String::from_utf8_lossy(&out.stdout).trim().to_string();
|
||||
path
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
},
|
||||
Err(_) => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that one or more commands exist in the system PATH.
|
||||
* If any command doesn't exist, an error is thrown.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `commands` - The command(s) to check, comma-separated for multiple commands
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* * `Ok(String)` - A success message indicating all commands exist
|
||||
* * `Err(FsError)` - An error if any command doesn't exist
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* ```
|
||||
* // Check if a single command exists
|
||||
* let result = cmd_ensure_exists("nerdctl")?;
|
||||
*
|
||||
* // Check if multiple commands exist
|
||||
* let result = cmd_ensure_exists("nerdctl,docker,containerd")?;
|
||||
* ```
|
||||
*/
|
||||
pub fn cmd_ensure_exists(commands: &str) -> Result<String, FsError> {
|
||||
// Split the input by commas to handle multiple commands
|
||||
let command_list: Vec<&str> = commands.split(',')
|
||||
.map(|s| s.trim())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect();
|
||||
|
||||
if command_list.is_empty() {
|
||||
return Err(FsError::CommandFailed("No commands specified to check".to_string()));
|
||||
}
|
||||
|
||||
let mut missing_commands = Vec::new();
|
||||
|
||||
// Check each command
|
||||
for cmd in &command_list {
|
||||
let cmd_path = which(cmd);
|
||||
if cmd_path.is_empty() {
|
||||
missing_commands.push(cmd.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// If any commands are missing, return an error
|
||||
if !missing_commands.is_empty() {
|
||||
return Err(FsError::CommandNotFound(missing_commands.join(", ")));
|
||||
}
|
||||
|
||||
// All commands exist
|
||||
if command_list.len() == 1 {
|
||||
Ok(format!("Command '{}' exists", command_list[0]))
|
||||
} else {
|
||||
Ok(format!("All commands exist: {}", command_list.join(", ")))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user