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 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}