mirror of
https://github.com/nushell/nushell.git
synced 2025-06-01 07:35:49 +02:00
Adding works
This commit is contained in:
parent
0a402ac3a9
commit
1ae82f4ad4
@ -58,21 +58,20 @@ impl DirectorySpecificEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn env_vars_to_add(&mut self) -> Result<IndexMap<EnvKey, EnvVal>, ShellError> {
|
pub fn env_vars_to_add(&mut self) -> Result<IndexMap<EnvKey, EnvVal>, ShellError> {
|
||||||
let current_dir = std::env::current_dir()?;
|
let mut working_dir = std::env::current_dir()?;
|
||||||
let mut working_dir = Some(current_dir.as_path());
|
|
||||||
let mut vars_to_add = IndexMap::new();
|
let mut vars_to_add = IndexMap::new();
|
||||||
|
|
||||||
//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 parent to last_seen_directory, current.cmp(last) returns less
|
||||||
//if current dir is the same as last_seen, current.cmp(last) returns equal
|
//if current dir is the same as last_seen, current.cmp(last) returns equal
|
||||||
if current_dir.cmp(&self.last_seen_directory) != std::cmp::Ordering::Greater {
|
|
||||||
|
if working_dir.cmp(&self.last_seen_directory) != std::cmp::Ordering::Greater {
|
||||||
return Ok(vars_to_add);
|
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 working_dir != self.last_seen_directory {
|
||||||
while let Some(wdir) = working_dir {
|
let wdirenv = working_dir.join(".nu-env");
|
||||||
let wdirenv = wdir.join(".nu-env");
|
|
||||||
if wdirenv.exists() {
|
if wdirenv.exists() {
|
||||||
let toml_doc = self.toml_if_directory_is_trusted(&wdirenv)?;
|
let toml_doc = self.toml_if_directory_is_trusted(&wdirenv)?;
|
||||||
toml_doc
|
toml_doc
|
||||||
@ -92,76 +91,49 @@ impl DirectorySpecificEnvironment {
|
|||||||
})?
|
})?
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|(dir_env_key, dir_env_val)| {
|
.for_each(|(dir_env_key, dir_env_val)| {
|
||||||
if let Some(existing_val) = std::env::var_os(dir_env_key) {
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open("toadd.txt")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
write!(&mut file, "{:?} = {:?}\n", dir_env_key, existing_val).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap_or("").into();
|
let dir_env_val: EnvVal = dir_env_val.as_str().unwrap_or("").into();
|
||||||
|
|
||||||
//This condition is to make sure variables in parent directories don't overwrite variables set by subdirectories.
|
//This condition is to make sure variables in parent directories don't overwrite variables set by subdirectories.
|
||||||
if !vars_to_add.contains_key(dir_env_key) {
|
if !vars_to_add.contains_key(dir_env_key) {
|
||||||
vars_to_add.insert(dir_env_key.clone(), dir_env_val);
|
vars_to_add.insert(dir_env_key.clone(), dir_env_val);
|
||||||
let existing_val = std::env::var_os(dir_env_key);
|
|
||||||
self.added_env_vars
|
self.added_env_vars
|
||||||
.entry(wdir.to_path_buf())
|
.entry(working_dir.clone())
|
||||||
.or_insert(IndexMap::new())
|
.or_insert(IndexMap::new())
|
||||||
.insert(dir_env_key.clone(), existing_val);
|
.insert(dir_env_key.clone(), std::env::var_os(dir_env_key));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
working_dir.pop();
|
||||||
//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);
|
|
||||||
}
|
|
||||||
|
|
||||||
working_dir = working_dir //Keep going up in the directory structure with .parent()
|
|
||||||
.expect("This should not be None because of the while condition")
|
|
||||||
.parent();
|
|
||||||
}
|
}
|
||||||
Ok(vars_to_add)
|
Ok(vars_to_add)
|
||||||
}
|
}
|
||||||
|
|
||||||
//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 cleanup_after_dir_exit(
|
pub fn cleanup_after_dir_exit(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Result<(IndexSet<EnvKey>, IndexMap<EnvKey, EnvVal>), ShellError> {
|
) -> Result<IndexMap<EnvKey, Option<EnvVal>>, ShellError> {
|
||||||
let current_dir = std::env::current_dir()?;
|
let current_dir = std::env::current_dir()?;
|
||||||
let mut vars_to_delete = IndexSet::new();
|
let mut vars_to_cleanup = IndexMap::new();
|
||||||
let mut vars_to_restore = IndexMap::new();
|
|
||||||
|
|
||||||
//If we are in the same directory as last_seen, or a subdirectory to it, do nothing
|
//If we are in the same directory as last_seen, or a subdirectory to it, do nothing
|
||||||
//If we are in a subdirectory to last seen, do nothing
|
//If we are in a subdirectory to last seen, do nothing
|
||||||
//If we are in a parent directory to last seen, exit .nu-envs from last seen to parent and restore old vals
|
//If we are in a parent directory to last seen, exit .nu-envs from last seen to parent and restore old vals
|
||||||
if self.last_seen_directory.cmp(¤t_dir) != std::cmp::Ordering::Greater {
|
if self.last_seen_directory.cmp(¤t_dir) != std::cmp::Ordering::Greater {
|
||||||
return Ok((vars_to_delete, vars_to_restore));
|
return Ok(vars_to_cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut working_dir = self.last_seen_directory.clone();
|
let mut working_dir = self.last_seen_directory.clone();
|
||||||
|
|
||||||
while working_dir != current_dir {
|
while working_dir != current_dir {
|
||||||
if let Some(vars_added_by_this_directory) = self.added_env_vars.get(&working_dir) {
|
if let Some(vars_added_by_this_directory) = self.added_env_vars.get(&working_dir) {
|
||||||
|
|
||||||
for (k, v) in vars_added_by_this_directory {
|
for (k, v) in vars_added_by_this_directory {
|
||||||
if let Some(v) = v {
|
vars_to_cleanup.insert(k.clone(), v.clone());
|
||||||
vars_to_restore.insert(k.clone(), v.clone());
|
|
||||||
} else {
|
|
||||||
vars_to_delete.insert(k.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.added_env_vars.remove(&working_dir);
|
||||||
}
|
}
|
||||||
working_dir.pop();
|
working_dir.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((vars_to_delete, vars_to_restore))
|
Ok(vars_to_cleanup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
54
crates/nu-cli/src/env/environment.rs
vendored
54
crates/nu-cli/src/env/environment.rs
vendored
@ -60,46 +60,34 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoenv(&mut self) -> Result<(), ShellError> {
|
pub fn autoenv(&mut self) -> Result<(), ShellError> {
|
||||||
let (to_delete, to_restore) = self.autoenv.cleanup_after_dir_exit()?;
|
|
||||||
|
|
||||||
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open("cleanup.txt")
|
|
||||||
.unwrap(
|
|
||||||
);
|
|
||||||
|
|
||||||
write!(&mut file, "delete {:?}\n", to_delete).unwrap();
|
|
||||||
|
|
||||||
for k in to_delete {
|
|
||||||
self.remove_env(&k);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k, v) in to_restore {
|
|
||||||
self.add_env(&k, &v.to_string_lossy(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k, v) in self.autoenv.env_vars_to_add()? {
|
for (k, v) in self.autoenv.env_vars_to_add()? {
|
||||||
self.add_env(&k, &v.to_string_lossy(), true);
|
std::env::set_var(&k, OsString::from(v.to_string_lossy().to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanup = self.autoenv.cleanup_after_dir_exit()?;
|
||||||
|
|
||||||
|
// let mut file = OpenOptions::new()
|
||||||
|
// .write(true)
|
||||||
|
// .append(true)
|
||||||
|
// .create(true)
|
||||||
|
// .open("cleanup.txt")
|
||||||
|
// .unwrap(
|
||||||
|
// );
|
||||||
|
|
||||||
|
// write!(&mut file, "{:?}\n", cleanup).unwrap();
|
||||||
|
|
||||||
|
for (k, v) in cleanup {
|
||||||
|
if let Some(v) = v {
|
||||||
|
std::env::set_var(k, v);
|
||||||
|
} else {
|
||||||
|
std::env::remove_var(k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.autoenv.last_seen_directory = std::env::current_dir()?;
|
self.autoenv.last_seen_directory = std::env::current_dir()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_env(&mut self, key: &str) {
|
|
||||||
if let Some(Value {
|
|
||||||
value: UntaggedValue::Row(ref mut envs),
|
|
||||||
..
|
|
||||||
}) = self.environment_vars
|
|
||||||
{
|
|
||||||
envs.entries.remove(key);
|
|
||||||
std::env::remove_var(key);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn morph<T: Conf>(&mut self, configuration: &T) {
|
pub fn morph<T: Conf>(&mut self, configuration: &T) {
|
||||||
self.environment_vars = configuration.env();
|
self.environment_vars = configuration.env();
|
||||||
self.path_vars = configuration.path();
|
self.path_vars = configuration.path();
|
||||||
|
5
crates/nu-cli/src/env/environment_syncer.rs
vendored
5
crates/nu-cli/src/env/environment_syncer.rs
vendored
@ -1,9 +1,10 @@
|
|||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::data::config::{Conf, NuConfig};
|
use crate::data::config::{Conf, NuConfig};
|
||||||
|
use std::io::Write;
|
||||||
use crate::env::environment::{Env, Environment};
|
use crate::env::environment::{Env, Environment};
|
||||||
use nu_source::Text;
|
use nu_source::Text;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::Arc;
|
use std::{fs::OpenOptions, sync::Arc};
|
||||||
|
|
||||||
pub struct EnvironmentSyncer {
|
pub struct EnvironmentSyncer {
|
||||||
pub env: Arc<Mutex<Box<Environment>>>,
|
pub env: Arc<Mutex<Box<Environment>>>,
|
||||||
@ -53,7 +54,7 @@ impl EnvironmentSyncer {
|
|||||||
if name != "path" && name != "PATH" {
|
if name != "path" && name != "PATH" {
|
||||||
// account for new env vars present in the current session
|
// account for new env vars present in the current session
|
||||||
// that aren't loaded from config.
|
// that aren't loaded from config.
|
||||||
environment.add_env(&name, &value, false);
|
environment.add_env(&name, &value, true);
|
||||||
|
|
||||||
// clear the env var from the session
|
// clear the env var from the session
|
||||||
// we are about to replace them
|
// we are about to replace them
|
||||||
|
Loading…
x
Reference in New Issue
Block a user