gammaloop_api/commands/
shell.rs1use clap::Args;
2use color_eyre::Result;
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[derive(Args, Debug, Serialize, Deserialize, Clone, JsonSchema, PartialEq, Default)]
8pub struct Shell {
9 #[arg(
12 trailing_var_arg = true,
13 allow_hyphen_values = true,
14 value_name = "CMD",
15 num_args = 1..,
16 )]
17 cmd: Vec<std::ffi::OsString>,
18}
19
20impl Shell {
21 pub fn run(self) -> Result<()> {
22 use std::process::Command;
23
24 let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
26
27 fn sh_quote(arg: &std::ffi::OsString) -> String {
29 let s = arg.to_string_lossy();
31 if s.is_empty() {
32 "''".to_string()
33 } else {
34 format!("'{}'", s.replace('\'', "'\"'\"'"))
35 }
36 }
37
38 let cmd_string = self.cmd.iter().map(sh_quote).collect::<Vec<_>>().join(" ");
39
40 let status = Command::new(shell)
41 .arg("-lc") .arg(cmd_string)
43 .status()?;
44
45 if !status.success() {
46 return Err(eyre::eyre!(
47 "Shell command exited with status {:?}",
48 status.code()
49 ));
50 }
51 Ok(())
52 }
53}