From e231b85570bcb3fc838f950e9f5004c6a7c5a2ac Mon Sep 17 00:00:00 2001 From: Sam Hedin Date: Sat, 27 Jun 2020 16:58:24 +0200 Subject: [PATCH] Non-working --- crates/nu-cli/src/commands/autoenv.rs | 62 ++++++++++++++----- .../src/env/directory_specific_environment.rs | 9 +-- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/crates/nu-cli/src/commands/autoenv.rs b/crates/nu-cli/src/commands/autoenv.rs index bc91506ed4..57800c311f 100644 --- a/crates/nu-cli/src/commands/autoenv.rs +++ b/crates/nu-cli/src/commands/autoenv.rs @@ -4,9 +4,9 @@ use nu_errors::ShellError; use nu_protocol::{ReturnSuccess, Signature, UntaggedValue}; use serde::Deserialize; use serde::Serialize; +use sha2::{Digest, Sha256}; use std::io::Read; use std::path::PathBuf; - pub struct Autoenv; #[derive(Deserialize, Serialize, Debug, Default)] @@ -19,26 +19,54 @@ impl Trusted { files: IndexMap::new(), } } - pub fn read_trusted() -> Result { - let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?; - let mut file = std::fs::OpenOptions::new() - .read(true) - .create(true) - .write(true) - .open(config_path) - .or_else(|_| { - Err(ShellError::untagged_runtime_error( - "Couldn't open nu-env.toml", - )) - })?; - let mut doc = String::new(); - file.read_to_string(&mut doc)?; - - let allowed: Trusted = toml::from_str(doc.as_str()).unwrap_or_else(|_| Trusted::new()); + pub fn read_trusted() -> Result { + let allowed = Trusted { + files: read_config_file()?, + }; Ok(allowed) } + pub fn file_is_trusted_reload_config( + &mut self, + nu_env_file: &PathBuf, + content: &Vec, + ) -> Result { + let contentdigest = Sha256::digest(&content).as_slice().to_vec(); + let nufile = nu_env_file.to_str().unwrap_or(""); + + //If the existing hash for nu_env_file exists and corresponds to the hash of content, everything is fine. + if self.files.get(nufile) == Some(&contentdigest) { + return Ok(true); + } + //Otherwise, we re-read the hash from nu-env.toml and compare with that. If it is the same, we update the map. + //This allows the user to use autoenv trust without having to restart nushell afterwards + // let current_config = read_config_file()?; + // if current_config.get(nufile) == Some(&contentdigest) { + // self.files = current_config; + // return Ok(true); + // } + Ok(false) + } } + +fn read_config_file() -> Result>, ShellError> { + let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?; + + let mut file = std::fs::OpenOptions::new() + .read(true) + .create(true) + .write(true) + .open(config_path) + .or_else(|_| { + Err(ShellError::untagged_runtime_error( + "Couldn't open nu-env.toml", + )) + })?; + let mut doc = String::new(); + file.read_to_string(&mut doc)?; + Ok(toml::from_str(doc.as_str()).unwrap_or_else(|_| IndexMap::new())) +} + #[async_trait] impl WholeStreamCommand for Autoenv { fn name(&self) -> &str { diff --git a/crates/nu-cli/src/env/directory_specific_environment.rs b/crates/nu-cli/src/env/directory_specific_environment.rs index 23d59f0fac..7d32c5bc1d 100644 --- a/crates/nu-cli/src/env/directory_specific_environment.rs +++ b/crates/nu-cli/src/env/directory_specific_environment.rs @@ -36,12 +36,11 @@ impl DirectorySpecificEnvironment { } } - fn toml_if_directory_is_trusted(&self, nu_env_file: &PathBuf) -> Result { - if let Some(trusted) = &self.trusted { + fn toml_if_directory_is_trusted(&mut self, nu_env_file: &PathBuf) -> Result { + if let Some(trusted) = self.trusted.as_mut() { let content = std::fs::read(&nu_env_file)?; - if trusted.files.get(nu_env_file.to_str().unwrap_or("")) - == Some(&Sha256::digest(&content).as_slice().to_vec()) + if trusted.file_is_trusted_reload_config(&nu_env_file, &content)? { return Ok(std::str::from_utf8(&content.as_slice()).or_else(|_| { Err(ShellError::untagged_runtime_error(format!("Could not read {:?} as utf8 string", content))) @@ -66,8 +65,6 @@ impl DirectorySpecificEnvironment { //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 current dir is parent to last_seen_directory, current.cmp(last) returns less - //if current dir is the same as last_seen, current.cmp(last) returns equal while self.last_seen_directory.cmp(&working_dir) == std::cmp::Ordering::Less { //parent.cmp(child) = Less if nu_env_file.exists() { let toml_doc = self.toml_if_directory_is_trusted(&nu_env_file)?;