WIP Start export-env

This commit is contained in:
kubouch
2022-08-18 20:55:40 +03:00
parent 529c98085a
commit ea8b0e8a1d
8 changed files with 99 additions and 20 deletions

View File

@ -3,9 +3,9 @@ use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{Category, Example, PipelineData, Signature, Span, SyntaxShape, Value}; use nu_protocol::{Category, Example, PipelineData, Signature, Span, SyntaxShape, Value};
#[derive(Clone)] #[derive(Clone)]
pub struct ExportEnv; pub struct ExportEnvModule;
impl Command for ExportEnv { impl Command for ExportEnvModule {
fn name(&self) -> &str { fn name(&self) -> &str {
"export env" "export env"
} }

View File

@ -40,7 +40,7 @@ pub use export::ExportCommand;
pub use export_alias::ExportAlias; pub use export_alias::ExportAlias;
pub use export_def::ExportDef; pub use export_def::ExportDef;
pub use export_def_env::ExportDefEnv; pub use export_def_env::ExportDefEnv;
pub use export_env::ExportEnv; pub use export_env::ExportEnvModule;
pub use export_extern::ExportExtern; pub use export_extern::ExportExtern;
pub use export_use::ExportUse; pub use export_use::ExportUse;
pub use extern_::Extern; pub use extern_::Extern;

View File

@ -40,7 +40,7 @@ pub fn create_default_context() -> EngineState {
ExportCommand, ExportCommand,
ExportDef, ExportDef,
ExportDefEnv, ExportDefEnv,
ExportEnv, ExportEnvModule,
ExportExtern, ExportExtern,
ExportUse, ExportUse,
Extern, Extern,
@ -352,6 +352,7 @@ pub fn create_default_context() -> EngineState {
// Env // Env
bind_command! { bind_command! {
Env, Env,
ExportEnv,
LetEnv, LetEnv,
LoadEnv, LoadEnv,
WithEnv, WithEnv,

View File

@ -1,5 +1,6 @@
mod config; mod config;
mod env_command; mod env_command;
mod export_env;
mod let_env; mod let_env;
mod load_env; mod load_env;
mod with_env; mod with_env;
@ -9,6 +10,7 @@ pub use config::ConfigMeta;
pub use config::ConfigNu; pub use config::ConfigNu;
pub use config::ConfigReset; pub use config::ConfigReset;
pub use env_command::Env; pub use env_command::Env;
pub use export_env::ExportEnv;
pub use let_env::LetEnv; pub use let_env::LetEnv;
pub use load_env::LoadEnv; pub use load_env::LoadEnv;
pub use with_env::WithEnv; pub use with_env::WithEnv;

View File

@ -159,20 +159,7 @@ pub fn eval_call(
); );
if block.redirect_env { if block.redirect_env {
let caller_env_vars = caller_stack.get_env_var_names(engine_state); redirect_env(engine_state, caller_stack, &callee_stack);
// remove env vars that are present in the caller but not in the callee
// (the callee hid them)
for var in caller_env_vars.iter() {
if !callee_stack.has_env_var(engine_state, var) {
caller_stack.remove_env_var(engine_state, var);
}
}
// add new env vars from callee to caller
for (var, value) in callee_stack.get_stack_env_vars() {
caller_stack.add_env_var(var, value);
}
} }
result result
@ -184,6 +171,24 @@ pub fn eval_call(
} }
} }
/// Redirect the environment from callee to the caller.
pub fn redirect_env(engine_state: &EngineState, caller_stack: &mut Stack, callee_stack: &Stack) {
let caller_env_vars = caller_stack.get_env_var_names(engine_state);
// remove env vars that are present in the caller but not in the callee
// (the callee hid them)
for var in caller_env_vars.iter() {
if !callee_stack.has_env_var(engine_state, var) {
caller_stack.remove_env_var(engine_state, var);
}
}
// add new env vars from callee to caller
for (var, value) in callee_stack.get_stack_env_vars() {
caller_stack.add_env_var(var, value);
}
}
/// Eval extarnal expression /// Eval extarnal expression
/// ///
/// It returns PipelineData with a boolean flag, indicate that if the external runs to failed. /// It returns PipelineData with a boolean flag, indicate that if the external runs to failed.

View File

@ -11,6 +11,6 @@ pub use documentation::get_full_help;
pub use env::*; pub use env::*;
pub use eval::{ pub use eval::{
eval_block, eval_call, eval_expression, eval_expression_with_input, eval_operator, eval_block, eval_call, eval_expression, eval_expression_with_input, eval_operator,
eval_subexpression, eval_variable, eval_subexpression, eval_variable, redirect_env,
}; };
pub use glob_from::glob_from; pub use glob_from::glob_from;

View File

@ -1083,6 +1083,76 @@ pub fn parse_export(
) )
} }
pub fn parse_export_env(
working_set: &mut StateWorkingSet,
spans: &[Span],
expand_aliases_denylist: &[usize],
) -> (Pipeline, Option<ParseError>) {
if (spans.len() > 0 && working_set.get_span_contents(span(&[spans[0]])) != b"export-env") || (spans.len() != 2) {
return (
garbage_pipeline(spans),
Some(ParseError::UnknownState(
"internal error: Wrong signature of 'export-env' command".into(),
span(spans),
)),
);
}
let (call, call_span) = match working_set.find_decl(b"export-env", &Type::Any) {
Some(decl_id) => {
let ParsedInternalCall {
call,
error: mut err,
output,
} = parse_internal_call(
working_set,
span(&[spans[0]]),
&spans[1..],
decl_id,
expand_aliases_denylist,
);
let decl = working_set.get_decl(decl_id);
let call_span = span(spans);
err = check_call(call_span, &decl.signature(), &call).or(err);
if err.is_some() || call.has_flag("help") {
return (
Pipeline::from_vec(vec![Expression {
expr: Expr::Call(call),
span: call_span,
ty: output,
custom_completion: None,
}]),
err,
);
}
(call, call_span)
}
None => {
return (
garbage_pipeline(spans),
Some(ParseError::UnknownState(
"internal error: 'export-env' declaration not found".into(),
span(spans),
)),
)
}
};
let pipeline = Pipeline::from_vec(vec![Expression {
expr: Expr::Call(call),
span: span(spans),
ty: Type::Any,
custom_completion: None,
}]);
let mut error = None;
(pipeline, error)
}
pub fn parse_module_block( pub fn parse_module_block(
working_set: &mut StateWorkingSet, working_set: &mut StateWorkingSet,
span: Span, span: Span,

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
lex, lite_parse, lex, lite_parse,
lite_parse::LiteCommand, lite_parse::LiteCommand,
parse_keywords::{parse_extern, parse_for, parse_source}, parse_keywords::{parse_extern, parse_for, parse_source, parse_export_env},
type_check::{math_result_type, type_compatible}, type_check::{math_result_type, type_compatible},
LiteBlock, ParseError, Token, TokenContents, LiteBlock, ParseError, Token, TokenContents,
}; };
@ -4851,6 +4851,7 @@ pub fn parse_builtin_commands(
) )
} }
} }
b"export-env" => parse_export_env(working_set, &lite_command.parts, expand_aliases_denylist),
b"hide" => parse_hide(working_set, &lite_command.parts, expand_aliases_denylist), b"hide" => parse_hide(working_set, &lite_command.parts, expand_aliases_denylist),
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
b"register" => parse_register(working_set, &lite_command.parts, expand_aliases_denylist), b"register" => parse_register(working_set, &lite_command.parts, expand_aliases_denylist),