From c0f14251a4c842d1fa9c9cf5f2d6b57cf2179662 Mon Sep 17 00:00:00 2001 From: Diego Giagio Date: Mon, 15 Oct 2018 18:44:54 +0200 Subject: [PATCH] Improve execution of .bat and .cmd files on Windows --- warp-runner/src/executor.rs | 77 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/warp-runner/src/executor.rs b/warp-runner/src/executor.rs index b5245cf..270b1b7 100644 --- a/warp-runner/src/executor.rs +++ b/warp-runner/src/executor.rs @@ -1,41 +1,22 @@ use std::env; +use std::io; +use std::path::Path; use std::process::Command; use std::process::Stdio; -use std::path::Path; -use std::io; - -#[cfg(target_family = "windows")] -const PATH_SEPARATOR: char = ';'; - -#[cfg(target_family = "unix")] -const PATH_SEPARATOR: char = ':'; pub fn execute(target: &Path) -> io::Result { - let target_dir = target.parent() - .and_then(|dir| dir.to_str()) - .expect("Unable to construct target directory"); - let target_file_name = target.file_name() - .and_then(|file_name| file_name.to_str()) - .expect("Unable to identify target file name"); trace!("target={:?}", target); - trace!("target_dir={:?}", target_dir); - trace!("target_file_name={:?}", target_file_name); - - let current_path_env = env::var("PATH").unwrap_or(String::new()); - let path_env = format!("{}{}{}", target_dir, PATH_SEPARATOR, current_path_env); - trace!("path_env={:?}", path_env); let args: Vec = env::args().skip(1).collect(); trace!("args={:?}", args); - do_execute(target_file_name, &args, &path_env) + do_execute(target, &args) } #[cfg(target_family = "unix")] -fn do_execute(target: &str, args: &[String], path_env: &str) -> io::Result { +fn do_execute(target: &Path, args: &[String]) -> io::Result { Ok(Command::new(target) .args(args) - .env("PATH", path_env) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) @@ -45,19 +26,41 @@ fn do_execute(target: &str, args: &[String], path_env: &str) -> io::Result } #[cfg(target_family = "windows")] -fn do_execute(target: &str, args: &[String], path_env: &str) -> io::Result { - let mut cmd_args = Vec::with_capacity(args.len() + 2); - cmd_args.push("/c".to_string()); - cmd_args.push(target.to_string()); - cmd_args.extend_from_slice(&args); +fn is_script(target: &Path) -> bool { + const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"]; + SCRIPT_EXTENSIONS.contains( + &target.extension() + .unwrap_or_default() + .to_string_lossy() + .to_lowercase().as_str()) +} - Ok(Command::new("cmd") - .args(cmd_args) - .env("PATH", path_env) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn()? - .wait()? - .code().unwrap_or(1)) +#[cfg(target_family = "windows")] +fn do_execute(target: &Path, args: &[String]) -> io::Result { + let target_str = target.as_os_str().to_str().unwrap(); + + if is_script(target) { + let mut cmd_args = Vec::with_capacity(args.len() + 2); + cmd_args.push("/c".to_string()); + cmd_args.push(target_str.to_string()); + cmd_args.extend_from_slice(&args); + + Ok(Command::new("cmd") + .args(cmd_args) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()? + .wait()? + .code().unwrap_or(1)) + } else { + Ok(Command::new(target) + .args(args) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()? + .wait()? + .code().unwrap_or(1)) + } } \ No newline at end of file