mirror of
https://github.com/nushell/nushell
synced 2024-12-27 21:43:09 +00:00
parent
5bf1c98a39
commit
c17129a92a
2 changed files with 83 additions and 19 deletions
|
@ -1,7 +1,7 @@
|
||||||
use crate::CliError;
|
use crate::CliError;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_engine::eval_block;
|
use nu_engine::eval_block;
|
||||||
use nu_parser::{lex, parse, trim_quotes, Token, TokenContents};
|
use nu_parser::{lex, parse, unescape_unquote_string, Token, TokenContents};
|
||||||
use nu_protocol::engine::StateWorkingSet;
|
use nu_protocol::engine::StateWorkingSet;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
|
@ -98,6 +98,10 @@ pub fn print_pipeline_data(
|
||||||
// env vars into it (in a "NAME"="value" format, quite similar to the output of the Unix 'env'
|
// env vars into it (in a "NAME"="value" format, quite similar to the output of the Unix 'env'
|
||||||
// tool), then uses the file to get the spans. The file stays in memory, no filesystem IO is done.
|
// tool), then uses the file to get the spans. The file stays in memory, no filesystem IO is done.
|
||||||
pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||||
|
gather_env_vars(std::env::vars(), engine_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_env_vars(vars: impl Iterator<Item = (String, String)>, engine_state: &mut EngineState) {
|
||||||
fn report_capture_error(engine_state: &EngineState, env_str: &str, msg: &str) {
|
fn report_capture_error(engine_state: &EngineState, env_str: &str, msg: &str) {
|
||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
report_error(
|
report_error(
|
||||||
|
@ -110,20 +114,35 @@ pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_env_to_fake_file(name: &str, val: &str, fake_env_file: &mut String) {
|
fn put_env_to_fake_file(name: &str, val: &str, fake_env_file: &mut String) {
|
||||||
fake_env_file.push('`');
|
fn push_string_literal(s: &str, fake_env_file: &mut String) {
|
||||||
fake_env_file.push_str(name);
|
fake_env_file.push('"');
|
||||||
fake_env_file.push('`');
|
for c in s.chars() {
|
||||||
|
if c == '\\' || c == '"' {
|
||||||
|
fake_env_file.push('\\');
|
||||||
|
}
|
||||||
|
fake_env_file.push(c);
|
||||||
|
}
|
||||||
|
fake_env_file.push('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
push_string_literal(name, fake_env_file);
|
||||||
fake_env_file.push('=');
|
fake_env_file.push('=');
|
||||||
fake_env_file.push('`');
|
push_string_literal(val, fake_env_file);
|
||||||
fake_env_file.push_str(val);
|
|
||||||
fake_env_file.push('`');
|
|
||||||
fake_env_file.push('\n');
|
fake_env_file.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fake_env_file = String::new();
|
let mut fake_env_file = String::new();
|
||||||
|
let mut has_pwd = false;
|
||||||
|
|
||||||
// Make sure we always have PWD
|
// Write all the env vars into a fake file
|
||||||
if std::env::var("PWD").is_err() {
|
for (name, val) in vars {
|
||||||
|
if name == "PWD" {
|
||||||
|
has_pwd = true;
|
||||||
|
}
|
||||||
|
put_env_to_fake_file(&name, &val, &mut fake_env_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has_pwd {
|
||||||
match std::env::current_dir() {
|
match std::env::current_dir() {
|
||||||
Ok(cwd) => {
|
Ok(cwd) => {
|
||||||
put_env_to_fake_file("PWD", &cwd.to_string_lossy(), &mut fake_env_file);
|
put_env_to_fake_file("PWD", &cwd.to_string_lossy(), &mut fake_env_file);
|
||||||
|
@ -142,11 +161,6 @@ pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write all the env vars into a fake file
|
|
||||||
for (name, val) in std::env::vars() {
|
|
||||||
put_env_to_fake_file(&name, &val, &mut fake_env_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lex the fake file, assign spans to all environment variables and add them
|
// Lex the fake file, assign spans to all environment variables and add them
|
||||||
// to stack
|
// to stack
|
||||||
let span_offset = engine_state.next_span_start();
|
let span_offset = engine_state.next_span_start();
|
||||||
|
@ -184,8 +198,19 @@ pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = trim_quotes(bytes);
|
let (bytes, parse_error) = unescape_unquote_string(bytes, *span);
|
||||||
String::from_utf8_lossy(bytes).to_string()
|
|
||||||
|
if parse_error.is_some() {
|
||||||
|
report_capture_error(
|
||||||
|
engine_state,
|
||||||
|
&String::from_utf8_lossy(contents),
|
||||||
|
"Got unparsable name.",
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes
|
||||||
} else {
|
} else {
|
||||||
report_capture_error(
|
report_capture_error(
|
||||||
engine_state,
|
engine_state,
|
||||||
|
@ -213,10 +238,20 @@ pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = trim_quotes(bytes);
|
let (bytes, parse_error) = unescape_unquote_string(bytes, *span);
|
||||||
|
|
||||||
|
if parse_error.is_some() {
|
||||||
|
report_capture_error(
|
||||||
|
engine_state,
|
||||||
|
&String::from_utf8_lossy(contents),
|
||||||
|
"Got unparsable value.",
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Value::String {
|
Value::String {
|
||||||
val: String::from_utf8_lossy(bytes).to_string(),
|
val: bytes,
|
||||||
span: *span,
|
span: *span,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -350,3 +385,32 @@ pub fn get_init_cwd() -> PathBuf {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gather_env_vars() {
|
||||||
|
let mut engine_state = EngineState::new();
|
||||||
|
let symbols = r##" !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"##;
|
||||||
|
|
||||||
|
gather_env_vars(
|
||||||
|
[
|
||||||
|
("FOO".into(), "foo".into()),
|
||||||
|
("SYMBOLS".into(), symbols.into()),
|
||||||
|
(symbols.into(), "symbols".into()),
|
||||||
|
]
|
||||||
|
.into_iter(),
|
||||||
|
&mut engine_state,
|
||||||
|
);
|
||||||
|
|
||||||
|
let env = engine_state.env_vars;
|
||||||
|
|
||||||
|
assert!(matches!(env.get("FOO"), Some(Value::String { val, .. }) if val == "foo"));
|
||||||
|
assert!(matches!(env.get("SYMBOLS"), Some(Value::String { val, .. }) if val == symbols));
|
||||||
|
assert!(matches!(env.get(symbols), Some(Value::String { val, .. }) if val == "symbols"));
|
||||||
|
assert!(env.get("PWD").is_some());
|
||||||
|
assert_eq!(env.len(), 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub use lite_parse::{lite_parse, LiteBlock};
|
||||||
|
|
||||||
pub use parser::{
|
pub use parser::{
|
||||||
is_math_expression_like, parse, parse_block, parse_duration_bytes, parse_external_call,
|
is_math_expression_like, parse, parse_block, parse_duration_bytes, parse_external_call,
|
||||||
trim_quotes, Import,
|
trim_quotes, unescape_unquote_string, Import,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
|
|
Loading…
Reference in a new issue