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};
#[derive(Clone)]
pub struct ExportEnv;
pub struct ExportEnvModule;
impl Command for ExportEnv {
impl Command for ExportEnvModule {
fn name(&self) -> &str {
"export env"
}

View File

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

View File

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

View File

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

View File

@ -159,20 +159,7 @@ pub fn eval_call(
);
if block.redirect_env {
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);
}
redirect_env(engine_state, caller_stack, &callee_stack);
}
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
///
/// 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 eval::{
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;

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(
working_set: &mut StateWorkingSet,
span: Span,

View File

@ -1,7 +1,7 @@
use crate::{
lex, lite_parse,
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},
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),
#[cfg(feature = "plugin")]
b"register" => parse_register(working_set, &lite_command.parts, expand_aliases_denylist),