2022-06-18 21:56:31 -07:00
|
|
|
use super::*;
|
2019-11-10 23:17:47 -08:00
|
|
|
|
2022-01-18 11:02:15 -08:00
|
|
|
pub(crate) const DEFAULT_SHELL: &str = "sh";
|
|
|
|
pub(crate) const DEFAULT_SHELL_ARGS: &[&str] = &["-cu"];
|
|
|
|
pub(crate) const WINDOWS_POWERSHELL_SHELL: &str = "powershell.exe";
|
|
|
|
pub(crate) const WINDOWS_POWERSHELL_ARGS: &[&str] = &["-NoLogo", "-Command"];
|
|
|
|
|
2021-11-17 00:07:48 -08:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2019-11-10 23:17:47 -08:00
|
|
|
pub(crate) struct Settings<'src> {
|
2022-02-14 18:37:06 -08:00
|
|
|
pub(crate) allow_duplicate_recipes: bool,
|
2021-09-16 06:44:40 -07:00
|
|
|
pub(crate) dotenv_load: Option<bool>,
|
|
|
|
pub(crate) export: bool,
|
2021-04-24 18:29:58 -07:00
|
|
|
pub(crate) positional_arguments: bool,
|
2022-05-31 13:01:59 -07:00
|
|
|
pub(crate) shell: Option<Shell<'src>>,
|
2022-01-18 11:02:15 -08:00
|
|
|
pub(crate) windows_powershell: bool,
|
2022-05-31 13:01:59 -07:00
|
|
|
pub(crate) windows_shell: Option<Shell<'src>>,
|
2019-11-10 23:17:47 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'src> Settings<'src> {
|
|
|
|
pub(crate) fn new() -> Settings<'src> {
|
2021-03-25 17:00:32 -07:00
|
|
|
Settings {
|
2022-02-14 18:37:06 -08:00
|
|
|
allow_duplicate_recipes: false,
|
2021-09-16 06:44:40 -07:00
|
|
|
dotenv_load: None,
|
|
|
|
export: false,
|
2021-04-24 18:29:58 -07:00
|
|
|
positional_arguments: false,
|
2021-09-16 06:44:40 -07:00
|
|
|
shell: None,
|
2022-01-18 11:02:15 -08:00
|
|
|
windows_powershell: false,
|
2022-05-31 13:01:59 -07:00
|
|
|
windows_shell: None,
|
2021-03-25 17:00:32 -07:00
|
|
|
}
|
2019-11-10 23:17:47 -08:00
|
|
|
}
|
|
|
|
|
2019-11-22 11:33:56 -08:00
|
|
|
pub(crate) fn shell_command(&self, config: &Config) -> Command {
|
2021-03-25 17:44:18 -07:00
|
|
|
let mut cmd = Command::new(self.shell_binary(config));
|
2019-11-10 23:17:47 -08:00
|
|
|
|
2021-03-25 17:44:18 -07:00
|
|
|
cmd.args(self.shell_arguments(config));
|
2019-11-10 23:17:47 -08:00
|
|
|
|
2021-03-25 17:44:18 -07:00
|
|
|
cmd
|
|
|
|
}
|
2019-11-10 23:17:47 -08:00
|
|
|
|
2021-03-25 17:44:18 -07:00
|
|
|
pub(crate) fn shell_binary<'a>(&'a self, config: &'a Config) -> &'a str {
|
2022-01-18 11:02:15 -08:00
|
|
|
let shell_or_args_present = config.shell.is_some() || config.shell_args.is_some();
|
|
|
|
|
|
|
|
if let (Some(shell), false) = (&self.shell, shell_or_args_present) {
|
2021-03-25 17:44:18 -07:00
|
|
|
shell.command.cooked.as_ref()
|
2022-01-18 11:02:15 -08:00
|
|
|
} else if let Some(shell) = &config.shell {
|
|
|
|
shell
|
2022-05-31 13:01:59 -07:00
|
|
|
} else if let (true, Some(shell)) = (cfg!(windows), &self.windows_shell) {
|
|
|
|
shell.command.cooked.as_ref()
|
2022-01-18 11:02:15 -08:00
|
|
|
} else if cfg!(windows) && self.windows_powershell {
|
|
|
|
WINDOWS_POWERSHELL_SHELL
|
2021-03-25 17:44:18 -07:00
|
|
|
} else {
|
2022-01-18 11:02:15 -08:00
|
|
|
DEFAULT_SHELL
|
2021-03-25 17:44:18 -07:00
|
|
|
}
|
|
|
|
}
|
2019-11-10 23:17:47 -08:00
|
|
|
|
2021-03-25 17:44:18 -07:00
|
|
|
pub(crate) fn shell_arguments<'a>(&'a self, config: &'a Config) -> Vec<&'a str> {
|
2022-01-18 11:02:15 -08:00
|
|
|
let shell_or_args_present = config.shell.is_some() || config.shell_args.is_some();
|
|
|
|
|
|
|
|
if let (Some(shell), false) = (&self.shell, shell_or_args_present) {
|
2021-03-25 17:44:18 -07:00
|
|
|
shell
|
|
|
|
.arguments
|
|
|
|
.iter()
|
|
|
|
.map(|argument| argument.cooked.as_ref())
|
|
|
|
.collect()
|
2022-01-18 11:02:15 -08:00
|
|
|
} else if let Some(shell_args) = &config.shell_args {
|
|
|
|
shell_args.iter().map(String::as_ref).collect()
|
2022-05-31 13:01:59 -07:00
|
|
|
} else if let (true, Some(shell)) = (cfg!(windows), &self.windows_shell) {
|
|
|
|
shell
|
|
|
|
.arguments
|
|
|
|
.iter()
|
|
|
|
.map(|argument| argument.cooked.as_ref())
|
|
|
|
.collect()
|
2022-01-18 11:02:15 -08:00
|
|
|
} else if cfg!(windows) && self.windows_powershell {
|
|
|
|
WINDOWS_POWERSHELL_ARGS.to_vec()
|
|
|
|
} else {
|
|
|
|
DEFAULT_SHELL_ARGS.to_vec()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn default_shell() {
|
|
|
|
let settings = Settings::new();
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: false,
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_eq!(settings.shell_binary(&config), "sh");
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-cu"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn default_shell_powershell() {
|
|
|
|
let mut settings = Settings::new();
|
|
|
|
settings.windows_powershell = true;
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: false,
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
if cfg!(windows) {
|
|
|
|
assert_eq!(settings.shell_binary(&config), "powershell.exe");
|
|
|
|
assert_eq!(
|
|
|
|
settings.shell_arguments(&config),
|
|
|
|
vec!["-NoLogo", "-Command"]
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
assert_eq!(settings.shell_binary(&config), "sh");
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-cu"]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn overwrite_shell() {
|
|
|
|
let settings = Settings::new();
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: true,
|
|
|
|
shell: Some("lol".to_string()),
|
|
|
|
shell_args: Some(vec!["-nice".to_string()]),
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_eq!(settings.shell_binary(&config), "lol");
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn overwrite_shell_powershell() {
|
|
|
|
let mut settings = Settings::new();
|
|
|
|
settings.windows_powershell = true;
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: true,
|
|
|
|
shell: Some("lol".to_string()),
|
|
|
|
shell_args: Some(vec!["-nice".to_string()]),
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_eq!(settings.shell_binary(&config), "lol");
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn shell_cooked() {
|
|
|
|
let mut settings = Settings::new();
|
|
|
|
|
|
|
|
settings.shell = Some(Shell {
|
|
|
|
command: StringLiteral {
|
|
|
|
kind: StringKind::from_token_start("\"").unwrap(),
|
|
|
|
raw: "asdf.exe",
|
|
|
|
cooked: "asdf.exe".to_string(),
|
|
|
|
},
|
|
|
|
arguments: vec![StringLiteral {
|
|
|
|
kind: StringKind::from_token_start("\"").unwrap(),
|
|
|
|
raw: "-nope",
|
|
|
|
cooked: "-nope".to_string(),
|
|
|
|
}],
|
|
|
|
});
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: false,
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_eq!(settings.shell_binary(&config), "asdf.exe");
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-nope"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn shell_present_but_not_shell_args() {
|
|
|
|
let mut settings = Settings::new();
|
|
|
|
settings.windows_powershell = true;
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell: Some("lol".to_string()),
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
assert_eq!(settings.shell_binary(&config), "lol");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn shell_args_present_but_not_shell() {
|
|
|
|
let mut settings = Settings::new();
|
|
|
|
settings.windows_powershell = true;
|
|
|
|
|
|
|
|
let config = Config {
|
|
|
|
shell_command: false,
|
|
|
|
shell_args: Some(vec!["-nice".to_string()]),
|
|
|
|
..testing::config(&[])
|
|
|
|
};
|
|
|
|
|
|
|
|
if cfg!(windows) {
|
|
|
|
assert_eq!(settings.shell_binary(&config), "powershell.exe");
|
2021-03-25 17:44:18 -07:00
|
|
|
} else {
|
2022-01-18 11:02:15 -08:00
|
|
|
assert_eq!(settings.shell_binary(&config), "sh");
|
2019-11-10 23:17:47 -08:00
|
|
|
}
|
2022-05-03 23:05:55 -07:00
|
|
|
|
|
|
|
assert_eq!(settings.shell_arguments(&config), vec!["-nice"]);
|
2019-11-10 23:17:47 -08:00
|
|
|
}
|
|
|
|
}
|