From 6a0b4d112255322c86f35fac406565c58f7b1272 Mon Sep 17 00:00:00 2001 From: Sam Hedin Date: Mon, 15 Jun 2020 16:24:29 +0200 Subject: [PATCH] Add type aliases for String and OsString --- .../src/env/directory_specific_environment.rs | 45 ++++++++++++------- crates/nu-cli/src/env/environment.rs | 27 +++++++---- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/crates/nu-cli/src/env/directory_specific_environment.rs b/crates/nu-cli/src/env/directory_specific_environment.rs index b11bca1841..a0e677cc0d 100644 --- a/crates/nu-cli/src/env/directory_specific_environment.rs +++ b/crates/nu-cli/src/env/directory_specific_environment.rs @@ -1,21 +1,25 @@ use indexmap::{IndexMap, IndexSet}; use nu_protocol::{Primitive, UntaggedValue, Value}; +use std::io::Write; use std::{ ffi::OsString, fmt::Debug, + fs::OpenOptions, io::{Error, ErrorKind, Result}, path::PathBuf, }; +type EnvKey = String; +type EnvVal = OsString; #[derive(Debug, Default)] pub struct DirectorySpecificEnvironment { allowed_directories: IndexSet, //Directory -> Env key. If an environment var has been added from a .nu in a directory, we track it here so we can remove it when the user leaves the directory. - added_env_vars: IndexMap>, + added_env_vars: IndexMap>, //Directory -> (env_key, value). If a .nu overwrites some existing environment variables, they are added here so that they can be restored later. - overwritten_env_vars: IndexMap>, + overwritten_env_vars: IndexMap>, } impl DirectorySpecificEnvironment { @@ -50,7 +54,7 @@ impl DirectorySpecificEnvironment { } //If we are no longer in a directory, we restore the values it overwrote. - pub fn overwritten_values_to_restore(&mut self) -> Result> { + pub fn overwritten_values_to_restore(&mut self) -> Result> { let current_dir = std::env::current_dir()?; let mut working_dir = Some(current_dir.as_path()); @@ -69,7 +73,7 @@ impl DirectorySpecificEnvironment { for (dir, keyvals) in &self.overwritten_env_vars { if !new_overwritten_env_values.contains_key(dir) { keyvals.iter().for_each(|(k, v)| { - keyvals_to_restore.insert(k.clone(), v.to_str().unwrap().to_string()); + keyvals_to_restore.insert(k.clone(), v.clone()); }); } } @@ -78,7 +82,7 @@ impl DirectorySpecificEnvironment { Ok(keyvals_to_restore) } - pub fn env_vars_to_add(&mut self) -> Result> { + pub fn env_vars_to_add(&mut self) -> Result> { let current_dir = std::env::current_dir()?; let mut working_dir = Some(current_dir.as_path()); @@ -97,22 +101,29 @@ impl DirectorySpecificEnvironment { .as_table() .ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))? .iter() - .for_each(|(k, v)| { - if !vars_to_add.contains_key(k) { - vars_to_add.insert(k.clone(), v.as_str().unwrap().to_string()); + .for_each(|(env_key, directory_env_val)| { + if !vars_to_add.contains_key(env_key) { + let directory_env_val: EnvVal = + directory_env_val.as_str().unwrap().into(); //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) { - self.overwritten_env_vars - .entry(wdir.to_path_buf()) - .or_insert(IndexMap::new()) - .insert(k.clone(), val); + if let Some(existing_val) = std::env::var_os(env_key) { + if existing_val != directory_env_val { + self.overwritten_env_vars + .entry(wdir.to_path_buf()) + .or_insert(IndexMap::new()) + .insert(env_key.clone(), existing_val); + + vars_to_add.insert(env_key.clone(), directory_env_val); + } } else { //Otherwise, we just track that we added it here self.added_env_vars .entry(wdir.to_path_buf()) .or_insert(vec![]) - .push(k.clone()); + .push(env_key.clone()); + + vars_to_add.insert(env_key.clone(), directory_env_val); } } }); @@ -127,9 +138,8 @@ impl DirectorySpecificEnvironment { //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 - pub fn env_vars_to_delete(&mut self) -> Result> { + pub fn env_vars_to_delete(&mut self) -> Result> { let current_dir = std::env::current_dir()?; - let mut new_added_env_vars = IndexMap::new(); let mut working_dir = Some(current_dir.as_path()); @@ -143,7 +153,7 @@ impl DirectorySpecificEnvironment { .parent(); } - //Gather up all environment variables that should be deleted. + // Gather up all environment variables that should be deleted. let mut vars_to_delete = vec![]; for (dir, added_keys) in &self.added_env_vars { if !new_added_env_vars.contains_key(dir) { @@ -151,6 +161,7 @@ impl DirectorySpecificEnvironment { } } self.added_env_vars = new_added_env_vars; + Ok(vars_to_delete) } } diff --git a/crates/nu-cli/src/env/environment.rs b/crates/nu-cli/src/env/environment.rs index 86b6b82d13..e7a60368e9 100644 --- a/crates/nu-cli/src/env/environment.rs +++ b/crates/nu-cli/src/env/environment.rs @@ -1,9 +1,10 @@ use crate::data::config::Conf; +use std::io::Write; use crate::env::directory_specific_environment::*; use indexmap::{indexmap, IndexSet}; use nu_protocol::{UntaggedValue, Value}; use std::ffi::OsString; -use std::fmt::Debug; +use std::{fs::OpenOptions, fmt::Debug}; pub trait Env: Debug + Send { fn env(&self) -> Option; @@ -63,15 +64,15 @@ impl Environment { self.remove_env(&k); }); - self.direnv - .overwritten_values_to_restore()? - .iter() - .for_each(|(k, v)| { - self.add_env(&k, &v, true); - }); + // self.direnv + // .overwritten_values_to_restore()? + // .iter() + // .for_each(|(k, v)| { + // self.add_env(&k, &v.to_string_lossy(), true); + // }); self.direnv.env_vars_to_add()?.iter().for_each(|(k, v)| { - self.add_env(&k, &v, true); + self.add_env(&k, &v.to_string_lossy(), true); }); Ok(()) @@ -83,7 +84,17 @@ impl Environment { tag: _, }) = self.environment_vars { + + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open("delete.txt") + .unwrap(); + + write!(&mut file, "deleting: {:?}\n", key).unwrap(); envs.entries.remove(key); + std::env::remove_var(key); }; }