mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 08:55:40 +02:00
Hiding of environment variables (#362)
* Remember environment variables from previous scope * Re-introduce env var hiding Right now, hiding decls is broken * Re-introduce hidden field of import patterns All tests pass now. * Remove/Address tests TODOs * Fix test typo; Report hiding error * Add a few more tests * Fix wrong expected test result
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use crate::{span, Span};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ImportPatternMember {
|
||||
@ -17,6 +18,9 @@ pub struct ImportPatternHead {
|
||||
pub struct ImportPattern {
|
||||
pub head: ImportPatternHead,
|
||||
pub members: Vec<ImportPatternMember>,
|
||||
// communicate to eval which decls/aliases were hidden during `parse_hide()` so it does not
|
||||
// interpret these as env var names:
|
||||
pub hidden: HashSet<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl ImportPattern {
|
||||
@ -37,4 +41,12 @@ impl ImportPattern {
|
||||
|
||||
span(&spans)
|
||||
}
|
||||
|
||||
pub fn with_hidden(self, hidden: HashSet<Vec<u8>>) -> Self {
|
||||
ImportPattern {
|
||||
head: self.head,
|
||||
members: self.members,
|
||||
hidden,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,10 @@ use crate::{Config, ShellError, Value, VarId, CONFIG_VARIABLE_ID};
|
||||
/// use the Stack as a way of representing the local and closure-captured state.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Stack {
|
||||
/// Variables
|
||||
pub vars: HashMap<VarId, Value>,
|
||||
pub env_vars: HashMap<String, String>,
|
||||
/// Environment variables arranged as a stack to be able to recover values from parent scopes
|
||||
pub env_vars: Vec<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl Default for Stack {
|
||||
@ -35,7 +37,7 @@ impl Stack {
|
||||
pub fn new() -> Stack {
|
||||
Stack {
|
||||
vars: HashMap::new(),
|
||||
env_vars: HashMap::new(),
|
||||
env_vars: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +54,11 @@ impl Stack {
|
||||
}
|
||||
|
||||
pub fn add_env_var(&mut self, var: String, value: String) {
|
||||
self.env_vars.insert(var, value);
|
||||
if let Some(scope) = self.env_vars.last_mut() {
|
||||
scope.insert(var, value);
|
||||
} else {
|
||||
self.env_vars.push(HashMap::from([(var, value)]));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_captures(&self, captures: &[VarId]) -> Stack {
|
||||
@ -68,6 +74,7 @@ impl Stack {
|
||||
|
||||
// FIXME: this is probably slow
|
||||
output.env_vars = self.env_vars.clone();
|
||||
output.env_vars.push(HashMap::new());
|
||||
|
||||
let config = self
|
||||
.get_var(CONFIG_VARIABLE_ID)
|
||||
@ -77,19 +84,35 @@ impl Stack {
|
||||
output
|
||||
}
|
||||
|
||||
/// Flatten the env var scope frames into one frame
|
||||
pub fn get_env_vars(&self) -> HashMap<String, String> {
|
||||
self.env_vars.clone()
|
||||
let mut result = HashMap::new();
|
||||
|
||||
for scope in &self.env_vars {
|
||||
result.extend(scope.clone());
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn get_env_var(&self, name: &str) -> Option<String> {
|
||||
if let Some(v) = self.env_vars.get(name) {
|
||||
return Some(v.to_string());
|
||||
for scope in self.env_vars.iter().rev() {
|
||||
if let Some(v) = scope.get(name) {
|
||||
return Some(v.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn remove_env_var(&mut self, name: &str) -> Option<String> {
|
||||
self.env_vars.remove(name)
|
||||
for scope in self.env_vars.iter_mut().rev() {
|
||||
if let Some(v) = scope.remove(name) {
|
||||
return Some(v);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_config(&self) -> Result<Config, ShellError> {
|
||||
@ -109,9 +132,11 @@ impl Stack {
|
||||
for (var, val) in &self.vars {
|
||||
println!(" {}: {:?}", var, val);
|
||||
}
|
||||
println!("env vars:");
|
||||
for (var, val) in &self.env_vars {
|
||||
println!(" {}: {:?}", var, val);
|
||||
for (i, scope) in self.env_vars.iter().rev().enumerate() {
|
||||
println!("env vars, scope {} (from the last);", i);
|
||||
for (var, val) in scope {
|
||||
println!(" {}: {:?}", var, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user