rewrite everything

This commit is contained in:
Sam Hedin 2020-06-10 08:33:04 +02:00
parent 2fcde8daa9
commit 862ff60b3e
2 changed files with 38 additions and 67 deletions

View File

@ -1,7 +1,8 @@
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use nu_protocol::{Primitive, UntaggedValue, Value}; use nu_protocol::{Primitive, UntaggedValue, Value};
use std::io::Write;
use std::io::{Error, ErrorKind, Result}; use std::io::{Error, ErrorKind, Result};
use std::{ffi::OsString, fmt::Debug, path::PathBuf}; use std::{ffi::OsString, fmt::Debug, fs::OpenOptions, path::PathBuf};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct DirectorySpecificEnvironment { pub struct DirectorySpecificEnvironment {
@ -48,45 +49,23 @@ impl DirectorySpecificEnvironment {
//If we are no longer in a directory, we restore the values it overwrote. //If we are no longer in a directory, we restore the values it overwrote.
pub fn overwritten_values_to_restore(&mut self) -> Result<IndexMap<String, String>> { pub fn overwritten_values_to_restore(&mut self) -> Result<IndexMap<String, String>> {
let current_dir = std::env::current_dir()?; let current_dir = std::env::current_dir()?;
let working_dir = Some(current_dir.as_path());
let mut keyvals_to_restore = IndexMap::new(); let keyvals_to_restore = self
let mut new_overwritten = IndexMap::new(); .overwritten_env_values
.iter()
for (directory, keyvals) in &self.overwritten_env_values { .filter_map(|(directory, keyvals)| {
let mut working_dir = Some(current_dir.as_path()); while let Some(wdir) = working_dir {
if &wdir == directory {
let mut re_add_keyvals = true; return false;
while let Some(wdir) = working_dir { } else {
if wdir == directory.as_path() { working_dir = working_dir.expect("This directory has no parent").parent();
re_add_keyvals = false; }
new_overwritten.insert(directory.clone(), keyvals.clone());
break;
} else {
working_dir = working_dir //Keep going up in the directory structure with .parent()
.ok_or_else(|| {
Error::new(ErrorKind::NotFound, "Root directory has no parent")
})?
.parent();
} }
} true
if re_add_keyvals { })
for (k, v) in keyvals { .collect();
keyvals_to_restore.insert(
k.clone(),
v.to_str()
.ok_or_else(|| {
Error::new(
ErrorKind::Other,
format!("{:?} is not valid unicode", v),
)
})?
.to_string(),
);
}
}
}
self.overwritten_env_values = new_overwritten;
Ok(keyvals_to_restore) Ok(keyvals_to_restore)
} }
@ -94,25 +73,21 @@ impl DirectorySpecificEnvironment {
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 empty = toml::value::Table::new();
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 self.allowed_directories.contains(wdir) { if self.allowed_directories.contains(wdir) {
let toml_doc = std::fs::read_to_string(wdir.join(".nu").as_path()) let toml_doc = std::fs::read_to_string(wdir.join(".nu").as_path())
.unwrap_or_else(|_| "[env]".to_string()) .unwrap_or_else(|_| r#"[env]"#.to_string())
.parse::<toml::Value>()?; .parse::<toml::Value>()?;
toml_doc toml_doc
.get("env") .get("env")
.expect("No env section in file") .unwrap()
.as_table() .as_table()
.ok_or_else(|| { .unwrap_or_else(|| &empty)
Error::new(
ErrorKind::InvalidData,
"Malformed [env] section in .nu-file",
)
})?
.iter() .iter()
.for_each(|(k, v)| { .for_each(|(k, v)| {
if !vars_to_add.contains_key(k) { if !vars_to_add.contains_key(k) {
@ -120,27 +95,22 @@ impl DirectorySpecificEnvironment {
//If we are about to overwrite any environment variables, we save them first so they can be restored later. //If we are about to overwrite any environment variables, we save them first so they can be restored later.
if let Some(val) = std::env::var_os(k) { if let Some(val) = std::env::var_os(k) {
let entry = self self.overwritten_env_values
.overwritten_env_values
.entry(wdir.to_path_buf()) .entry(wdir.to_path_buf())
.or_insert(vec![]); .or_insert(vec![])
entry.push((k.clone(), val)); .push((k.clone(), val));
} else {
self.added_env_vars
.entry(wdir.to_path_buf())
.or_insert(vec![])
.push(k.clone());
} }
let entry = self
.added_env_vars
.entry(wdir.to_path_buf())
.or_insert(vec![]);
entry.push(k.clone());
} }
}); });
} }
working_dir = working_dir = working_dir //Keep going up in the directory structure with .parent()
working_dir //Keep going up in the directory structure with .parent() .expect("This directory has no parent")
.ok_or_else(|| { .parent();
Error::new(ErrorKind::NotFound, "Root directory has no parent")
})?
.parent();
} }
Ok(vars_to_add) Ok(vars_to_add)

View File

@ -59,12 +59,9 @@ impl Environment {
} }
pub fn maintain_directory_environment(&mut self) -> std::io::Result<()> { pub fn maintain_directory_environment(&mut self) -> std::io::Result<()> {
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);
}); // });
self.direnv.env_vars_to_add()?.iter().for_each(|(k, v)| {
self.add_env(&k, &v, true);
});
self.direnv self.direnv
.overwritten_values_to_restore()? .overwritten_values_to_restore()?
@ -73,6 +70,10 @@ impl Environment {
self.add_env(&k, &v, true); self.add_env(&k, &v, true);
}); });
self.direnv.env_vars_to_add()?.iter().for_each(|(k, v)| {
self.add_env(&k, &v, true);
});
Ok(()) Ok(())
} }