Display environment loading failures in the activity indicator (#18567)
As @maan2003 noted in #18473, we should warn the user if direnv call fails Release Notes: - Show a notice in the activity indicator if an error occurs while loading the shell environment
This commit is contained in:
parent
87cc208f9f
commit
910a773b89
4 changed files with 192 additions and 60 deletions
72
crates/project/src/direnv.rs
Normal file
72
crates/project/src/direnv.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use crate::environment::EnvironmentErrorMessage;
|
||||
use std::process::ExitStatus;
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
use {collections::HashMap, std::path::Path, util::ResultExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DirenvError {
|
||||
NotFound,
|
||||
FailedRun,
|
||||
NonZeroExit(ExitStatus, Vec<u8>),
|
||||
EmptyOutput,
|
||||
InvalidJson,
|
||||
}
|
||||
|
||||
impl From<DirenvError> for Option<EnvironmentErrorMessage> {
|
||||
fn from(value: DirenvError) -> Self {
|
||||
match value {
|
||||
DirenvError::NotFound => None,
|
||||
DirenvError::FailedRun | DirenvError::NonZeroExit(_, _) => {
|
||||
Some(EnvironmentErrorMessage(String::from(
|
||||
"Failed to run direnv. See logs for more info",
|
||||
)))
|
||||
}
|
||||
DirenvError::EmptyOutput => None,
|
||||
DirenvError::InvalidJson => Some(EnvironmentErrorMessage(String::from(
|
||||
"Direnv returned invalid json. See logs for more info",
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
pub async fn load_direnv_environment(dir: &Path) -> Result<HashMap<String, String>, DirenvError> {
|
||||
let Ok(direnv_path) = which::which("direnv") else {
|
||||
return Err(DirenvError::NotFound);
|
||||
};
|
||||
|
||||
let Some(direnv_output) = smol::process::Command::new(direnv_path)
|
||||
.args(["export", "json"])
|
||||
.env("TERM", "dumb")
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.await
|
||||
.log_err()
|
||||
else {
|
||||
return Err(DirenvError::FailedRun);
|
||||
};
|
||||
|
||||
if !direnv_output.status.success() {
|
||||
log::error!(
|
||||
"Loading direnv environment failed ({}), stderr: {}",
|
||||
direnv_output.status,
|
||||
String::from_utf8_lossy(&direnv_output.stderr)
|
||||
);
|
||||
return Err(DirenvError::NonZeroExit(
|
||||
direnv_output.status,
|
||||
direnv_output.stderr,
|
||||
));
|
||||
}
|
||||
|
||||
let output = String::from_utf8_lossy(&direnv_output.stdout);
|
||||
if output.is_empty() {
|
||||
return Err(DirenvError::EmptyOutput);
|
||||
}
|
||||
|
||||
let Some(env) = serde_json::from_str(&output).log_err() else {
|
||||
return Err(DirenvError::InvalidJson);
|
||||
};
|
||||
|
||||
Ok(env)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue