diff --git a/packages/perseus-cli/src/errors.rs b/packages/perseus-cli/src/errors.rs index 15d759025f..37b8b042f4 100644 --- a/packages/perseus-cli/src/errors.rs +++ b/packages/perseus-cli/src/errors.rs @@ -5,6 +5,11 @@ use thiserror::Error; /// All errors that can be returned by the CLI. #[derive(Error, Debug)] pub enum Error { + #[error("couldn't find your system shell (sh on unix and powershell on windows), which is required to run the perseus cli")] + ShellNotPresent { + #[source] + source: std::io::Error, + }, #[error("couldn't find `cargo`, which is a dependency of this cli (set 'PERSEUS_CARGO_PATH' to another location if you've installed it elsewhere)")] CargoNotPresent { #[source] diff --git a/packages/perseus-cli/src/prepare.rs b/packages/perseus-cli/src/prepare.rs index 62069171f2..a561d60f93 100644 --- a/packages/perseus-cli/src/prepare.rs +++ b/packages/perseus-cli/src/prepare.rs @@ -22,6 +22,22 @@ pub fn check_env(global_opts: &Opts) -> Result<(), Error> { #[cfg(windows)] let shell_param = "-command"; + // Check for the shell before anything else (#314) + let shell_res = Command::new(shell_exec) + .arg("--version") + .output() + .map_err(|err| Error::ShellNotPresent { source: err })?; + let exit_code = match shell_res.status.code() { + Some(exit_code) => exit_code, + None if shell_res.status.success() => 0, + None => 1, + }; + if exit_code != 0 { + return Err(Error::ShellNotPresent { + source: std::io::Error::new(std::io::ErrorKind::NotFound, "non-zero exit code"), + }); + } + // Check for `cargo` let cargo_cmd = global_opts.cargo_engine_path.to_string() + " --version"; let cargo_res = Command::new(shell_exec)