ralph/tools/
shell_tools.rs1use crate::errors::{RalphError, Result};
2use std::path::Path;
3use tokio::process::Command;
4
5pub async fn run_command(cmd: &str, cwd: &Path) -> Result<String> {
6 let output = Command::new("sh")
7 .arg("-c")
8 .arg(cmd)
9 .current_dir(cwd)
10 .output()
11 .await
12 .map_err(|e| RalphError::ToolFailed {
13 tool: "run_command".to_string(),
14 message: e.to_string(),
15 })?;
16
17 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
18 let stderr = String::from_utf8_lossy(&output.stderr).to_string();
19 let exit_code = output.status.code().unwrap_or(-1);
20
21 let mut result = String::new();
22 if !stdout.is_empty() {
23 result.push_str(&stdout);
24 }
25 if !stderr.is_empty() {
26 if !result.is_empty() {
27 result.push('\n');
28 }
29 result.push_str(&stderr);
30 }
31 result.push_str(&format!("\n[exit: {}]", exit_code));
32 Ok(result)
33}