fix: set cwd for command execution (#3309)
This commit is contained in:
parent
19e084e79b
commit
af98f5b8ce
|
@ -1,7 +1,7 @@
|
||||||
use crate::config::{RootModuleConfig, StarshipConfig};
|
use crate::config::{RootModuleConfig, StarshipConfig};
|
||||||
use crate::configs::StarshipRootConfig;
|
use crate::configs::StarshipRootConfig;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
use crate::utils::{exec_cmd, CommandOutput};
|
use crate::utils::{create_command, exec_timeout, CommandOutput};
|
||||||
|
|
||||||
use crate::modules;
|
use crate::modules;
|
||||||
use crate::utils::{self, home_dir};
|
use crate::utils::{self, home_dir};
|
||||||
|
@ -316,16 +316,27 @@ impl<'a> Context<'a> {
|
||||||
cmd: T,
|
cmd: T,
|
||||||
args: &[U],
|
args: &[U],
|
||||||
) -> Option<CommandOutput> {
|
) -> Option<CommandOutput> {
|
||||||
|
log::trace!(
|
||||||
|
"Executing command {:?} with args {:?} from context",
|
||||||
|
cmd,
|
||||||
|
args
|
||||||
|
);
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
{
|
{
|
||||||
let command = crate::utils::display_command(&cmd, args);
|
let command = crate::utils::display_command(&cmd, args);
|
||||||
if let Some(output) = self.cmd.get(command.as_str()) {
|
if let Some(output) = self
|
||||||
return output.clone();
|
.cmd
|
||||||
|
.get(command.as_str())
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| crate::utils::mock_cmd(&cmd, args))
|
||||||
|
{
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exec_cmd(
|
let mut cmd = create_command(cmd).ok()?;
|
||||||
&cmd,
|
cmd.args(args).current_dir(&self.current_dir);
|
||||||
args,
|
exec_timeout(
|
||||||
|
&mut cmd,
|
||||||
Duration::from_millis(self.root_config.command_timeout),
|
Duration::from_millis(self.root_config.command_timeout),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
59
src/utils.rs
59
src/utils.rs
|
@ -38,7 +38,7 @@ pub fn get_command_string_output(command: CommandOutput) -> String {
|
||||||
/// This function also initialises std{err,out,in} to protect against processes changing the console mode
|
/// This function also initialises std{err,out,in} to protect against processes changing the console mode
|
||||||
pub fn create_command<T: AsRef<OsStr>>(binary_name: T) -> Result<Command> {
|
pub fn create_command<T: AsRef<OsStr>>(binary_name: T) -> Result<Command> {
|
||||||
let binary_name = binary_name.as_ref();
|
let binary_name = binary_name.as_ref();
|
||||||
log::trace!("Creating Command struct with binary name {:?}", binary_name);
|
log::trace!("Creating Command for binary {:?}", binary_name);
|
||||||
|
|
||||||
let full_path = match which::which(binary_name) {
|
let full_path = match which::which(binary_name) {
|
||||||
Ok(full_path) => {
|
Ok(full_path) => {
|
||||||
|
@ -85,23 +85,26 @@ pub fn display_command<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a command and return the output on stdout and stderr if successful
|
/// Execute a command and return the output on stdout and stderr if successful
|
||||||
#[cfg(not(test))]
|
|
||||||
pub fn exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
pub fn exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||||
cmd: T,
|
cmd: T,
|
||||||
args: &[U],
|
args: &[U],
|
||||||
time_limit: Duration,
|
time_limit: Duration,
|
||||||
) -> Option<CommandOutput> {
|
) -> Option<CommandOutput> {
|
||||||
|
log::trace!("Executing command {:?} with args {:?}", cmd, args);
|
||||||
|
#[cfg(test)]
|
||||||
|
if let Some(o) = mock_cmd(&cmd, args) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
internal_exec_cmd(cmd, args, time_limit)
|
internal_exec_cmd(cmd, args, time_limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
pub fn mock_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||||
cmd: T,
|
cmd: T,
|
||||||
args: &[U],
|
args: &[U],
|
||||||
time_limit: Duration,
|
) -> Option<Option<CommandOutput>> {
|
||||||
) -> Option<CommandOutput> {
|
|
||||||
let command = display_command(&cmd, args);
|
let command = display_command(&cmd, args);
|
||||||
match command.as_str() {
|
let out = match command.as_str() {
|
||||||
"cobc -version" => Some(CommandOutput {
|
"cobc -version" => Some(CommandOutput {
|
||||||
stdout: String::from("\
|
stdout: String::from("\
|
||||||
cobc (GnuCOBOL) 3.1.2.0
|
cobc (GnuCOBOL) 3.1.2.0
|
||||||
|
@ -313,9 +316,9 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake).\n",
|
||||||
stdout: String::from("22.1.3\n"),
|
stdout: String::from("22.1.3\n"),
|
||||||
stderr: String::default(),
|
stderr: String::default(),
|
||||||
}),
|
}),
|
||||||
// If we don't have a mocked command fall back to executing the command
|
_ => return None,
|
||||||
_ => internal_exec_cmd(&cmd, args, time_limit),
|
};
|
||||||
}
|
Some(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps ANSI color escape sequences in the shell-appropriate wrappers.
|
/// Wraps ANSI color escape sequences in the shell-appropriate wrappers.
|
||||||
|
@ -376,36 +379,20 @@ fn internal_exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||||
args: &[U],
|
args: &[U],
|
||||||
time_limit: Duration,
|
time_limit: Duration,
|
||||||
) -> Option<CommandOutput> {
|
) -> Option<CommandOutput> {
|
||||||
log::trace!("Executing command {:?} with args {:?}", cmd, args);
|
let mut cmd = create_command(cmd).ok()?;
|
||||||
|
cmd.args(args);
|
||||||
let full_path = match which::which(&cmd) {
|
exec_timeout(&mut cmd, time_limit)
|
||||||
Ok(full_path) => {
|
}
|
||||||
log::trace!("Using {:?} as {:?}", full_path, cmd);
|
|
||||||
full_path
|
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
log::trace!("Unable to find {:?} in PATH, {:?}", cmd, error);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
pub fn exec_timeout(cmd: &mut Command, time_limit: Duration) -> Option<CommandOutput> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
let process = match cmd.spawn() {
|
||||||
#[allow(clippy::disallowed_method)]
|
|
||||||
let process = match Command::new(full_path)
|
|
||||||
.args(args)
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stdin(Stdio::null())
|
|
||||||
.spawn()
|
|
||||||
{
|
|
||||||
Ok(process) => process,
|
Ok(process) => process,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::info!("Unable to run {:?}, {:?}", cmd, error);
|
log::info!("Unable to run {:?}, {:?}", cmd.get_program(), error);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match process.with_output_timeout(time_limit).terminating().wait() {
|
match process.with_output_timeout(time_limit).terminating().wait() {
|
||||||
Ok(Some(output)) => {
|
Ok(Some(output)) => {
|
||||||
let stdout_string = match String::from_utf8(output.stdout) {
|
let stdout_string = match String::from_utf8(output.stdout) {
|
||||||
|
@ -441,12 +428,16 @@ fn internal_exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
log::warn!("Executing command {:?} timed out.", cmd);
|
log::warn!("Executing command {:?} timed out.", cmd.get_program());
|
||||||
log::warn!("You can set command_timeout in your config to a higher value to allow longer-running commands to keep executing.");
|
log::warn!("You can set command_timeout in your config to a higher value to allow longer-running commands to keep executing.");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::info!("Executing command {:?} failed by: {:?}", cmd, error);
|
log::info!(
|
||||||
|
"Executing command {:?} failed by: {:?}",
|
||||||
|
cmd.get_program(),
|
||||||
|
error
|
||||||
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue