mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 18:03:51 +01:00
parent
e231b85570
commit
804092e46a
@ -4,9 +4,9 @@ use nu_errors::ShellError;
|
|||||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct Autoenv;
|
pub struct Autoenv;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
@ -19,54 +19,26 @@ impl Trusted {
|
|||||||
files: IndexMap::new(),
|
files: IndexMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn read_trusted() -> Result<Self, ShellError> {
|
||||||
|
let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?;
|
||||||
|
|
||||||
pub fn read_trusted() -> Result<Trusted, ShellError> {
|
let mut file = std::fs::OpenOptions::new()
|
||||||
let allowed = Trusted {
|
.read(true)
|
||||||
files: read_config_file()?,
|
.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());
|
||||||
Ok(allowed)
|
Ok(allowed)
|
||||||
}
|
}
|
||||||
pub fn file_is_trusted_reload_config(
|
|
||||||
&mut self,
|
|
||||||
nu_env_file: &PathBuf,
|
|
||||||
content: &Vec<u8>,
|
|
||||||
) -> Result<bool, ShellError> {
|
|
||||||
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<IndexMap<String, Vec<u8>>, 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]
|
#[async_trait]
|
||||||
impl WholeStreamCommand for Autoenv {
|
impl WholeStreamCommand for Autoenv {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -36,11 +36,12 @@ impl DirectorySpecificEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toml_if_directory_is_trusted(&mut self, nu_env_file: &PathBuf) -> Result<toml::Value, ShellError> {
|
fn toml_if_directory_is_trusted(&self, nu_env_file: &PathBuf) -> Result<toml::Value, ShellError> {
|
||||||
if let Some(trusted) = self.trusted.as_mut() {
|
if let Some(trusted) = &self.trusted {
|
||||||
let content = std::fs::read(&nu_env_file)?;
|
let content = std::fs::read(&nu_env_file)?;
|
||||||
|
|
||||||
if trusted.file_is_trusted_reload_config(&nu_env_file, &content)?
|
if trusted.files.get(nu_env_file.to_str().unwrap_or(""))
|
||||||
|
== Some(&Sha256::digest(&content).as_slice().to_vec())
|
||||||
{
|
{
|
||||||
return Ok(std::str::from_utf8(&content.as_slice()).or_else(|_| {
|
return Ok(std::str::from_utf8(&content.as_slice()).or_else(|_| {
|
||||||
Err(ShellError::untagged_runtime_error(format!("Could not read {:?} as utf8 string", content)))
|
Err(ShellError::untagged_runtime_error(format!("Could not read {:?} as utf8 string", content)))
|
||||||
@ -65,6 +66,8 @@ impl DirectorySpecificEnvironment {
|
|||||||
|
|
||||||
//If we are in the last seen directory, do nothing
|
//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 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
|
while self.last_seen_directory.cmp(&working_dir) == std::cmp::Ordering::Less { //parent.cmp(child) = Less
|
||||||
if nu_env_file.exists() {
|
if nu_env_file.exists() {
|
||||||
let toml_doc = self.toml_if_directory_is_trusted(&nu_env_file)?;
|
let toml_doc = self.toml_if_directory_is_trusted(&nu_env_file)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user