Add type aliases for String and OsString

This commit is contained in:
Sam Hedin 2020-06-15 16:24:29 +02:00
parent 26ec9cf432
commit 6a0b4d1122
2 changed files with 47 additions and 25 deletions

View File

@ -1,21 +1,25 @@
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::{ use std::{
ffi::OsString, ffi::OsString,
fmt::Debug, fmt::Debug,
fs::OpenOptions,
io::{Error, ErrorKind, Result}, io::{Error, ErrorKind, Result},
path::PathBuf, path::PathBuf,
}; };
type EnvKey = String;
type EnvVal = OsString;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct DirectorySpecificEnvironment { pub struct DirectorySpecificEnvironment {
allowed_directories: IndexSet<PathBuf>, allowed_directories: IndexSet<PathBuf>,
//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. //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<PathBuf, Vec<String>>, added_env_vars: IndexMap<PathBuf, Vec<EnvKey>>,
//Directory -> (env_key, value). If a .nu overwrites some existing environment variables, they are added here so that they can be restored later. //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<PathBuf, IndexMap<String, OsString>>, overwritten_env_vars: IndexMap<PathBuf, IndexMap<EnvKey, EnvVal>>,
} }
impl DirectorySpecificEnvironment { impl DirectorySpecificEnvironment {
@ -50,7 +54,7 @@ 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<EnvKey, EnvVal>> {
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());
@ -69,7 +73,7 @@ impl DirectorySpecificEnvironment {
for (dir, keyvals) in &self.overwritten_env_vars { for (dir, keyvals) in &self.overwritten_env_vars {
if !new_overwritten_env_values.contains_key(dir) { if !new_overwritten_env_values.contains_key(dir) {
keyvals.iter().for_each(|(k, v)| { 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) Ok(keyvals_to_restore)
} }
pub fn env_vars_to_add(&mut self) -> Result<IndexMap<String, String>> { pub fn env_vars_to_add(&mut self) -> Result<IndexMap<EnvKey, EnvVal>> {
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());
@ -97,22 +101,29 @@ impl DirectorySpecificEnvironment {
.as_table() .as_table()
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))? .ok_or_else(|| Error::new(ErrorKind::InvalidData, "env section malformed"))?
.iter() .iter()
.for_each(|(k, v)| { .for_each(|(env_key, directory_env_val)| {
if !vars_to_add.contains_key(k) { if !vars_to_add.contains_key(env_key) {
vars_to_add.insert(k.clone(), v.as_str().unwrap().to_string()); 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 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(existing_val) = std::env::var_os(env_key) {
if existing_val != directory_env_val {
self.overwritten_env_vars self.overwritten_env_vars
.entry(wdir.to_path_buf()) .entry(wdir.to_path_buf())
.or_insert(IndexMap::new()) .or_insert(IndexMap::new())
.insert(k.clone(), val); .insert(env_key.clone(), existing_val);
vars_to_add.insert(env_key.clone(), directory_env_val);
}
} else { } else {
//Otherwise, we just track that we added it here //Otherwise, we just track that we added it here
self.added_env_vars self.added_env_vars
.entry(wdir.to_path_buf()) .entry(wdir.to_path_buf())
.or_insert(vec![]) .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 //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) -> Result<Vec<String>> { pub fn env_vars_to_delete(&mut self) -> Result<Vec<EnvKey>> {
let current_dir = std::env::current_dir()?; let current_dir = std::env::current_dir()?;
let mut new_added_env_vars = IndexMap::new(); let mut new_added_env_vars = IndexMap::new();
let mut working_dir = Some(current_dir.as_path()); let mut working_dir = Some(current_dir.as_path());
@ -151,6 +161,7 @@ impl DirectorySpecificEnvironment {
} }
} }
self.added_env_vars = new_added_env_vars; self.added_env_vars = new_added_env_vars;
Ok(vars_to_delete) Ok(vars_to_delete)
} }
} }

View File

@ -1,9 +1,10 @@
use crate::data::config::Conf; use crate::data::config::Conf;
use std::io::Write;
use crate::env::directory_specific_environment::*; use crate::env::directory_specific_environment::*;
use indexmap::{indexmap, IndexSet}; 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::{fs::OpenOptions, fmt::Debug};
pub trait Env: Debug + Send { pub trait Env: Debug + Send {
fn env(&self) -> Option<Value>; fn env(&self) -> Option<Value>;
@ -63,15 +64,15 @@ impl Environment {
self.remove_env(&k); self.remove_env(&k);
}); });
self.direnv // self.direnv
.overwritten_values_to_restore()? // .overwritten_values_to_restore()?
.iter() // .iter()
.for_each(|(k, v)| { // .for_each(|(k, v)| {
self.add_env(&k, &v, true); // self.add_env(&k, &v.to_string_lossy(), true);
}); // });
self.direnv.env_vars_to_add()?.iter().for_each(|(k, v)| { 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(()) Ok(())
@ -83,7 +84,17 @@ impl Environment {
tag: _, tag: _,
}) = self.environment_vars }) = 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); envs.entries.remove(key);
std::env::remove_var(key);
}; };
} }