feat(utils): Support non-exe commands on Windows (#2019)

Have added support to the `utils::exec_cmd` to allow it to execute
commands that are not `.exe` on Windows. Have also added a timer to
measure how long a command took to execute.
This commit is contained in:
Thomas O'Donnell 2020-12-22 17:44:38 +01:00 committed by GitHub
parent dc7ad58317
commit 85de6dfe50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 4 deletions

31
Cargo.lock generated
View File

@ -1240,6 +1240,7 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
"unicode-width", "unicode-width",
"urlencoding", "urlencoding",
"which",
"winapi", "winapi",
"yaml-rust", "yaml-rust",
] ]
@ -1349,6 +1350,26 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "thiserror"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab"
dependencies = [
"proc-macro2",
"quote 1.0.7",
"syn 1.0.44",
]
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "1.0.1" version = "1.0.1"
@ -1496,6 +1517,16 @@ version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "which"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
dependencies = [
"libc",
"thiserror",
]
[[package]] [[package]]
name = "wildmatch" name = "wildmatch"
version = "1.0.11" version = "1.0.11"

View File

@ -63,6 +63,7 @@ serde = { version = "1.0.118", features = ["derive"] }
indexmap = "1.6.1" indexmap = "1.6.1"
notify-rust = { version = "4.0.0", optional = true } notify-rust = { version = "4.0.0", optional = true }
semver = "0.11.0" semver = "0.11.0"
which = "4.0.2"
# Optional/http: # Optional/http:
attohttpc = { version = "0.16.0", optional = true, default-features = false, features = ["tls", "form"] } attohttpc = { version = "0.16.0", optional = true, default-features = false, features = ["tls", "form"] }

View File

@ -2,6 +2,7 @@ use std::fs::File;
use std::io::{Read, Result}; use std::io::{Read, Result};
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::time::Instant;
use crate::context::Shell; use crate::context::Shell;
@ -243,14 +244,31 @@ pub fn wrap_seq_for_shell(
fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> { fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
log::trace!("Executing command {:?} with args {:?}", cmd, args); log::trace!("Executing command {:?} with args {:?}", cmd, args);
match Command::new(cmd).args(args).output() {
let full_path = match which::which(cmd) {
Ok(full_path) => {
log::trace!("Using {:?} as {:?}", full_path, cmd);
full_path
}
Err(e) => {
log::trace!("Unable to find {:?} in PATH, {:?}", cmd, e);
return None;
}
};
let start = Instant::now();
match Command::new(full_path).args(args).output() {
Ok(output) => { Ok(output) => {
let stdout_string = String::from_utf8(output.stdout).unwrap(); let stdout_string = String::from_utf8(output.stdout).unwrap();
let stderr_string = String::from_utf8(output.stderr).unwrap(); let stderr_string = String::from_utf8(output.stderr).unwrap();
log::trace!("stdout: {:?}", stdout_string); log::trace!(
log::trace!("stderr: {:?}", stderr_string); "stdout: {:?}, stderr: {:?}, exit code: \"{:?}\", took {:?}",
log::trace!("exit code: \"{:?}\"", output.status.code()); stdout_string,
stderr_string,
output.status.code(),
start.elapsed()
);
if !output.status.success() { if !output.status.success() {
return None; return None;