mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 14:40:06 +02:00
Fix external redirect (#3345)
* Fix external redirection * Fix external redirection
This commit is contained in:
@ -5,7 +5,10 @@ use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::{Block, CapturedBlock, ClassifiedCommand, Group, InternalCommand, Pipeline},
|
||||
hir::{
|
||||
Block, CapturedBlock, ClassifiedCommand, ExternalRedirection, Group, InternalCommand,
|
||||
Pipeline,
|
||||
},
|
||||
Dictionary, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use rand::{
|
||||
@ -84,7 +87,12 @@ fn benchmark(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
// let start = time();
|
||||
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
&context,
|
||||
input,
|
||||
ExternalRedirection::StdoutAndStderr,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
let output = result?.into_vec();
|
||||
|
||||
@ -154,7 +162,12 @@ where
|
||||
let time_block = add_implicit_autoview(time_block.block);
|
||||
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&time_block, context, benchmark_output);
|
||||
let result = run_block(
|
||||
&time_block,
|
||||
context,
|
||||
benchmark_output,
|
||||
ExternalRedirection::StdoutAndStderr,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
result?;
|
||||
context.clear_errors();
|
||||
|
@ -58,7 +58,7 @@ fn do_(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (
|
||||
DoArgs {
|
||||
ignore_errors,
|
||||
mut block,
|
||||
block,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process()?;
|
||||
@ -81,11 +81,8 @@ fn do_(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
x => x,
|
||||
};
|
||||
|
||||
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
|
||||
block.set_redirect(block_redirection);
|
||||
}
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(&block.block, &context, input, block_redirection);
|
||||
context.scope.exit_scope();
|
||||
|
||||
if ignore_errors {
|
||||
|
@ -4,7 +4,8 @@ use nu_engine::WholeStreamCommand;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||
hir::{CapturedBlock, ExternalRedirection},
|
||||
Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
pub struct Each;
|
||||
@ -62,6 +63,7 @@ pub fn process_row(
|
||||
captured_block: Arc<Box<CapturedBlock>>,
|
||||
context: Arc<EvaluationContext>,
|
||||
input: Value,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let input_clone = input.clone();
|
||||
// When we process a row, we need to know whether the block wants to have the contents of the row as
|
||||
@ -86,7 +88,12 @@ pub fn process_row(
|
||||
context.scope.add_var("$it", input);
|
||||
}
|
||||
|
||||
let result = run_block(&captured_block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&captured_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
external_redirection,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
@ -103,6 +110,7 @@ pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
||||
|
||||
fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let args = raw_args.evaluate_once()?;
|
||||
|
||||
let block: CapturedBlock = args.req(0)?;
|
||||
@ -119,7 +127,7 @@ fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let context = context.clone();
|
||||
let row = make_indexed_item(input.0, input.1);
|
||||
|
||||
match process_row(block, context, row) {
|
||||
match process_row(block, context, row, external_redirection) {
|
||||
Ok(s) => s,
|
||||
Err(e) => OutputStream::one(Value::error(e)),
|
||||
}
|
||||
@ -133,7 +141,7 @@ fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let block = block.clone();
|
||||
let context = context.clone();
|
||||
|
||||
match process_row(block, context, input) {
|
||||
match process_row(block, context, input, external_redirection) {
|
||||
Ok(s) => s,
|
||||
Err(e) => OutputStream::one(Value::error(e)),
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ use crate::commands::each::process_row;
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{hir::CapturedBlock, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
hir::{CapturedBlock, ExternalRedirection},
|
||||
Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
use serde::Deserialize;
|
||||
|
||||
@ -44,6 +47,7 @@ impl WholeStreamCommand for EachGroup {
|
||||
|
||||
fn run_with_actions(&self, raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let (each_args, input): (EachGroupArgs, _) = raw_args.process()?;
|
||||
let block = Arc::new(Box::new(each_args.block));
|
||||
|
||||
@ -52,6 +56,7 @@ impl WholeStreamCommand for EachGroup {
|
||||
context,
|
||||
group_size: each_args.group_size.item,
|
||||
input,
|
||||
external_redirection,
|
||||
};
|
||||
|
||||
Ok(each_group_iterator.flatten().to_action_stream())
|
||||
@ -63,6 +68,7 @@ struct EachGroupIterator {
|
||||
context: Arc<EvaluationContext>,
|
||||
group_size: usize,
|
||||
input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
}
|
||||
|
||||
impl Iterator for EachGroupIterator {
|
||||
@ -89,6 +95,7 @@ impl Iterator for EachGroupIterator {
|
||||
group,
|
||||
self.block.clone(),
|
||||
self.context.clone(),
|
||||
self.external_redirection,
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -97,13 +104,14 @@ pub(crate) fn run_block_on_vec(
|
||||
input: Vec<Value>,
|
||||
block: Arc<Box<CapturedBlock>>,
|
||||
context: Arc<EvaluationContext>,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> OutputStream {
|
||||
let value = Value {
|
||||
value: UntaggedValue::Table(input),
|
||||
tag: Tag::unknown(),
|
||||
};
|
||||
|
||||
match process_row(block, context, value) {
|
||||
match process_row(block, context, value, external_redirection) {
|
||||
Ok(s) => {
|
||||
// We need to handle this differently depending on whether process_row
|
||||
// returned just 1 value or if it returned multiple as a stream.
|
||||
|
@ -51,6 +51,7 @@ impl WholeStreamCommand for EachWindow {
|
||||
|
||||
fn run_with_actions(&self, raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process()?;
|
||||
let block = Arc::new(Box::new(each_args.block));
|
||||
|
||||
@ -76,7 +77,12 @@ impl WholeStreamCommand for EachWindow {
|
||||
let local_window = window.clone();
|
||||
|
||||
if i % stride == 0 {
|
||||
Some(run_block_on_vec(local_window, block, context))
|
||||
Some(run_block_on_vec(
|
||||
local_window,
|
||||
block,
|
||||
context,
|
||||
external_redirection,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape,
|
||||
UntaggedValue, Value,
|
||||
hir::CapturedBlock, hir::ExternalRedirection, ColumnPath, Primitive, ReturnSuccess, Signature,
|
||||
SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
use crate::utils::arguments::arguments;
|
||||
@ -142,7 +142,12 @@ fn process_row(
|
||||
context.scope.add_vars(&default_block.captured.entries);
|
||||
context.scope.add_var("$it", input.clone());
|
||||
|
||||
let stream = run_block(&default_block.block, &*context, input_stream);
|
||||
let stream = run_block(
|
||||
&default_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
let mut stream = stream?;
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use crate::utils::suggestions::suggestions;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
use nu_value_ext::as_string;
|
||||
@ -148,7 +149,12 @@ pub fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let run = block.clone();
|
||||
let context = context.clone();
|
||||
|
||||
match crate::commands::each::process_row(run, context, value.clone()) {
|
||||
match crate::commands::each::process_row(
|
||||
run,
|
||||
context,
|
||||
value.clone(),
|
||||
ExternalRedirection::Stdout,
|
||||
) {
|
||||
Ok(mut s) => {
|
||||
let collection: Vec<Value> = s.drain_vec();
|
||||
|
||||
|
@ -59,6 +59,7 @@ impl WholeStreamCommand for If {
|
||||
}
|
||||
fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
|
||||
let args = raw_args.evaluate_once()?;
|
||||
@ -105,9 +106,9 @@ fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => {
|
||||
let result = if b {
|
||||
run_block(&then_case.block, &*context, input)
|
||||
run_block(&then_case.block, &*context, input, external_redirection)
|
||||
} else {
|
||||
run_block(&else_case.block, &*context, input)
|
||||
run_block(&else_case.block, &*context, input, external_redirection)
|
||||
};
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
@ -81,7 +82,12 @@ fn process_row(
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
context.scope.add_var("$it", input.clone());
|
||||
|
||||
let result = run_block(&block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
@ -6,7 +6,8 @@ use nu_engine::WholeStreamCommand;
|
||||
use indexmap::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
hir::CapturedBlock, hir::ExternalRedirection, ReturnSuccess, Signature, SyntaxShape,
|
||||
UntaggedValue, Value,
|
||||
};
|
||||
pub struct Merge;
|
||||
|
||||
@ -53,7 +54,12 @@ fn merge(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
|
||||
context.scope.enter_scope();
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
let result = run_block(&block.block, &context, InputStream::empty());
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
&context,
|
||||
InputStream::empty(),
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
let table: Option<Vec<Value>> = match result {
|
||||
|
@ -5,7 +5,9 @@ use nu_engine::WholeStreamCommand;
|
||||
use nu_engine::{CommandArgs, Example};
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::{hir::CapturedBlock, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, hir::ExternalRedirection, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
use nu_stream::ActionStream;
|
||||
|
||||
@ -88,7 +90,12 @@ fn process_row(
|
||||
context.scope.enter_scope();
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
context.scope.add_var("$it", row);
|
||||
let result = run_block(&block.block, context, input_stream);
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
result
|
||||
|
@ -12,9 +12,6 @@ use nu_protocol::hir::{Expression, ExternalArgs, ExternalCommand, Literal, Spann
|
||||
use nu_protocol::{Signature, SyntaxShape};
|
||||
use nu_source::Tagged;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RunExternalArgs {}
|
||||
|
||||
#[derive(new)]
|
||||
pub struct RunExternalCommand {
|
||||
/// Whether or not nushell is being used in an interactive context
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
@ -86,7 +87,12 @@ fn process_row(
|
||||
context.scope.add_var("$it", input.clone());
|
||||
context.scope.add_vars(&captured_block.captured.entries);
|
||||
|
||||
let result = run_block(&captured_block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&captured_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
@ -68,19 +68,9 @@ impl WholeStreamCommand for WithEnv {
|
||||
}
|
||||
|
||||
fn with_env(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let redirection = raw_args.call_info.args.external_redirection;
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let context = EvaluationContext::from_args(&raw_args);
|
||||
let (
|
||||
WithEnvArgs {
|
||||
variable,
|
||||
mut block,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process()?;
|
||||
|
||||
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
|
||||
block.set_redirect(redirection);
|
||||
}
|
||||
let (WithEnvArgs { variable, block }, input) = raw_args.process()?;
|
||||
|
||||
let mut env = IndexMap::new();
|
||||
|
||||
@ -118,7 +108,7 @@ fn with_env(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
context.scope.add_env(env);
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(&block.block, &context, input, external_redirection);
|
||||
context.scope.exit_scope();
|
||||
|
||||
result.map(|x| x.to_action_stream())
|
||||
|
@ -11,7 +11,7 @@ use stub_generate::{mock_path, Command as StubOpen};
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::hir::ClassifiedBlock;
|
||||
use nu_protocol::hir::{ClassifiedBlock, ExternalRedirection};
|
||||
use nu_protocol::{ShellTypeName, Value};
|
||||
use nu_source::AnchorLocation;
|
||||
|
||||
@ -231,7 +231,7 @@ fn evaluate_block(
|
||||
|
||||
ctx.scope.enter_scope();
|
||||
|
||||
let result = run_block(&block.block, ctx, input_stream);
|
||||
let result = run_block(&block.block, ctx, input_stream, ExternalRedirection::Stdout);
|
||||
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
|
Reference in New Issue
Block a user