Only apply vars once

This commit is contained in:
Sam Hedin 2020-06-26 14:46:38 +02:00
parent a86438686e
commit 5dc5bb11aa

View File

@ -3,9 +3,11 @@ use commands::autoenv;
use indexmap::{IndexMap, IndexSet};
use nu_errors::ShellError;
use sha2::{Digest, Sha256};
use std::io::Write;
use std::{
ffi::OsString,
fmt::Debug,
fs::OpenOptions,
path::{Path, PathBuf},
};
@ -14,7 +16,7 @@ type EnvVal = OsString;
#[derive(Debug, Default)]
pub struct DirectorySpecificEnvironment {
trusted: Option<Trusted>,
last_seen_directory: 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.
added_env_vars: IndexMap<PathBuf, IndexSet<EnvKey>>,
}
@ -27,6 +29,7 @@ impl DirectorySpecificEnvironment {
};
DirectorySpecificEnvironment {
trusted,
last_seen_directory: PathBuf::from("/"),
added_env_vars: IndexMap::new(),
}
}
@ -54,13 +57,35 @@ impl DirectorySpecificEnvironment {
Err(ShellError::untagged_runtime_error("No trusted directories"))
}
fn is_parent_or_same(&self, parent: &PathBuf, child: &PathBuf) -> bool {
let mut child = Some(child.as_path());
while let Some(c) = child {
if c == parent {
return true;
}
child = child.expect("Can't be none").parent();
}
return false;
}
pub fn env_vars_to_add(&mut self) -> Result<IndexMap<EnvKey, EnvVal>, ShellError> {
let current_dir = std::env::current_dir()?;
let mut working_dir = Some(current_dir.as_path());
let mut vars_to_add = IndexMap::new();
//If we are in the last seen directory, do nothing
//If we are in a parent directory to last_seen_directory, just return without applying .nu-env in the parent directory - they were already applied earlier.
if self.is_parent_or_same(&current_dir, &self.last_seen_directory) {
return Ok(vars_to_add);
}
//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 {
//If we are in a subdirectory to last_seen_directory, we should apply all .nu-envs up until last_seen_directory
if wdir == self.last_seen_directory {
self.last_seen_directory = current_dir;
return Ok(vars_to_add);
}
let wdirenv = wdir.join(".nu-env");
if wdirenv.exists() {
let toml_doc = self.toml_if_directory_is_trusted(&wdirenv)?;
@ -99,6 +124,7 @@ impl DirectorySpecificEnvironment {
.parent();
}
self.last_seen_directory = current_dir;
Ok(vars_to_add)
}