From eccbda8328159adbb261112cba285d1f63ae29e7 Mon Sep 17 00:00:00 2001 From: David Knaack Date: Thu, 11 Feb 2021 21:34:47 +0100 Subject: [PATCH] feat: allow changing default command timeout (#2283) * feat: allow changing default command timeout * fix clippy * add doc to exec_cmd in Context * update docs in CONTRIBUTING.md * Fix comment in CONTRIBUTING.md Co-authored-by: Thomas O'Donnell Co-authored-by: Thomas O'Donnell --- CONTRIBUTING.md | 8 +++----- src/bug_report.rs | 3 ++- src/configs/starship_root.rs | 2 ++ src/context.rs | 12 ++++++++++++ src/modules/cmake.rs | 4 ++-- src/modules/crystal.rs | 3 +-- src/modules/dart.rs | 3 +-- src/modules/dotnet.rs | 27 +++++++++++++++---------- src/modules/elixir.rs | 7 +++---- src/modules/elm.rs | 3 +-- src/modules/erlang.rs | 8 +++----- src/modules/golang.rs | 4 ++-- src/modules/helm.rs | 4 ++-- src/modules/java.rs | 4 +--- src/modules/julia.rs | 9 ++++----- src/modules/kotlin.rs | 11 ++++++----- src/modules/lua.rs | 8 ++++---- src/modules/nim.rs | 4 ++-- src/modules/nodejs.rs | 7 +++++-- src/modules/ocaml.rs | 5 ++--- src/modules/perl.rs | 6 +++--- src/modules/php.rs | 3 +-- src/modules/purescript.rs | 3 +-- src/modules/python.rs | 9 ++++----- src/modules/ruby.rs | 3 +-- src/modules/swift.rs | 3 +-- src/modules/terraform.rs | 2 +- src/modules/vagrant.rs | 3 +-- src/modules/zig.rs | 3 +-- src/utils.rs | 38 ++++++++++++++++++++++-------------- 30 files changed, 112 insertions(+), 97 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 314908a8..0a0a23de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::php::PhpConfig; use crate::formatter::StringFormatter; -use crate::utils; pub fn module<'a>(context: &'a Context) -> Option> { @@ -51,20 +50,19 @@ pub fn module<'a>(context: &'a Context) -> Option> { ## External commands -To run a external command (e.g. to get the version of a tool) and to allow for mocking use the `utils::exec_cmd` function. Here's a quick example: +To run a external command (e.g. to get the version of a tool) and to allow for mocking use the `context.exec_cmd` function. Here's a quick example: ```rust use super::{Context, Module, RootModuleConfig}; use crate::configs::php::PhpConfig; use crate::formatter::StringFormatter; -use crate::utils; pub fn module<'a>(context: &'a Context) -> Option> { - // Here `my_env_var` will be either the stdout of the called command or the function + // Here `output` will be either the stdout of the called command or the function // will exit if the called program was not installed or could not be run. - let output = utils::exec_cmd("my_command", &["first_arg", "second_arg"])?.stdout; + let output = context.exec_cmd("my_command", &["first_arg", "second_arg"])?.stdout; // Then you can happily use the output } diff --git a/src/bug_report.rs b/src/bug_report.rs index 261c7be5..d93fcc80 100644 --- a/src/bug_report.rs +++ b/src/bug_report.rs @@ -3,6 +3,7 @@ use crate::utils::exec_cmd; use std::fs; use std::path::PathBuf; +use std::time::Duration; #[cfg(feature = "http")] const GIT_IO_BASE_URL: &str = "https://git.io/"; @@ -152,7 +153,7 @@ fn get_shell_info() -> ShellInfo { let shell = shell.unwrap(); - let version = exec_cmd(&shell, &["--version"]) + let version = exec_cmd(&shell, &["--version"], Duration::from_millis(500)) .map(|output| output.stdout.trim().to_string()) .unwrap_or_else(|| UNKNOWN_VERSION.to_string()); diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 5450747e..0c9ccc8f 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -6,6 +6,7 @@ use starship_module_config_derive::ModuleConfig; pub struct StarshipRootConfig<'a> { pub format: &'a str, pub scan_timeout: u64, + pub command_timeout: u64, pub add_newline: bool, } @@ -78,6 +79,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { StarshipRootConfig { format: "$all", scan_timeout: 30, + command_timeout: 500, add_newline: true, } } diff --git a/src/context.rs b/src/context.rs index 8b97d6ca..2ce55258 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,5 +1,6 @@ use crate::config::StarshipConfig; use crate::module::Module; +use crate::utils::{exec_cmd, CommandOutput}; use crate::modules; use clap::ArgMatches; @@ -43,6 +44,9 @@ pub struct Context<'a> { /// A HashMap of environment variable mocks pub env: HashMap<&'a str, String>, + + /// Timeout for the execution of commands + cmd_timeout: Duration, } impl<'a> Context<'a> { @@ -100,6 +104,8 @@ impl<'a> Context<'a> { let current_dir = current_dir.canonicalize().unwrap_or(current_dir); let logical_dir = logical_path; + let cmd_timeout = Duration::from_millis(config.get_root_config().command_timeout); + Context { config, properties, @@ -109,6 +115,7 @@ impl<'a> Context<'a> { repo: OnceCell::new(), shell, env: HashMap::new(), + cmd_timeout, } } @@ -237,6 +244,11 @@ impl<'a> Context<'a> { pub fn get_cmd_duration(&self) -> Option { self.properties.get("cmd_duration")?.parse::().ok() } + + /// Execute a command and return the output on stdout and stderr if successful + pub fn exec_cmd(&self, cmd: &str, args: &[&str]) -> Option { + exec_cmd(cmd, args, self.cmd_timeout) + } } #[derive(Debug)] diff --git a/src/modules/cmake.rs b/src/modules/cmake.rs index aef0a8ce..638b7d72 100644 --- a/src/modules/cmake.rs +++ b/src/modules/cmake.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::cmake::CMakeConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current CMake version /// @@ -31,7 +30,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { _ => None, }) .map(|variable| match variable { - "version" => utils::exec_cmd("cmake", &["--version"]) + "version" => context + .exec_cmd("cmake", &["--version"]) .map(|output| format_cmake_version(&output.stdout)) .flatten() .map(Ok), diff --git a/src/modules/crystal.rs b/src/modules/crystal.rs index 33140b55..9ba121eb 100644 --- a/src/modules/crystal.rs +++ b/src/modules/crystal.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::crystal::CrystalConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Crystal version /// @@ -35,7 +34,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => format_crystal_version( - utils::exec_cmd("crystal", &["--version"])?.stdout.as_str(), + context.exec_cmd("crystal", &["--version"])?.stdout.as_str(), ) .map(Ok), _ => None, diff --git a/src/modules/dart.rs b/src/modules/dart.rs index cd2b297f..5206bd7a 100644 --- a/src/modules/dart.rs +++ b/src/modules/dart.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::dart::DartConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Dart version /// @@ -37,7 +36,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let dart_version = utils::exec_cmd("dart", &["--version"])?.stderr; + let dart_version = context.exec_cmd("dart", &["--version"])?.stderr; parse_dart_version(&dart_version).map(Ok) } _ => None, diff --git a/src/modules/dotnet.rs b/src/modules/dotnet.rs index 8bb64768..7b8b04cd 100644 --- a/src/modules/dotnet.rs +++ b/src/modules/dotnet.rs @@ -66,9 +66,14 @@ pub fn module<'a>(context: &'a Context) -> Option> { "version" => { let version = if enable_heuristic { let repo_root = context.get_repo().ok().and_then(|r| r.root.as_deref()); - estimate_dotnet_version(&dotnet_files, &context.current_dir, repo_root) + estimate_dotnet_version( + context, + &dotnet_files, + &context.current_dir, + repo_root, + ) } else { - get_version_from_cli() + get_version_from_cli(context) }; version.map(|v| Ok(v.0)) } @@ -136,6 +141,7 @@ fn get_tfm_from_project_file(path: &Path) -> Option { } fn estimate_dotnet_version( + context: &Context, files: &[DotNetFile], current_dir: &Path, repo_root: Option<&Path>, @@ -150,17 +156,18 @@ fn estimate_dotnet_version( match relevant_file.file_type { FileType::GlobalJson => get_pinned_sdk_version_from_file(relevant_file.path.as_path()) - .or_else(get_latest_sdk_from_cli), + .or_else(|| get_latest_sdk_from_cli(context)), FileType::SolutionFile => { // With this heuristic, we'll assume that a "global.json" won't // be found in any directory above the solution file. - get_latest_sdk_from_cli() + get_latest_sdk_from_cli(context) } _ => { // If we see a dotnet project, we'll check a small number of neighboring // directories to see if we can find a global.json. Otherwise, assume the // latest SDK is in use. - try_find_nearby_global_json(current_dir, repo_root).or_else(get_latest_sdk_from_cli) + try_find_nearby_global_json(current_dir, repo_root) + .or_else(|| get_latest_sdk_from_cli(context)) } } } @@ -288,13 +295,13 @@ fn map_str_to_lower(value: Option<&OsStr>) -> Option { Some(value?.to_str()?.to_ascii_lowercase()) } -fn get_version_from_cli() -> Option { - let version_output = utils::exec_cmd("dotnet", &["--version"])?; +fn get_version_from_cli(context: &Context) -> Option { + let version_output = context.exec_cmd("dotnet", &["--version"])?; Some(Version(format!("v{}", version_output.stdout.trim()))) } -fn get_latest_sdk_from_cli() -> Option { - match utils::exec_cmd("dotnet", &["--list-sdks"]) { +fn get_latest_sdk_from_cli(context: &Context) -> Option { + match context.exec_cmd("dotnet", &["--list-sdks"]) { Some(sdks_output) => { fn parse_failed() -> Option { log::warn!("Unable to parse the output from `dotnet --list-sdks`."); @@ -325,7 +332,7 @@ fn get_latest_sdk_from_cli() -> Option { "Received a non-success exit code from `dotnet --list-sdks`. \ Falling back to `dotnet --version`.", ); - get_version_from_cli() + get_version_from_cli(context) } } } diff --git a/src/modules/elixir.rs b/src/modules/elixir.rs index 3fd31fa2..22489b7c 100644 --- a/src/modules/elixir.rs +++ b/src/modules/elixir.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::elixir::ElixirConfig; use crate::formatter::StringFormatter; -use crate::utils; use once_cell::sync::Lazy; use regex::Regex; @@ -23,7 +22,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { return None; } - let versions = Lazy::new(get_elixir_version); + let versions = Lazy::new(|| get_elixir_version(context)); let mut module = context.new_module("elixir"); let config = ElixirConfig::try_load(module.config); @@ -64,8 +63,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_elixir_version() -> Option<(String, String)> { - let output = utils::exec_cmd("elixir", &["--version"])?.stdout; +fn get_elixir_version(context: &Context) -> Option<(String, String)> { + let output = context.exec_cmd("elixir", &["--version"])?.stdout; parse_elixir_version(&output) } diff --git a/src/modules/elm.rs b/src/modules/elm.rs index b4773c46..b3ee4338 100644 --- a/src/modules/elm.rs +++ b/src/modules/elm.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::elm::ElmConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Elm version /// @@ -39,7 +38,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let elm_version = utils::exec_cmd("elm", &["--version"])?.stdout; + let elm_version = context.exec_cmd("elm", &["--version"])?.stdout; let module_version = Some(format!("v{}", elm_version.trim()))?; Some(Ok(module_version)) } diff --git a/src/modules/erlang.rs b/src/modules/erlang.rs index 02ddbd88..90adf3b8 100644 --- a/src/modules/erlang.rs +++ b/src/modules/erlang.rs @@ -32,7 +32,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { _ => None, }) .map(|variable| match variable { - "version" => get_erlang_version().map(Ok), + "version" => get_erlang_version(context).map(Ok), _ => None, }) .parse(None) @@ -49,10 +49,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_erlang_version() -> Option { - use crate::utils; - - Some(utils::exec_cmd( +fn get_erlang_version(context: &Context) -> Option { + Some(context.exec_cmd( "erl", &[ "-noshell", diff --git a/src/modules/golang.rs b/src/modules/golang.rs index 58d5e744..77aa062f 100644 --- a/src/modules/golang.rs +++ b/src/modules/golang.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::go::GoConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Go version /// @@ -48,7 +47,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - format_go_version(&utils::exec_cmd("go", &["version"])?.stdout.as_str()).map(Ok) + format_go_version(&context.exec_cmd("go", &["version"])?.stdout.as_str()) + .map(Ok) } _ => None, }) diff --git a/src/modules/helm.rs b/src/modules/helm.rs index 9c80b7a9..8e206a8d 100644 --- a/src/modules/helm.rs +++ b/src/modules/helm.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::helm::HelmConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Helm version /// @@ -33,7 +32,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => format_helm_version( - &utils::exec_cmd("helm", &["version", "--short", "--client"])? + &context + .exec_cmd("helm", &["version", "--short", "--client"])? .stdout .as_str(), ) diff --git a/src/modules/java.rs b/src/modules/java.rs index dffec6e9..9fa1789b 100644 --- a/src/modules/java.rs +++ b/src/modules/java.rs @@ -3,8 +3,6 @@ use crate::formatter::StringFormatter; use super::{Context, Module, RootModuleConfig}; -use crate::utils; - use regex::Regex; const JAVA_VERSION_PATTERN: &str = "(?P[\\d\\.]+)[^\\s]*\\s(?:built|from)"; @@ -72,7 +70,7 @@ fn get_java_version(context: &Context) -> Option { None => String::from("java"), }; - let output = utils::exec_cmd(&java_command.as_str(), &["-Xinternalversion"])?; + let output = context.exec_cmd(&java_command.as_str(), &["-Xinternalversion"])?; let java_version = if output.stdout.is_empty() { output.stderr } else { diff --git a/src/modules/julia.rs b/src/modules/julia.rs index cfd292fa..db729d33 100644 --- a/src/modules/julia.rs +++ b/src/modules/julia.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::julia::JuliaConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Julia version /// @@ -34,10 +33,10 @@ pub fn module<'a>(context: &'a Context) -> Option> { _ => None, }) .map(|variable| match variable { - "version" => { - format_julia_version(&utils::exec_cmd("julia", &["--version"])?.stdout.as_str()) - .map(Ok) - } + "version" => format_julia_version( + &context.exec_cmd("julia", &["--version"])?.stdout.as_str(), + ) + .map(Ok), _ => None, }) .parse(None) diff --git a/src/modules/kotlin.rs b/src/modules/kotlin.rs index 267b5378..bebfb03a 100644 --- a/src/modules/kotlin.rs +++ b/src/modules/kotlin.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::kotlin::KotlinConfig; use crate::formatter::StringFormatter; -use crate::utils; use regex::Regex; const KOTLIN_VERSION_PATTERN: &str = "(?P[\\d\\.]+[\\d\\.]+[\\d\\.]+)"; @@ -35,8 +34,10 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let kotlin_version = - format_kotlin_version(&get_kotlin_version(&config.kotlin_binary)?)?; + let kotlin_version = format_kotlin_version(&get_kotlin_version( + context, + &config.kotlin_binary, + )?)?; Some(Ok(kotlin_version)) } _ => None, @@ -55,8 +56,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_kotlin_version(kotlin_binary: &str) -> Option { - match utils::exec_cmd(kotlin_binary, &["-version"]) { +fn get_kotlin_version(context: &Context, kotlin_binary: &str) -> Option { + match context.exec_cmd(kotlin_binary, &["-version"]) { Some(output) => { if output.stdout.is_empty() { Some(output.stderr) diff --git a/src/modules/lua.rs b/src/modules/lua.rs index 3b30eb1c..8c7aa556 100644 --- a/src/modules/lua.rs +++ b/src/modules/lua.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::lua::LuaConfig; use crate::formatter::StringFormatter; -use crate::utils; use regex::Regex; const LUA_VERSION_PATERN: &str = "(?P[\\d\\.]+[a-z\\-]*[1-9]*)[^\\s]*"; @@ -39,7 +38,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let lua_version = format_lua_version(&get_lua_version(&config.lua_binary)?)?; + let lua_version = + format_lua_version(&get_lua_version(context, &config.lua_binary)?)?; Some(Ok(lua_version)) } _ => None, @@ -58,8 +58,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_lua_version(lua_binary: &str) -> Option { - match utils::exec_cmd(lua_binary, &["-v"]) { +fn get_lua_version(context: &Context, lua_binary: &str) -> Option { + match context.exec_cmd(lua_binary, &["-v"]) { Some(output) => { if output.stdout.is_empty() { Some(output.stderr) diff --git a/src/modules/nim.rs b/src/modules/nim.rs index ce37711b..75af863c 100644 --- a/src/modules/nim.rs +++ b/src/modules/nim.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::nim::NimConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Nim version /// @@ -34,7 +33,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { _ => None, }) .map(|variable| match variable { - "version" => utils::exec_cmd("nim", &["--version"]) + "version" => context + .exec_cmd("nim", &["--version"]) .map(|command_output| command_output.stdout) .and_then(|nim_version_output| { Some(format!("v{}", parse_nim_version(&nim_version_output)?)) diff --git a/src/modules/nodejs.rs b/src/modules/nodejs.rs index 137857ef..be65b8f9 100644 --- a/src/modules/nodejs.rs +++ b/src/modules/nodejs.rs @@ -38,8 +38,11 @@ pub fn module<'a>(context: &'a Context) -> Option> { let mut module = context.new_module("nodejs"); let config = NodejsConfig::try_load(module.config); - let nodejs_version = - Lazy::new(|| utils::exec_cmd("node", &["--version"]).map(|cmd| cmd.stdout)); + let nodejs_version = Lazy::new(|| { + context + .exec_cmd("node", &["--version"]) + .map(|cmd| cmd.stdout) + }); let parsed = StringFormatter::new(config.format).and_then(|formatter| { formatter .map_meta(|var, _| match var { diff --git a/src/modules/ocaml.rs b/src/modules/ocaml.rs index 8bc7d91a..0c7bd8d7 100644 --- a/src/modules/ocaml.rs +++ b/src/modules/ocaml.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::ocaml::OCamlConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current OCaml version /// @@ -46,9 +45,9 @@ pub fn module<'a>(context: &'a Context) -> Option> { .is_match(); let ocaml_version = if is_esy_project { - utils::exec_cmd("esy", &["ocaml", "-vnum"])?.stdout + context.exec_cmd("esy", &["ocaml", "-vnum"])?.stdout } else { - utils::exec_cmd("ocaml", &["-vnum"])?.stdout + context.exec_cmd("ocaml", &["-vnum"])?.stdout }; Some(Ok(format!("v{}", &ocaml_version.trim()))) } diff --git a/src/modules/perl.rs b/src/modules/perl.rs index b3a6e7be..a307e287 100644 --- a/src/modules/perl.rs +++ b/src/modules/perl.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::perl::PerlConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current perl version /// @@ -44,8 +43,9 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let perl_version = - utils::exec_cmd("perl", &["-e", "printf q#%vd#,$^V;"])?.stdout; + let perl_version = context + .exec_cmd("perl", &["-e", "printf q#%vd#,$^V;"])? + .stdout; Some(Ok(format!("v{}", perl_version))) } _ => None, diff --git a/src/modules/php.rs b/src/modules/php.rs index 62d99414..f85cbd21 100644 --- a/src/modules/php.rs +++ b/src/modules/php.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::php::PhpConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current PHP version /// @@ -35,7 +34,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let php_cmd_output = utils::exec_cmd( + let php_cmd_output = context.exec_cmd( "php", &[ "-nr", diff --git a/src/modules/purescript.rs b/src/modules/purescript.rs index 96d189bb..4252ae1e 100644 --- a/src/modules/purescript.rs +++ b/src/modules/purescript.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::purescript::PureScriptConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current PureScript version /// @@ -35,7 +34,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let purs_version = utils::exec_cmd("purs", &["--version"])?.stdout; + let purs_version = context.exec_cmd("purs", &["--version"])?.stdout; Some(Ok(format!("v{}", purs_version.trim()))) } _ => None, diff --git a/src/modules/python.rs b/src/modules/python.rs index dca60127..8fda37fc 100644 --- a/src/modules/python.rs +++ b/src/modules/python.rs @@ -4,7 +4,6 @@ use std::path::Path; use super::{Context, Module, RootModuleConfig}; use crate::configs::python::PythonConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Python version and, if active, virtual environment. pub fn module<'a>(context: &'a Context) -> Option> { @@ -42,7 +41,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let version = get_python_version(&config)?; + let version = get_python_version(context, &config)?; Some(Ok(version.trim().to_string())) } "virtualenv" => { @@ -66,12 +65,12 @@ pub fn module<'a>(context: &'a Context) -> Option> { Some(module) } -fn get_python_version(config: &PythonConfig) -> Option { +fn get_python_version(context: &Context, config: &PythonConfig) -> Option { if config.pyenv_version_name { - return Some(utils::exec_cmd("pyenv", &["version-name"])?.stdout); + return Some(context.exec_cmd("pyenv", &["version-name"])?.stdout); }; let version = config.python_binary.0.iter().find_map(|binary| { - match utils::exec_cmd(binary, &["--version"]) { + match context.exec_cmd(binary, &["--version"]) { Some(output) => { if output.stdout.is_empty() { Some(output.stderr) diff --git a/src/modules/ruby.rs b/src/modules/ruby.rs index 97c4c31e..6772d750 100644 --- a/src/modules/ruby.rs +++ b/src/modules/ruby.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::ruby::RubyConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Ruby version /// @@ -34,7 +33,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - format_ruby_version(&utils::exec_cmd("ruby", &["-v"])?.stdout.as_str()).map(Ok) + format_ruby_version(&context.exec_cmd("ruby", &["-v"])?.stdout.as_str()).map(Ok) } _ => None, }) diff --git a/src/modules/swift.rs b/src/modules/swift.rs index 18695c4c..1cf2cd30 100644 --- a/src/modules/swift.rs +++ b/src/modules/swift.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::swift::SwiftConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Swift version /// @@ -34,7 +33,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let swift_version = utils::exec_cmd("swift", &["--version"])?.stdout; + let swift_version = context.exec_cmd("swift", &["--version"])?.stdout; parse_swift_version(&swift_version).map(Ok) } _ => None, diff --git a/src/modules/terraform.rs b/src/modules/terraform.rs index 95d3706e..f3cf168a 100644 --- a/src/modules/terraform.rs +++ b/src/modules/terraform.rs @@ -38,7 +38,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => format_terraform_version( - &utils::exec_cmd("terraform", &["version"])?.stdout.as_str(), + &context.exec_cmd("terraform", &["version"])?.stdout.as_str(), ) .map(Ok), "workspace" => get_terraform_workspace(context).map(Ok), diff --git a/src/modules/vagrant.rs b/src/modules/vagrant.rs index 45563c2b..99f8bd6a 100644 --- a/src/modules/vagrant.rs +++ b/src/modules/vagrant.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::vagrant::VagrantConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Vagrant version /// @@ -32,7 +31,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => format_vagrant_version( - &utils::exec_cmd("vagrant", &["--version"])?.stdout.as_str(), + &context.exec_cmd("vagrant", &["--version"])?.stdout.as_str(), ) .map(Ok), _ => None, diff --git a/src/modules/zig.rs b/src/modules/zig.rs index b8b3eac3..64f0b98a 100644 --- a/src/modules/zig.rs +++ b/src/modules/zig.rs @@ -2,7 +2,6 @@ use super::{Context, Module, RootModuleConfig}; use crate::configs::zig::ZigConfig; use crate::formatter::StringFormatter; -use crate::utils; /// Creates a module with the current Zig version /// @@ -33,7 +32,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { }) .map(|variable| match variable { "version" => { - let zig_version_output = utils::exec_cmd("zig", &["version"])?.stdout; + let zig_version_output = context.exec_cmd("zig", &["version"])?.stdout; let zig_version = format!("v{}", zig_version_output.trim()); Some(Ok(zig_version)) } diff --git a/src/utils.rs b/src/utils.rs index 6d561222..8d73a3f4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -30,12 +30,12 @@ impl PartialEq for CommandOutput { /// Execute a command and return the output on stdout and stderr if successful #[cfg(not(test))] -pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option { - internal_exec_cmd(&cmd, &args) +pub fn exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option { + internal_exec_cmd(&cmd, &args, time_limit) } #[cfg(test)] -pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option { +pub fn exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option { let command = match args.len() { 0 => String::from(cmd), _ => format!("{} {}", cmd, args.join(" ")), @@ -202,7 +202,7 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake).\n", stderr: String::default(), }), // If we don't have a mocked command fall back to executing the command - _ => internal_exec_cmd(&cmd, &args), + _ => internal_exec_cmd(&cmd, &args, time_limit), } } @@ -255,7 +255,7 @@ pub fn wrap_seq_for_shell( final_string } -fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option { +fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option { log::trace!("Executing command {:?} with args {:?}", cmd, args); let full_path = match which::which(cmd) { @@ -269,8 +269,6 @@ fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option { } }; - let time_limit = Duration::from_millis(500); - let start = Instant::now(); let process = match Command::new(full_path) @@ -310,7 +308,8 @@ fn internal_exec_cmd(cmd: &str, args: &[&str]) -> Option { }) } Ok(None) => { - log::warn!("Executing command {:?} timed out", cmd); + log::warn!("Executing command {:?} timed out.", cmd); + log::warn!("You can set command_timeout in your config to a higher value to allow longer-running commands to keep executing."); None } Err(error) => { @@ -326,7 +325,7 @@ mod tests { #[test] fn exec_mocked_command() { - let result = exec_cmd("dummy_command", &[]); + let result = exec_cmd("dummy_command", &[], Duration::from_millis(500)); let expected = Some(CommandOutput { stdout: String::from("stdout ok!\n"), stderr: String::from("stderr ok!\n"), @@ -341,7 +340,7 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_no_output() { - let result = internal_exec_cmd("true", &[]); + let result = internal_exec_cmd("true", &[], Duration::from_millis(500)); let expected = Some(CommandOutput { stdout: String::from(""), stderr: String::from(""), @@ -353,7 +352,8 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_with_output_stdout() { - let result = internal_exec_cmd("/bin/sh", &["-c", "echo hello"]); + let result = + internal_exec_cmd("/bin/sh", &["-c", "echo hello"], Duration::from_millis(500)); let expected = Some(CommandOutput { stdout: String::from("hello\n"), stderr: String::from(""), @@ -365,7 +365,11 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_with_output_stderr() { - let result = internal_exec_cmd("/bin/sh", &["-c", "echo hello >&2"]); + let result = internal_exec_cmd( + "/bin/sh", + &["-c", "echo hello >&2"], + Duration::from_millis(500), + ); let expected = Some(CommandOutput { stdout: String::from(""), stderr: String::from("hello\n"), @@ -377,7 +381,11 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_with_output_both() { - let result = internal_exec_cmd("/bin/sh", &["-c", "echo hello; echo world >&2"]); + let result = internal_exec_cmd( + "/bin/sh", + &["-c", "echo hello; echo world >&2"], + Duration::from_millis(500), + ); let expected = Some(CommandOutput { stdout: String::from("hello\n"), stderr: String::from("world\n"), @@ -389,7 +397,7 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_with_non_zero_exit_code() { - let result = internal_exec_cmd("false", &[]); + let result = internal_exec_cmd("false", &[], Duration::from_millis(500)); let expected = None; assert_eq!(result, expected) @@ -398,7 +406,7 @@ mod tests { #[test] #[cfg(not(windows))] fn exec_slow_command() { - let result = internal_exec_cmd("sleep", &["500"]); + let result = internal_exec_cmd("sleep", &["500"], Duration::from_millis(500)); let expected = None; assert_eq!(result, expected)