mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
Fix warnings and split Scope (#1902)
This commit is contained in:
parent
9567c1f564
commit
fa812849b8
@ -13,7 +13,7 @@ use futures_codec::FramedRead;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::{ClassifiedCommand, Expression, InternalCommand, Literal, NamedArguments};
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Scope, Signature, UntaggedValue, Value};
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||
|
||||
use log::{debug, trace};
|
||||
use rustyline::error::ReadlineError;
|
||||
@ -870,7 +870,16 @@ async fn process_line(
|
||||
|
||||
trace!("{:#?}", classified_block);
|
||||
let env = ctx.get_env();
|
||||
match run_block(&classified_block.block, ctx, input_stream, &Scope::env(env)).await {
|
||||
match run_block(
|
||||
&classified_block.block,
|
||||
ctx,
|
||||
input_stream,
|
||||
&Value::nothing(),
|
||||
&IndexMap::new(),
|
||||
&env,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(input) => {
|
||||
// Running a pipeline gives us back a stream that we can then
|
||||
// work through. At the top level, we just want to pull on the
|
||||
|
@ -368,7 +368,7 @@ fn create_default_command_args(context: &RunnableContextWithoutInput) -> RawComm
|
||||
is_last: true,
|
||||
},
|
||||
name_tag: context.name.clone(),
|
||||
scope: Scope::empty(),
|
||||
scope: Scope::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,16 @@ use crate::stream::InputStream;
|
||||
use futures::stream::TryStreamExt;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::{Block, ClassifiedCommand, Commands};
|
||||
use nu_protocol::{ReturnSuccess, Scope, UntaggedValue, Value};
|
||||
use nu_protocol::{ReturnSuccess, UntaggedValue, Value};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
pub(crate) async fn run_block(
|
||||
block: &Block,
|
||||
ctx: &mut Context,
|
||||
mut input: InputStream,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
let mut output: Result<InputStream, ShellError> = Ok(InputStream::empty());
|
||||
for pipeline in &block.block {
|
||||
@ -52,7 +54,7 @@ pub(crate) async fn run_block(
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
output = run_pipeline(pipeline, ctx, input, scope).await;
|
||||
output = run_pipeline(pipeline, ctx, input, it, vars, env).await;
|
||||
|
||||
input = InputStream::empty();
|
||||
}
|
||||
@ -64,10 +66,11 @@ async fn run_pipeline(
|
||||
commands: &Commands,
|
||||
ctx: &mut Context,
|
||||
mut input: InputStream,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
let mut iter = commands.list.clone().into_iter().peekable();
|
||||
|
||||
loop {
|
||||
let item: Option<ClassifiedCommand> = iter.next();
|
||||
let next: Option<&ClassifiedCommand> = iter.peek();
|
||||
@ -78,13 +81,13 @@ async fn run_pipeline(
|
||||
}
|
||||
|
||||
(Some(ClassifiedCommand::Expr(expr)), _) => {
|
||||
run_expression_block(*expr, ctx, input, scope).await?
|
||||
run_expression_block(*expr, ctx, it, vars, env).await?
|
||||
}
|
||||
(Some(ClassifiedCommand::Error(err)), _) => return Err(err.into()),
|
||||
(_, Some(ClassifiedCommand::Error(err))) => return Err(err.clone().into()),
|
||||
|
||||
(Some(ClassifiedCommand::Internal(left)), _) => {
|
||||
run_internal_command(left, ctx, input, scope)?
|
||||
run_internal_command(left, ctx, input, it, vars, env)?
|
||||
}
|
||||
|
||||
(None, _) => break,
|
||||
|
@ -6,22 +6,22 @@ use log::{log_enabled, trace};
|
||||
use futures::stream::once;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::SpannedExpression;
|
||||
use nu_protocol::Scope;
|
||||
use nu_protocol::Value;
|
||||
|
||||
pub(crate) async fn run_expression_block(
|
||||
expr: SpannedExpression,
|
||||
context: &mut Context,
|
||||
_input: InputStream,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
if log_enabled!(log::Level::Trace) {
|
||||
trace!(target: "nu::run::expr", "->");
|
||||
trace!(target: "nu::run::expr", "{:?}", expr);
|
||||
}
|
||||
|
||||
let scope = scope.clone();
|
||||
let registry = context.registry().clone();
|
||||
let output = evaluate_baseline_expr(&expr, ®istry, &scope).await?;
|
||||
let output = evaluate_baseline_expr(&expr, ®istry, it, vars, env).await?;
|
||||
|
||||
Ok(once(async { Ok(output) }).to_input_stream())
|
||||
}
|
||||
|
@ -115,7 +115,9 @@ async fn run_with_stdin(
|
||||
|
||||
let mut command_args = vec![];
|
||||
for arg in command.args.iter() {
|
||||
let value = evaluate_baseline_expr(arg, &context.registry, scope).await?;
|
||||
let value =
|
||||
evaluate_baseline_expr(arg, &context.registry, &scope.it, &scope.vars, &scope.env)
|
||||
.await?;
|
||||
// Skip any arguments that don't really exist, treating them as optional
|
||||
// FIXME: we may want to preserve the gap in the future, though it's hard to say
|
||||
// what value we would put in its place.
|
||||
@ -509,7 +511,7 @@ mod tests {
|
||||
let mut ctx = Context::basic().expect("There was a problem creating a basic context.");
|
||||
|
||||
assert!(
|
||||
run_external_command(cmd, &mut ctx, input, &Scope::empty(), false)
|
||||
run_external_command(cmd, &mut ctx, input, &Scope::new(), false)
|
||||
.await
|
||||
.is_err()
|
||||
);
|
||||
|
@ -11,13 +11,20 @@ pub(crate) fn run_internal_command(
|
||||
command: InternalCommand,
|
||||
context: &mut Context,
|
||||
input: InputStream,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
if log_enabled!(log::Level::Trace) {
|
||||
trace!(target: "nu::run::internal", "->");
|
||||
trace!(target: "nu::run::internal", "{}", command.name);
|
||||
}
|
||||
|
||||
let scope = Scope {
|
||||
it: it.clone(),
|
||||
vars: vars.clone(),
|
||||
env: env.clone(),
|
||||
};
|
||||
let objects: InputStream = trace_stream!(target: "nu::trace_stream::internal", "input" = input);
|
||||
let internal_command = context.expect_command(&command.name);
|
||||
|
||||
@ -26,14 +33,14 @@ pub(crate) fn run_internal_command(
|
||||
internal_command?,
|
||||
Tag::unknown_anchor(command.name_span),
|
||||
command.args.clone(),
|
||||
scope,
|
||||
&scope,
|
||||
objects,
|
||||
)
|
||||
};
|
||||
|
||||
let mut result = trace_out_stream!(target: "nu::trace_stream::internal", "output" = result);
|
||||
let mut context = context.clone();
|
||||
let scope = scope.clone();
|
||||
// let scope = scope.clone();
|
||||
|
||||
let stream = async_stream! {
|
||||
let mut soft_errs: Vec<ShellError> = vec![];
|
||||
|
@ -35,7 +35,7 @@ impl UnevaluatedCallInfo {
|
||||
it: &Value,
|
||||
) -> Result<CallInfo, ShellError> {
|
||||
let mut scope = self.scope.clone();
|
||||
scope = scope.set_it(it.clone());
|
||||
scope.it = it.clone();
|
||||
let args = evaluate_args(&self.args, registry, &scope).await?;
|
||||
|
||||
Ok(CallInfo {
|
||||
|
@ -84,19 +84,20 @@ fn each(raw_args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStrea
|
||||
let (each_args, mut input): (EachArgs, _) = raw_args.process(®istry).await?;
|
||||
let block = each_args.block;
|
||||
while let Some(input) = input.next().await {
|
||||
|
||||
let input_clone = input.clone();
|
||||
let input_stream = if is_expanded_it_usage(&head) {
|
||||
InputStream::empty()
|
||||
} else {
|
||||
once(async { Ok(input) }).to_input_stream()
|
||||
once(async { Ok(input_clone) }).to_input_stream()
|
||||
};
|
||||
|
||||
let result = run_block(
|
||||
&block,
|
||||
&mut context,
|
||||
input_stream,
|
||||
&scope.clone().set_it(input_clone),
|
||||
&input,
|
||||
&scope.vars,
|
||||
&scope.env
|
||||
).await;
|
||||
|
||||
match result {
|
||||
|
@ -62,7 +62,6 @@ fn format_command(
|
||||
let commands = format_pattern;
|
||||
|
||||
while let Some(value) = input.next().await {
|
||||
let scope = scope.clone().set_it(value);
|
||||
let mut output = String::new();
|
||||
|
||||
for command in &commands {
|
||||
@ -74,7 +73,7 @@ fn format_command(
|
||||
// FIXME: use the correct spans
|
||||
let full_column_path = nu_parser::parse_full_column_path(&(c.to_string()).spanned(Span::unknown()), ®istry);
|
||||
|
||||
let result = evaluate_baseline_expr(&full_column_path.0, ®istry, &scope).await;
|
||||
let result = evaluate_baseline_expr(&full_column_path.0, ®istry, &value, &scope.vars, &scope.env).await;
|
||||
|
||||
if let Ok(c) = result {
|
||||
output
|
||||
|
@ -89,7 +89,7 @@ impl WholeStreamCommand for KeepUntil {
|
||||
let condition = condition.clone();
|
||||
trace!("ITEM = {:?}", item);
|
||||
let result =
|
||||
evaluate_baseline_expr(&*condition, ®istry, &scope.clone().set_it(item.clone()))
|
||||
evaluate_baseline_expr(&*condition, ®istry, &item, &scope.vars, &scope.env)
|
||||
.await;
|
||||
trace!("RESULT = {:?}", result);
|
||||
|
||||
|
@ -89,7 +89,7 @@ impl WholeStreamCommand for KeepWhile {
|
||||
let condition = condition.clone();
|
||||
trace!("ITEM = {:?}", item);
|
||||
let result =
|
||||
evaluate_baseline_expr(&*condition, ®istry, &scope.clone().set_it(item.clone()))
|
||||
evaluate_baseline_expr(&*condition, ®istry, &item, &scope.vars, &scope.env)
|
||||
.await;
|
||||
trace!("RESULT = {:?}", result);
|
||||
|
||||
|
@ -50,17 +50,19 @@ impl WholeStreamCommand for Merge {
|
||||
|
||||
fn merge(raw_args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
let scope = raw_args.call_info.scope.clone();
|
||||
let stream = async_stream! {
|
||||
let mut context = Context::from_raw(&raw_args, ®istry);
|
||||
let name_tag = raw_args.call_info.name_tag.clone();
|
||||
let scope = raw_args.call_info.scope.clone();
|
||||
let (merge_args, mut input): (MergeArgs, _) = raw_args.process(®istry).await?;
|
||||
let block = merge_args.block;
|
||||
|
||||
let table: Option<Vec<Value>> = match run_block(&block,
|
||||
&mut context,
|
||||
InputStream::empty(),
|
||||
&scope).await {
|
||||
&scope.it,
|
||||
&scope.vars,
|
||||
&scope.env).await {
|
||||
Ok(mut stream) => Some(stream.drain_vec().await),
|
||||
Err(err) => {
|
||||
yield Err(err);
|
||||
|
@ -50,7 +50,7 @@ impl WholeStreamCommand for AliasCommand {
|
||||
let evaluated = call_info.evaluate(®istry).await?;
|
||||
if let Some(positional) = &evaluated.args.positional {
|
||||
for (pos, arg) in positional.iter().enumerate() {
|
||||
scope = scope.set_var(alias_command.args[pos].to_string(), arg.clone());
|
||||
scope.vars.insert(alias_command.args[pos].to_string(), arg.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,9 @@ impl WholeStreamCommand for AliasCommand {
|
||||
&block,
|
||||
&mut context,
|
||||
input,
|
||||
&scope,
|
||||
&scope.it,
|
||||
&scope.vars,
|
||||
&scope.env,
|
||||
).await;
|
||||
|
||||
match result {
|
||||
|
@ -90,7 +90,7 @@ impl WholeStreamCommand for SkipUntil {
|
||||
let condition = condition.clone();
|
||||
trace!("ITEM = {:?}", item);
|
||||
let result =
|
||||
evaluate_baseline_expr(&*condition, ®istry, &scope.clone().set_it(item.clone()))
|
||||
evaluate_baseline_expr(&*condition, ®istry, &item, &scope.vars, &scope.env)
|
||||
.await;
|
||||
trace!("RESULT = {:?}", result);
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl WholeStreamCommand for SkipWhile {
|
||||
let condition = condition.clone();
|
||||
trace!("ITEM = {:?}", item);
|
||||
let result =
|
||||
evaluate_baseline_expr(&*condition, ®istry, &scope.clone().set_it(item.clone()))
|
||||
evaluate_baseline_expr(&*condition, ®istry, &item, &scope.vars, &scope.env)
|
||||
.await;
|
||||
trace!("RESULT = {:?}", result);
|
||||
|
||||
|
@ -62,14 +62,15 @@ fn update(raw_args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStr
|
||||
tag,
|
||||
} => {
|
||||
let for_block = input.clone();
|
||||
let input_clone = input.clone();
|
||||
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
||||
|
||||
let result = run_block(
|
||||
&block,
|
||||
&mut context,
|
||||
input_stream,
|
||||
&scope.clone().set_it(input_clone),
|
||||
&input,
|
||||
&scope.vars,
|
||||
&scope.env
|
||||
).await;
|
||||
|
||||
match result {
|
||||
|
@ -67,10 +67,9 @@ fn where_command(
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
let scope = raw_args.call_info.scope.clone();
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let stream = async_stream! {
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let scope = raw_args.call_info.scope.clone();
|
||||
|
||||
let (WhereArgs { block }, mut input) = raw_args.process(®istry).await?;
|
||||
let condition = {
|
||||
if block.block.len() != 1 {
|
||||
@ -108,7 +107,7 @@ fn where_command(
|
||||
while let Some(input) = input.next().await {
|
||||
|
||||
//FIXME: should we use the scope that's brought in as well?
|
||||
let condition = evaluate_baseline_expr(&condition, ®istry, &scope.clone().set_it(input.clone())).await?;
|
||||
let condition = evaluate_baseline_expr(&condition, ®istry, &input, &scope.vars, &scope.env).await?;
|
||||
|
||||
match condition.as_bool() {
|
||||
Ok(b) => {
|
||||
|
@ -57,18 +57,21 @@ fn with_env(raw_args: CommandArgs, registry: &CommandRegistry) -> Result<OutputS
|
||||
|
||||
let stream = async_stream! {
|
||||
let mut context = Context::from_raw(&raw_args, ®istry);
|
||||
let scope = raw_args
|
||||
let mut scope = raw_args
|
||||
.call_info
|
||||
.scope
|
||||
.clone();
|
||||
let (WithEnvArgs { variable, block }, mut input) = raw_args.process(®istry).await?;
|
||||
let scope = scope.set_env_var(variable.0.item, variable.1.item);
|
||||
|
||||
scope.env.insert(variable.0.item, variable.1.item);
|
||||
|
||||
let result = run_block(
|
||||
&block,
|
||||
&mut context,
|
||||
input,
|
||||
&scope.clone(),
|
||||
&scope.it,
|
||||
&scope.vars,
|
||||
&scope.env,
|
||||
).await;
|
||||
|
||||
match result {
|
||||
|
@ -14,7 +14,8 @@ pub(crate) async fn evaluate_args(
|
||||
|
||||
if let Some(positional) = &call.positional {
|
||||
for pos in positional {
|
||||
let result = evaluate_baseline_expr(pos, registry, scope).await?;
|
||||
let result =
|
||||
evaluate_baseline_expr(pos, registry, &scope.it, &scope.vars, &scope.env).await?;
|
||||
positional_args.push(result);
|
||||
}
|
||||
}
|
||||
@ -36,7 +37,8 @@ pub(crate) async fn evaluate_args(
|
||||
hir::NamedValue::Value(_, expr) => {
|
||||
named_args.insert(
|
||||
name.clone(),
|
||||
evaluate_baseline_expr(expr, registry, scope).await?,
|
||||
evaluate_baseline_expr(expr, registry, &scope.it, &scope.vars, &scope.env)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,16 @@ use log::trace;
|
||||
use nu_errors::{ArgumentError, ShellError};
|
||||
use nu_protocol::hir::{self, Expression, SpannedExpression};
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, RangeInclusion, Scope, UnspannedPathMember, UntaggedValue, Value,
|
||||
ColumnPath, Primitive, RangeInclusion, UnspannedPathMember, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
#[async_recursion]
|
||||
pub(crate) async fn evaluate_baseline_expr(
|
||||
expr: &SpannedExpression,
|
||||
registry: &CommandRegistry,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = Tag {
|
||||
span: expr.span,
|
||||
@ -31,14 +33,14 @@ pub(crate) async fn evaluate_baseline_expr(
|
||||
Expression::Synthetic(hir::Synthetic::String(s)) => {
|
||||
Ok(UntaggedValue::string(s).into_untagged_value())
|
||||
}
|
||||
Expression::Variable(var) => evaluate_reference(&var, &scope, tag),
|
||||
Expression::Command(_) => evaluate_command(tag, &scope),
|
||||
Expression::Invocation(block) => evaluate_invocation(block, registry, scope).await,
|
||||
Expression::ExternalCommand(external) => evaluate_external(&external, &scope),
|
||||
Expression::Variable(var) => evaluate_reference(&var, it, vars, env, tag),
|
||||
Expression::Command(_) => unimplemented!(),
|
||||
Expression::Invocation(block) => evaluate_invocation(block, registry, it, vars, env).await,
|
||||
Expression::ExternalCommand(_) => unimplemented!(),
|
||||
Expression::Binary(binary) => {
|
||||
// TODO: If we want to add short-circuiting, we'll need to move these down
|
||||
let left = evaluate_baseline_expr(&binary.left, registry, scope).await?;
|
||||
let right = evaluate_baseline_expr(&binary.right, registry, scope).await?;
|
||||
let left = evaluate_baseline_expr(&binary.left, registry, it, vars, env).await?;
|
||||
let right = evaluate_baseline_expr(&binary.right, registry, it, vars, env).await?;
|
||||
|
||||
trace!("left={:?} right={:?}", left.value, right.value);
|
||||
|
||||
@ -59,8 +61,8 @@ pub(crate) async fn evaluate_baseline_expr(
|
||||
let left = &range.left;
|
||||
let right = &range.right;
|
||||
|
||||
let left = evaluate_baseline_expr(&left, registry, scope).await?;
|
||||
let right = evaluate_baseline_expr(&right, registry, scope).await?;
|
||||
let left = evaluate_baseline_expr(&left, registry, it, vars, env).await?;
|
||||
let right = evaluate_baseline_expr(&right, registry, it, vars, env).await?;
|
||||
let left_span = left.tag.span;
|
||||
let right_span = right.tag.span;
|
||||
|
||||
@ -79,7 +81,7 @@ pub(crate) async fn evaluate_baseline_expr(
|
||||
let mut exprs = vec![];
|
||||
|
||||
for expr in list {
|
||||
let expr = evaluate_baseline_expr(&expr, registry, scope).await?;
|
||||
let expr = evaluate_baseline_expr(&expr, registry, it, vars, env).await?;
|
||||
exprs.push(expr);
|
||||
}
|
||||
|
||||
@ -87,7 +89,7 @@ pub(crate) async fn evaluate_baseline_expr(
|
||||
}
|
||||
Expression::Block(block) => Ok(UntaggedValue::Block(block.clone()).into_value(&tag)),
|
||||
Expression::Path(path) => {
|
||||
let value = evaluate_baseline_expr(&path.head, registry, scope).await?;
|
||||
let value = evaluate_baseline_expr(&path.head, registry, it, vars, env).await?;
|
||||
let mut item = value;
|
||||
|
||||
for member in &path.tail {
|
||||
@ -151,12 +153,17 @@ fn evaluate_literal(literal: &hir::Literal, span: Span) -> Value {
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_reference(name: &hir::Variable, scope: &Scope, tag: Tag) -> Result<Value, ShellError> {
|
||||
trace!("Evaluating {:?} with Scope {:?}", name, scope);
|
||||
fn evaluate_reference(
|
||||
name: &hir::Variable,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
tag: Tag,
|
||||
) -> Result<Value, ShellError> {
|
||||
match name {
|
||||
hir::Variable::It(_) => Ok(scope.it.value.clone().into_value(tag)),
|
||||
hir::Variable::It(_) => Ok(it.clone()),
|
||||
hir::Variable::Other(name, _) => match name {
|
||||
x if x == "$nu" => crate::evaluate::variables::nu(scope, tag),
|
||||
x if x == "$nu" => crate::evaluate::variables::nu(env, tag),
|
||||
x if x == "$true" => Ok(Value {
|
||||
value: UntaggedValue::boolean(true),
|
||||
tag,
|
||||
@ -165,8 +172,7 @@ fn evaluate_reference(name: &hir::Variable, scope: &Scope, tag: Tag) -> Result<V
|
||||
value: UntaggedValue::boolean(false),
|
||||
tag,
|
||||
}),
|
||||
x => Ok(scope
|
||||
.vars
|
||||
x => Ok(vars
|
||||
.get(x)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| UntaggedValue::nothing().into_value(tag))),
|
||||
@ -174,19 +180,12 @@ fn evaluate_reference(name: &hir::Variable, scope: &Scope, tag: Tag) -> Result<V
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_external(
|
||||
external: &hir::ExternalStringCommand,
|
||||
_scope: &Scope,
|
||||
) -> Result<Value, ShellError> {
|
||||
Err(ShellError::syntax_error(
|
||||
"Unexpected external command".spanned(external.name.span),
|
||||
))
|
||||
}
|
||||
|
||||
async fn evaluate_invocation(
|
||||
block: &hir::Block,
|
||||
registry: &CommandRegistry,
|
||||
scope: &Scope,
|
||||
it: &Value,
|
||||
vars: &IndexMap<String, Value>,
|
||||
env: &IndexMap<String, String>,
|
||||
) -> Result<Value, ShellError> {
|
||||
// FIXME: we should use a real context here
|
||||
let mut context = Context::basic()?;
|
||||
@ -194,7 +193,7 @@ async fn evaluate_invocation(
|
||||
|
||||
let input = InputStream::empty();
|
||||
|
||||
let result = run_block(&block, &mut context, input, &scope.clone()).await?;
|
||||
let result = run_block(&block, &mut context, input, it, vars, env).await?;
|
||||
|
||||
let output = result.into_vec().await;
|
||||
|
||||
@ -208,9 +207,3 @@ async fn evaluate_invocation(
|
||||
_ => Ok(UntaggedValue::nothing().into_value(Tag::unknown())),
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_command(tag: Tag, _scope: &Scope) -> Result<Value, ShellError> {
|
||||
Err(ShellError::syntax_error(
|
||||
"Unexpected command".spanned(tag.span),
|
||||
))
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
use crate::cli::History;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Scope, TaggedDictBuilder, UntaggedValue, Value};
|
||||
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
|
||||
use nu_source::Tag;
|
||||
|
||||
pub fn nu(scope: &Scope, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||
pub fn nu(env: &IndexMap<String, String>, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
|
||||
let mut nu_dict = TaggedDictBuilder::new(&tag);
|
||||
|
||||
let mut dict = TaggedDictBuilder::new(&tag);
|
||||
for v in scope.env.iter() {
|
||||
for v in env.iter() {
|
||||
if v.0 != "PATH" && v.0 != "Path" {
|
||||
dict.insert_untagged(v.0, UntaggedValue::string(v.1));
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ClassifiedBlock;
|
||||
use nu_protocol::{Scope, ShellTypeName, Value};
|
||||
use nu_protocol::{ShellTypeName, Value};
|
||||
|
||||
use crate::commands::classified::block::run_block;
|
||||
use crate::commands::{whole_stream_command, Echo};
|
||||
@ -58,10 +59,17 @@ async fn evaluate_block(
|
||||
let input_stream = InputStream::empty();
|
||||
let env = ctx.get_env();
|
||||
|
||||
Ok(run_block(&block.block, ctx, input_stream, &Scope::env(env))
|
||||
.await?
|
||||
.into_vec()
|
||||
.await)
|
||||
Ok(run_block(
|
||||
&block.block,
|
||||
ctx,
|
||||
input_stream,
|
||||
&Value::nothing(),
|
||||
&IndexMap::new(),
|
||||
&env,
|
||||
)
|
||||
.await?
|
||||
.into_vec()
|
||||
.await)
|
||||
}
|
||||
|
||||
// TODO probably something already available to do this
|
||||
|
@ -102,6 +102,7 @@ pub(crate) use std::future::Future;
|
||||
pub(crate) use std::sync::atomic::AtomicBool;
|
||||
pub(crate) use std::sync::Arc;
|
||||
|
||||
pub(crate) use indexmap::IndexMap;
|
||||
pub(crate) use itertools::Itertools;
|
||||
|
||||
pub trait FromInputStream {
|
||||
|
@ -24,6 +24,6 @@ fn to_row() {
|
||||
"#
|
||||
));
|
||||
|
||||
assert!(actual.out.contains("5"));
|
||||
assert!(actual.out.contains('5'));
|
||||
})
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ fn outputs_zero_with_no_input() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn compute_sum_of_individual_row() -> Result<(), String> {
|
||||
let answers_for_columns = [
|
||||
("cpu", 88.257434),
|
||||
@ -82,6 +84,8 @@ fn compute_sum_of_individual_row() -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
#[allow(clippy::float_cmp)]
|
||||
fn compute_sum_of_table() -> Result<(), String> {
|
||||
let answers_for_columns = [
|
||||
("cpu", 88.257434),
|
||||
|
@ -387,6 +387,10 @@ impl Value {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nothing() -> Value {
|
||||
UntaggedValue::nothing().into_untagged_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Value {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::value::{Primitive, UntaggedValue, Value};
|
||||
use crate::value::Value;
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
@ -13,69 +13,19 @@ pub struct Scope {
|
||||
pub env: IndexMap<String, String>,
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
/// Create a new scope
|
||||
pub fn new(it: Value) -> Scope {
|
||||
Scope {
|
||||
it,
|
||||
vars: IndexMap::new(),
|
||||
env: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
/// Create an empty scope
|
||||
pub fn empty() -> Scope {
|
||||
pub fn new() -> Scope {
|
||||
Scope {
|
||||
it: UntaggedValue::Primitive(Primitive::Nothing).into_untagged_value(),
|
||||
it: Value::nothing(),
|
||||
vars: IndexMap::new(),
|
||||
env: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an empty scope, setting $it to a known Value
|
||||
pub fn it_value(value: Value) -> Scope {
|
||||
Scope {
|
||||
it: value,
|
||||
vars: IndexMap::new(),
|
||||
env: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env(env: IndexMap<String, String>) -> Scope {
|
||||
Scope {
|
||||
it: UntaggedValue::Primitive(Primitive::Nothing).into_untagged_value(),
|
||||
vars: IndexMap::new(),
|
||||
env,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_it(self, value: Value) -> Scope {
|
||||
Scope {
|
||||
it: value,
|
||||
vars: self.vars,
|
||||
env: self.env,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_var(self, name: String, value: Value) -> Scope {
|
||||
let mut new_vars = self.vars.clone();
|
||||
new_vars.insert(name, value);
|
||||
Scope {
|
||||
it: self.it,
|
||||
vars: new_vars,
|
||||
env: self.env,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_env_var(self, variable: String, value: String) -> Scope {
|
||||
let mut new_env_vars = self.env.clone();
|
||||
new_env_vars.insert(variable, value);
|
||||
Scope {
|
||||
it: self.it,
|
||||
vars: self.vars,
|
||||
env: new_env_vars,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Scope {
|
||||
fn default() -> Scope {
|
||||
Scope::new()
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +267,7 @@ mod integration {
|
||||
Ok(())
|
||||
}
|
||||
#[test]
|
||||
#[allow(clippy::approx_constant)]
|
||||
fn converts_the_input_to_float_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(
|
||||
|
@ -294,6 +294,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::approx_constant)]
|
||||
fn converts_to_float() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut strutils = Str::new();
|
||||
strutils.for_to_float();
|
||||
|
Loading…
Reference in New Issue
Block a user