qali/commands/
shell.rs

1use super::QaliCommand;
2use anyhow::{Context, anyhow, Result};
3use std::{fs, path::PathBuf, str::FromStr, process::Command};
4use regex::Regex;
5use colored::Colorize;
6
7#[derive(Debug)]
8pub struct Shell{
9    pub filename: String,
10}
11
12impl QaliCommand for Shell {
13    fn execute(&self, args: Option<&String>) -> Result<()> {
14        eprintln!("{}","Running Shell script".dimmed());
15        let file = PathBuf::from_str(&self.filename)?;
16        if !file.exists() {
17            return Err(anyhow!("File {} not found", self.filename));
18        }
19        let mut shell_cmd = Command::new("sh");
20        shell_cmd.arg(file);
21        if let Some(arg) = args {
22            shell_cmd.arg(arg);
23        }
24        shell_cmd.status().context("Failed to execute process.")?;
25        Ok(())
26    }
27
28    fn is_valid(command: &String) -> bool {
29        let re = Regex::new(r"^.*\.sh$").unwrap();
30        re.is_match(command)
31    }
32
33    fn new(command: &String) -> Result<Self> where Self: Sized {
34        let file = PathBuf::from_str(command)?;
35        if !file.exists() {
36            return Err(anyhow!("File {} not found", command));
37        }
38        Ok(Shell{
39            filename: command.to_string(),
40        })
41    }
42
43    fn export(&self) -> Result<String> {
44        let file = PathBuf::from_str(&self.filename)?;
45        let fp = fs::canonicalize(file)?;
46        Ok(fp.to_string_lossy().to_string())
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use std::env;
54    #[test]
55    fn run_shell() -> Result<()> {
56        let mut dir = env::current_exe()?;
57        dir.pop();
58        dir.push("test.sh");
59        let program = "echo Hello World";
60        // write program to dir
61        std::fs::write(dir.to_str().unwrap(), program)?;
62        let shell = Shell{
63            filename: dir.to_str().unwrap().to_string(),
64        };
65        shell.execute(None)
66    }
67}