gw_bin/actions/utils/
command.rs1use duct::{cmd, Expression};
2use duct_sh::sh_dangerous;
3use log::{trace, warn};
4
5pub fn create_command(original_command: &str, runs_in_shell: bool) -> Option<(String, Expression)> {
6 if !runs_in_shell {
8 let contains_variables = original_command
9 .find('$')
10 .and_then(|pos| original_command.chars().nth(pos + 1))
11 .map(|ch| ch.is_ascii_alphabetic() || ch == '{')
12 == Some(true);
13
14 let contains_suspicious = original_command.contains(" | ")
15 || original_command.contains(" && ")
16 || original_command.contains(" || ");
17
18 if contains_variables || contains_suspicious {
19 warn!("The command {original_command:?} contains a variable or other shell-specific character: you might want to run it in a shell (-S or -P).")
20 }
21 }
22
23 let split_args = shlex::split(original_command)?;
25 let (command, args) = split_args.split_first()?;
26
27 let script = if runs_in_shell {
29 sh_dangerous(original_command)
30 } else {
31 cmd(command, args)
32 };
33
34 trace!("Parsed {original_command:?} to {script:?}.");
35
36 Some((command.clone(), script))
37}