mirror of
https://github.com/starship/starship.git
synced 2024-11-07 17:05:09 +01:00
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::configs::StarshipRootConfig;
|
||||
use crate::module::Module;
|
||||
use crate::utils::{exec_cmd, CommandOutput};
|
||||
use crate::utils::{create_command, exec_timeout, CommandOutput};
|
||||
|
||||
use crate::modules;
|
||||
use crate::utils::{self, home_dir};
|
||||
@ -316,16 +316,27 @@ impl<'a> Context<'a> {
|
||||
cmd: T,
|
||||
args: &[U],
|
||||
) -> Option<CommandOutput> {
|
||||
log::trace!(
|
||||
"Executing command {:?} with args {:?} from context",
|
||||
cmd,
|
||||
args
|
||||
);
|
||||
#[cfg(test)]
|
||||
{
|
||||
let command = crate::utils::display_command(&cmd, args);
|
||||
if let Some(output) = self.cmd.get(command.as_str()) {
|
||||
return output.clone();
|
||||
if let Some(output) = self
|
||||
.cmd
|
||||
.get(command.as_str())
|
||||
.cloned()
|
||||
.or_else(|| crate::utils::mock_cmd(&cmd, args))
|
||||
{
|
||||
return output;
|
||||
}
|
||||
}
|
||||
exec_cmd(
|
||||
&cmd,
|
||||
args,
|
||||
let mut cmd = create_command(cmd).ok()?;
|
||||
cmd.args(args).current_dir(&self.current_dir);
|
||||
exec_timeout(
|
||||
&mut cmd,
|
||||
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
|
||||
pub fn create_command<T: AsRef<OsStr>>(binary_name: T) -> Result<Command> {
|
||||
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) {
|
||||
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
|
||||
#[cfg(not(test))]
|
||||
pub fn exec_cmd<T: AsRef<OsStr> + Debug, U: AsRef<OsStr> + Debug>(
|
||||
cmd: T,
|
||||
args: &[U],
|
||||
time_limit: Duration,
|
||||
) -> 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)
|
||||
}
|
||||
|
||||
#[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,
|
||||
args: &[U],
|
||||
time_limit: Duration,
|
||||
) -> Option<CommandOutput> {
|
||||
) -> Option<Option<CommandOutput>> {
|
||||
let command = display_command(&cmd, args);
|
||||
match command.as_str() {
|
||||
let out = match command.as_str() {
|
||||
"cobc -version" => Some(CommandOutput {
|
||||
stdout: String::from("\
|
||||
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"),
|
||||
stderr: String::default(),
|
||||
}),
|
||||
// If we don't have a mocked command fall back to executing the command
|
||||
_ => internal_exec_cmd(&cmd, args, time_limit),
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(out)
|
||||
}
|
||||
|
||||
/// 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],
|
||||
time_limit: Duration,
|
||||
) -> Option<CommandOutput> {
|
||||
log::trace!("Executing command {:?} with args {:?}", cmd, args);
|
||||
|
||||
let full_path = match which::which(&cmd) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
let mut cmd = create_command(cmd).ok()?;
|
||||
cmd.args(args);
|
||||
exec_timeout(&mut cmd, time_limit)
|
||||
}
|
||||
|
||||
pub fn exec_timeout(cmd: &mut Command, time_limit: Duration) -> Option<CommandOutput> {
|
||||
let start = Instant::now();
|
||||
|
||||
#[allow(clippy::disallowed_method)]
|
||||
let process = match Command::new(full_path)
|
||||
.args(args)
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stdin(Stdio::null())
|
||||
.spawn()
|
||||
{
|
||||
let process = match cmd.spawn() {
|
||||
Ok(process) => process,
|
||||
Err(error) => {
|
||||
log::info!("Unable to run {:?}, {:?}", cmd, error);
|
||||
log::info!("Unable to run {:?}, {:?}", cmd.get_program(), error);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
match process.with_output_timeout(time_limit).terminating().wait() {
|
||||
Ok(Some(output)) => {
|
||||
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) => {
|
||||
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.");
|
||||
None
|
||||
}
|
||||
Err(error) => {
|
||||
log::info!("Executing command {:?} failed by: {:?}", cmd, error);
|
||||
log::info!(
|
||||
"Executing command {:?} failed by: {:?}",
|
||||
cmd.get_program(),
|
||||
error
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user