This commit is contained in:
Sam Hedin 2020-06-23 18:37:50 +02:00
parent 3d213a63c5
commit 595b188855
3 changed files with 68 additions and 42 deletions

View File

@ -238,7 +238,7 @@ pub fn create_default_context(
syncer.load_environment(); syncer.load_environment();
let mut context = Context::basic()?; let mut context = Context::basic()?;
syncer.sync_env_vars(&mut context)?; syncer.sync_env_vars(&mut context);
syncer.sync_path_vars(&mut context); syncer.sync_path_vars(&mut context);
{ {
@ -677,7 +677,7 @@ pub async fn cli(
// TODO: make sure config is cached so we don't path this load every call // TODO: make sure config is cached so we don't path this load every call
// FIXME: we probably want to be a bit more graceful if we can't set the environment // FIXME: we probably want to be a bit more graceful if we can't set the environment
syncer.reload(); syncer.reload();
syncer.sync_env_vars(&mut context)?; syncer.sync_env_vars(&mut context);
syncer.sync_path_vars(&mut context); syncer.sync_path_vars(&mut context);
match line { match line {

View File

@ -2,6 +2,7 @@ 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_errors::ShellError;
use nu_source::Span;
use std::{ use std::{
collections::hash_map::DefaultHasher, collections::hash_map::DefaultHasher,
ffi::OsString, ffi::OsString,
@ -33,30 +34,51 @@ impl DirectorySpecificEnvironment {
} }
} }
// fn toml_if_directory_is_trusted(
// &self,
// mut wdirenv: PathBuf,
// ) -> Result<toml::Value, ShellError> {
// if let Some(trusted) = &self.trusted {
// wdirenv.push(".nu-env");
// if wdirenv.exists() {
// let content = std::fs::read_to_string(&wdirenv)?;
// let mut hasher = DefaultHasher::new();
// content.hash(&mut hasher);
// if trusted.files.get(wdirenv.to_str().unwrap())
// == Some(&hasher.finish().to_string())
// {
// return Ok(content.parse::<toml::Value>().or_else(|_| {
// Err(ShellError::unexpected_eof(
// "Could not parse .nu-env file. Is it well-formed?",
// Span::default(),
// ))
// })?);
// } else {
// return Err(ShellError::unexpected_eof("Found .nu-env file in this directory, but it is not trusted. You can run 'autoenv trust' to allow it. This needs to be done after each change to the file",
// Span::default()));
// }
// }
// }
// Err(ShellError::unexpected_eof("No trusted directories", Span::default()))
// }
fn toml_if_directory_is_trusted( fn toml_if_directory_is_trusted(
&self, &self,
mut wdirenv: PathBuf, wdirenv: PathBuf,
) -> Result<toml::Value, ShellError> { ) -> 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>().or_else(|_| { ))
Err( })?);
ShellError::untagged_runtime_error(
"Could not parse .nu-env file. Is it well-formed?",
),
)
})?);
} else {
return Err(ShellError::untagged_runtime_error("Found .nu-env file in this directory, but it is not trusted. You can run 'autoenv trust' to allow it. This needs to be done after each change to the file"));
}
} }
return Err(ShellError::untagged_runtime_error("Found .nu-env file in this directory, but it is not trusted. You can run 'autoenv trust' to allow it. This needs to be done after each change to the file"));
} }
Err(ShellError::untagged_runtime_error("No trusted directories")) Err(ShellError::untagged_runtime_error("No trusted directories"))
} }
@ -68,26 +90,29 @@ impl DirectorySpecificEnvironment {
//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 {
let toml_doc = self.toml_if_directory_is_trusted(wdir.to_path_buf())?; let wdirenv = wdir.join(".nu-env");
toml_doc if wdirenv.exists() {
.get("env") let toml_doc = self.toml_if_directory_is_trusted(wdirenv)?;
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section missing"))? toml_doc
.as_table() .get("env")
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))? .ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section missing"))?
.iter() .as_table()
.for_each(|(dir_env_key, dir_env_val)| { .ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))?
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap().into(); .iter()
.for_each(|(dir_env_key, dir_env_val)| {
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap().into();
//This condition is to make sure variables in parent directories don't overwrite variables set by subdirectories. //This condition is to make sure variables in parent directories don't overwrite variables set by subdirectories.
if !vars_to_add.contains_key(dir_env_key) { if !vars_to_add.contains_key(dir_env_key) {
vars_to_add.insert(dir_env_key.clone(), dir_env_val); vars_to_add.insert(dir_env_key.clone(), dir_env_val);
self.added_env_vars self.added_env_vars
.entry(wdir.to_path_buf()) .entry(wdir.to_path_buf())
.or_insert(IndexSet::new()) .or_insert(IndexSet::new())
.insert(dir_env_key.clone()); .insert(dir_env_key.clone());
} }
}); });
}
working_dir = working_dir //Keep going up in the directory structure with .parent() working_dir = working_dir //Keep going up in the directory structure with .parent()
.expect("This should not be None because of the while condition") .expect("This should not be None because of the while condition")

View File

@ -42,10 +42,12 @@ impl EnvironmentSyncer {
environment.morph(&*self.config); environment.morph(&*self.config);
} }
pub fn sync_env_vars(&mut self, ctx: &mut Context) -> Result<(), ShellError>{ 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() {
ctx.error(e);
}
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" {
@ -72,7 +74,6 @@ impl EnvironmentSyncer {
} }
} }
} }
Ok(())
} }
pub fn sync_path_vars(&mut self, ctx: &mut Context) { pub fn sync_path_vars(&mut self, ctx: &mut Context) {