mirror of
https://github.com/nushell/nushell.git
synced 2025-05-29 22:29:06 +02:00
Merge branch 'errors' into direnv-rewrite
This commit is contained in:
commit
b0db689065
@ -1,6 +1,8 @@
|
|||||||
use crate::commands::{self, autoenv::Trusted};
|
use crate::commands::{self, autoenv::Trusted};
|
||||||
use commands::autoenv;
|
use commands::autoenv;
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_source::Span;
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map::DefaultHasher,
|
collections::hash_map::DefaultHasher,
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
@ -32,36 +34,42 @@ impl DirectorySpecificEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toml_if_directory_is_trusted(&self, mut wdirenv: PathBuf) -> std::io::Result<toml::Value> {
|
fn toml_if_directory_is_trusted(
|
||||||
|
&self,
|
||||||
|
wdirenv: PathBuf,
|
||||||
|
) -> Result<toml::Value, ShellError> {
|
||||||
if let Some(trusted) = &self.trusted {
|
if let Some(trusted) = &self.trusted {
|
||||||
wdirenv.push(".nu-env");
|
let content = std::fs::read_to_string(&wdirenv)?;
|
||||||
if wdirenv.exists() {
|
let mut hasher = DefaultHasher::new();
|
||||||
let content = std::fs::read_to_string(&wdirenv)?;
|
content.hash(&mut hasher);
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
content.hash(&mut hasher);
|
if trusted.files.get(wdirenv.to_str().unwrap()) == Some(&hasher.finish().to_string()) {
|
||||||
if trusted.files.get(wdirenv.to_str().unwrap())
|
return Ok(content.parse::<toml::Value>().or_else(|_| {
|
||||||
== Some(&hasher.finish().to_string())
|
Err(ShellError::untagged_runtime_error(
|
||||||
{
|
"Could not parse .nu-env file. Is it well-formed?",
|
||||||
return Ok(content.parse::<toml::Value>()?);
|
))
|
||||||
}
|
})?);
|
||||||
}
|
}
|
||||||
|
return Err(ShellError::untagged_runtime_error("Found untrusted .nu-env file in this directory. Run 'autoenv trust' and restart nushell to allow it. This needs to be done after each change to the file."));
|
||||||
}
|
}
|
||||||
Err(Error::new(ErrorKind::Other, "No trusted directories"))
|
Err(ShellError::untagged_runtime_error("No trusted directories"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn env_vars_to_add(&mut self) -> std::io::Result<IndexMap<EnvKey, EnvVal>> {
|
pub fn env_vars_to_add(&mut self) -> Result<IndexMap<EnvKey, EnvVal>, ShellError> {
|
||||||
let current_dir = std::env::current_dir()?;
|
let current_dir = std::env::current_dir()?;
|
||||||
let mut working_dir = Some(current_dir.as_path());
|
let mut working_dir = Some(current_dir.as_path());
|
||||||
let mut vars_to_add = IndexMap::new();
|
let mut vars_to_add = IndexMap::new();
|
||||||
|
|
||||||
//Start in the current directory, then traverse towards the root with working_dir to see if we are in a subdirectory of a valid directory.
|
//Start in the current directory, then traverse towards the root with working_dir to see if we are in a subdirectory of a valid directory.
|
||||||
while let Some(wdir) = working_dir {
|
while let Some(wdir) = working_dir {
|
||||||
if let Ok(toml_doc) = self.toml_if_directory_is_trusted(wdir.to_path_buf()) {
|
let wdirenv = wdir.join(".nu-env");
|
||||||
|
if wdirenv.exists() {
|
||||||
|
let toml_doc = self.toml_if_directory_is_trusted(wdirenv)?;
|
||||||
toml_doc
|
toml_doc
|
||||||
.get("env")
|
.get("env")
|
||||||
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section missing"))?
|
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section missing in .nu-env"))?
|
||||||
.as_table()
|
.as_table()
|
||||||
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))?
|
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "malformed env section in .nu-env"))?
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|(dir_env_key, dir_env_val)| {
|
.for_each(|(dir_env_key, dir_env_val)| {
|
||||||
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap().into();
|
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap().into();
|
||||||
@ -88,7 +96,7 @@ impl DirectorySpecificEnvironment {
|
|||||||
|
|
||||||
//If the user has left directories which added env vars through .nu, we clear those vars
|
//If the user has left directories which added env vars through .nu, we clear those vars
|
||||||
//once they are marked for deletion, remove them from added_env_vars
|
//once they are marked for deletion, remove them from added_env_vars
|
||||||
pub fn env_vars_to_delete(&mut self) -> std::io::Result<IndexSet<EnvKey>> {
|
pub fn env_vars_to_delete(&mut self) -> Result<IndexSet<EnvKey>, ShellError> {
|
||||||
let current_dir = std::env::current_dir()?;
|
let current_dir = std::env::current_dir()?;
|
||||||
let mut working_dir = Some(current_dir.as_path());
|
let mut working_dir = Some(current_dir.as_path());
|
||||||
|
|
||||||
|
3
crates/nu-cli/src/env/environment.rs
vendored
3
crates/nu-cli/src/env/environment.rs
vendored
@ -4,6 +4,7 @@ use indexmap::{indexmap, IndexSet};
|
|||||||
use nu_protocol::{UntaggedValue, Value};
|
use nu_protocol::{UntaggedValue, Value};
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
|
||||||
pub trait Env: Debug + Send {
|
pub trait Env: Debug + Send {
|
||||||
fn env(&self) -> Option<Value>;
|
fn env(&self) -> Option<Value>;
|
||||||
@ -57,7 +58,7 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maintain_directory_environment(&mut self) -> std::io::Result<()> {
|
pub fn maintain_directory_environment(&mut self) -> Result<(), ShellError> {
|
||||||
self.direnv.env_vars_to_delete()?.iter().for_each(|k| {
|
self.direnv.env_vars_to_delete()?.iter().for_each(|k| {
|
||||||
self.remove_env(&k);
|
self.remove_env(&k);
|
||||||
});
|
});
|
||||||
|
6
crates/nu-cli/src/env/environment_syncer.rs
vendored
6
crates/nu-cli/src/env/environment_syncer.rs
vendored
@ -3,6 +3,8 @@ use crate::data::config::{Conf, NuConfig};
|
|||||||
use crate::env::environment::{Env, Environment};
|
use crate::env::environment::{Env, Environment};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_source::Text;
|
||||||
|
|
||||||
pub struct EnvironmentSyncer {
|
pub struct EnvironmentSyncer {
|
||||||
pub env: Arc<Mutex<Box<Environment>>>,
|
pub env: Arc<Mutex<Box<Environment>>>,
|
||||||
@ -44,7 +46,9 @@ impl EnvironmentSyncer {
|
|||||||
pub fn sync_env_vars(&mut self, ctx: &mut Context) {
|
pub fn sync_env_vars(&mut self, ctx: &mut Context) {
|
||||||
let mut environment = self.env.lock();
|
let mut environment = self.env.lock();
|
||||||
|
|
||||||
environment.maintain_directory_environment().ok();
|
if let Err(e) = environment.maintain_directory_environment() {
|
||||||
|
crate::cli::print_err(e, &Text::from(""));
|
||||||
|
}
|
||||||
if environment.env().is_some() {
|
if environment.env().is_some() {
|
||||||
for (name, value) in ctx.with_host(|host| host.vars()) {
|
for (name, value) in ctx.with_host(|host| host.vars()) {
|
||||||
if name != "path" && name != "PATH" {
|
if name != "path" && name != "PATH" {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user