Start using autoenv

This commit is contained in:
Sam Hedin 2020-06-22 15:13:30 +02:00
parent e35c423796
commit 3a0ada6486
5 changed files with 52 additions and 65 deletions

View File

@ -4,19 +4,43 @@ use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
use serde::Deserialize;
use serde::Serialize;
use std::path::PathBuf;
use std::io::Read;
pub struct Autoenv;
#[derive(Deserialize, Serialize)]
pub struct Allowed {
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct Trusted {
pub files: IndexMap<String, String>,
}
impl Allowed {
impl Trusted {
pub fn new() -> Self {
Allowed {
Trusted {
files: IndexMap::new(),
}
}
pub fn read_trusted() -> Result<Self, ShellError> {
let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?;
let mut file = match std::fs::OpenOptions::new()
.read(true)
.create(true)
.write(true)
.open(config_path.clone())
{
Ok(p) => p,
Err(_) => {
return 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)
}
}
#[async_trait]
impl WholeStreamCommand for Autoenv {

View File

@ -1,12 +1,11 @@
use super::{autoenv::Allowed, cd::CdArgs};
use super::autoenv::Trusted;
use crate::commands::WholeStreamCommand;
use crate::{path, prelude::*};
use nu_errors::ShellError;
use nu_protocol::SyntaxShape;
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
use std::hash::{Hash, Hasher};
use std::io::Read;
use std::{collections::hash_map::DefaultHasher, fs, path::PathBuf};
use std::{fs, collections::hash_map::DefaultHasher, path::PathBuf};
pub struct AutoenvTrust;
#[async_trait]
@ -50,32 +49,13 @@ impl WholeStreamCommand for AutoenvTrust {
let mut hasher = DefaultHasher::new();
content.hash(&mut hasher);
let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?;
let mut file = match std::fs::OpenOptions::new()
.read(true)
.create(true)
.write(true)
.open(config_path.clone())
{
Ok(p) => p,
Err(_) => {
return Err(ShellError::untagged_runtime_error(
"Couldn't open nu-env.toml",
));
}
};
let mut doc = String::new();
file.read_to_string(&mut doc)?;
let mut allowed: Allowed = toml::from_str(doc.as_str()).unwrap_or_else(|_| Allowed::new());
let file_to_untrust = file_to_trust.to_string_lossy().to_string();
let file_to_trust = file_to_trust.to_string_lossy().to_string();
let mut allowed = Trusted::read_trusted()?;
allowed
.files
.insert(file_to_untrust, hasher.finish().to_string());
.insert(file_to_trust, hasher.finish().to_string());
let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?;
fs::write(config_path, toml::to_string(&allowed).unwrap())
.expect("Couldn't write to toml file");

View File

@ -3,9 +3,9 @@ use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::SyntaxShape;
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
use std::io::{Read, Write};
use std::io::Read;
use std::{fs, path::PathBuf};
use super::autoenv::Allowed;
use super::autoenv::Trusted;
pub struct AutoenvUnTrust;
@ -62,7 +62,7 @@ impl WholeStreamCommand for AutoenvUnTrust {
let mut doc = String::new();
file.read_to_string(&mut doc)?;
let mut allowed: Allowed = toml::from_str(doc.as_str()).unwrap_or_else(|_| Allowed::new());
let mut allowed: Trusted = toml::from_str(doc.as_str()).unwrap_or_else(|_| Trusted::new());
let file_to_untrust = file_to_untrust.to_string_lossy().to_string();

View File

@ -1,48 +1,31 @@
use indexmap::{IndexMap, IndexSet};
use nu_protocol::{Primitive, UntaggedValue, Value};
use std::{
ffi::OsString,
fmt::Debug,
io::{Error, ErrorKind, Result},
io::{Error, ErrorKind},
path::PathBuf,
};
use crate::commands::{autoenv::Trusted, self};
use commands::autoenv;
type EnvKey = String;
type EnvVal = OsString;
#[derive(Debug, Default)]
pub struct DirectorySpecificEnvironment {
allowed_directories: IndexSet<PathBuf>,
trusted: Option<Trusted>,
//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>>,
}
impl DirectorySpecificEnvironment {
pub fn new(allowed_directories: Option<Value>) -> DirectorySpecificEnvironment {
let allowed_directories = if let Some(Value {
value: UntaggedValue::Table(ref wrapped_directories),
tag: _,
}) = allowed_directories
{
wrapped_directories
.iter()
.filter_map(|dirval| {
if let Value {
value: UntaggedValue::Primitive(Primitive::String(ref dir)),
tag: _,
} = dirval
{
return Some(PathBuf::from(&dir));
}
None
})
.collect()
} else {
IndexSet::new()
pub fn new() -> DirectorySpecificEnvironment {
let trusted = match autoenv::Trusted::read_trusted() {
Ok(t) => Some(t),
Err(_) => None
};
DirectorySpecificEnvironment {
allowed_directories,
trusted,
added_env_vars: IndexMap::new(),
}
}
@ -54,7 +37,8 @@ impl DirectorySpecificEnvironment {
//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 self.allowed_directories.contains(wdir) {
// if self.allowed_directories.contains(wdir) {
if true {
let toml_doc = std::fs::read_to_string(wdir.join(".nu-env").as_path())?
.parse::<toml::Value>()?;
@ -89,7 +73,7 @@ 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<IndexSet<EnvKey>> {
pub fn env_vars_to_delete(&mut self) -> std::io::Result<IndexSet<EnvKey>> {
let current_dir = std::env::current_dir()?;
let mut working_dir = Some(current_dir.as_path());

View File

@ -43,18 +43,17 @@ impl Environment {
Environment {
environment_vars: None,
path_vars: None,
direnv: DirectorySpecificEnvironment::new(None),
direnv: DirectorySpecificEnvironment::new(),
}
}
pub fn from_config<T: Conf>(configuration: &T) -> Environment {
pub fn from_config<T: Conf>(configuration: &T) -> Environment {
let env = configuration.env();
let path = configuration.path();
Environment {
environment_vars: env,
path_vars: path,
direnv: DirectorySpecificEnvironment::new(configuration.nu_env_dirs()),
direnv: DirectorySpecificEnvironment::new(),
}
}