mirror of
https://github.com/starship/starship.git
synced 2024-11-25 17:54:08 +01:00
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 <andytom@users.noreply.github.com> Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com>
This commit is contained in:
parent
04d1332f9c
commit
eccbda8328
@ -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<Module<'a>> {
|
||||
@ -51,20 +50,19 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
## 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<Module<'a>> {
|
||||
// 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
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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<u128> {
|
||||
self.properties.get("cmd_duration")?.parse::<u128>().ok()
|
||||
}
|
||||
|
||||
/// Execute a command and return the output on stdout and stderr if successful
|
||||
pub fn exec_cmd(&self, cmd: &str, args: &[&str]) -> Option<CommandOutput> {
|
||||
exec_cmd(cmd, args, self.cmd_timeout)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -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<Module<'a>> {
|
||||
_ => 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),
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -66,9 +66,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
"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<String> {
|
||||
}
|
||||
|
||||
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<String> {
|
||||
Some(value?.to_str()?.to_ascii_lowercase())
|
||||
}
|
||||
|
||||
fn get_version_from_cli() -> Option<Version> {
|
||||
let version_output = utils::exec_cmd("dotnet", &["--version"])?;
|
||||
fn get_version_from_cli(context: &Context) -> Option<Version> {
|
||||
let version_output = context.exec_cmd("dotnet", &["--version"])?;
|
||||
Some(Version(format!("v{}", version_output.stdout.trim())))
|
||||
}
|
||||
|
||||
fn get_latest_sdk_from_cli() -> Option<Version> {
|
||||
match utils::exec_cmd("dotnet", &["--list-sdks"]) {
|
||||
fn get_latest_sdk_from_cli(context: &Context) -> Option<Version> {
|
||||
match context.exec_cmd("dotnet", &["--list-sdks"]) {
|
||||
Some(sdks_output) => {
|
||||
fn parse_failed<T>() -> Option<T> {
|
||||
log::warn!("Unable to parse the output from `dotnet --list-sdks`.");
|
||||
@ -325,7 +332,7 @@ fn get_latest_sdk_from_cli() -> Option<Version> {
|
||||
"Received a non-success exit code from `dotnet --list-sdks`. \
|
||||
Falling back to `dotnet --version`.",
|
||||
);
|
||||
get_version_from_cli()
|
||||
get_version_from_cli(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Module<'a>> {
|
||||
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<Module<'a>> {
|
||||
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)
|
||||
}
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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))
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
_ => 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<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_erlang_version() -> Option<String> {
|
||||
use crate::utils;
|
||||
|
||||
Some(utils::exec_cmd(
|
||||
fn get_erlang_version(context: &Context) -> Option<String> {
|
||||
Some(context.exec_cmd(
|
||||
"erl",
|
||||
&[
|
||||
"-noshell",
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
})
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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(),
|
||||
)
|
||||
|
@ -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<version>[\\d\\.]+)[^\\s]*\\s(?:built|from)";
|
||||
|
||||
@ -72,7 +70,7 @@ fn get_java_version(context: &Context) -> Option<String> {
|
||||
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 {
|
||||
|
@ -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<Module<'a>> {
|
||||
_ => 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)
|
||||
|
@ -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<version>[\\d\\.]+[\\d\\.]+[\\d\\.]+)";
|
||||
@ -35,8 +34,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
})
|
||||
.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<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_kotlin_version(kotlin_binary: &str) -> Option<String> {
|
||||
match utils::exec_cmd(kotlin_binary, &["-version"]) {
|
||||
fn get_kotlin_version(context: &Context, kotlin_binary: &str) -> Option<String> {
|
||||
match context.exec_cmd(kotlin_binary, &["-version"]) {
|
||||
Some(output) => {
|
||||
if output.stdout.is_empty() {
|
||||
Some(output.stderr)
|
||||
|
@ -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<version>[\\d\\.]+[a-z\\-]*[1-9]*)[^\\s]*";
|
||||
@ -39,7 +38,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
})
|
||||
.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<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_lua_version(lua_binary: &str) -> Option<String> {
|
||||
match utils::exec_cmd(lua_binary, &["-v"]) {
|
||||
fn get_lua_version(context: &Context, lua_binary: &str) -> Option<String> {
|
||||
match context.exec_cmd(lua_binary, &["-v"]) {
|
||||
Some(output) => {
|
||||
if output.stdout.is_empty() {
|
||||
Some(output.stderr)
|
||||
|
@ -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<Module<'a>> {
|
||||
_ => 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)?))
|
||||
|
@ -38,8 +38,11 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
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 {
|
||||
|
@ -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<Module<'a>> {
|
||||
.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())))
|
||||
}
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.map(|variable| match variable {
|
||||
"version" => {
|
||||
let php_cmd_output = utils::exec_cmd(
|
||||
let php_cmd_output = context.exec_cmd(
|
||||
"php",
|
||||
&[
|
||||
"-nr",
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -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<Module<'a>> {
|
||||
@ -42,7 +41,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
})
|
||||
.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<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_python_version(config: &PythonConfig) -> Option<String> {
|
||||
fn get_python_version(context: &Context, config: &PythonConfig) -> Option<String> {
|
||||
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)
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
})
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -38,7 +38,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
})
|
||||
.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),
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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,
|
||||
|
@ -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<Module<'a>> {
|
||||
})
|
||||
.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))
|
||||
}
|
||||
|
38
src/utils.rs
38
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<CommandOutput> {
|
||||
internal_exec_cmd(&cmd, &args)
|
||||
pub fn exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<CommandOutput> {
|
||||
internal_exec_cmd(&cmd, &args, time_limit)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
|
||||
pub fn exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<CommandOutput> {
|
||||
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<CommandOutput> {
|
||||
fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<CommandOutput> {
|
||||
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<CommandOutput> {
|
||||
}
|
||||
};
|
||||
|
||||
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<CommandOutput> {
|
||||
})
|
||||
}
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user