mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
Fix non-zero exit code errors in middle of pipeline (#13899)
# Description Fixes #13868. Should come after #13885. # User-Facing Changes Bug fix. # Tests + Formatting Added a test.
This commit is contained in:
parent
475aa4f1dd
commit
f03ba6793e
7 changed files with 37 additions and 8 deletions
|
@ -1,4 +1,5 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::ByteStreamSource;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Print;
|
||||
|
@ -50,7 +51,7 @@ Since this command has no output, there is no point in piping it with other comm
|
|||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
mut input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let args: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let no_newline = call.has_flag(engine_state, stack, "no-newline")?;
|
||||
|
@ -69,6 +70,11 @@ Since this command has no output, there is no point in piping it with other comm
|
|||
}
|
||||
}
|
||||
} else if !input.is_nothing() {
|
||||
if let PipelineData::ByteStream(stream, _) = &mut input {
|
||||
if let ByteStreamSource::Child(child) = stream.source_mut() {
|
||||
child.ignore_error(true);
|
||||
}
|
||||
}
|
||||
if raw {
|
||||
input.print_raw(engine_state, no_newline, to_stderr)?;
|
||||
} else {
|
||||
|
|
|
@ -147,6 +147,7 @@ impl Command for Do {
|
|||
None
|
||||
};
|
||||
|
||||
child.ignore_error(false);
|
||||
child.wait()?;
|
||||
|
||||
let mut child = ChildProcess::from_raw(None, None, None, span);
|
||||
|
@ -172,7 +173,7 @@ impl Command for Do {
|
|||
) =>
|
||||
{
|
||||
if let ByteStreamSource::Child(child) = stream.source_mut() {
|
||||
child.ignore_error();
|
||||
child.ignore_error(true);
|
||||
}
|
||||
Ok(PipelineData::ByteStream(stream, metadata))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::{engine::StateWorkingSet, OutDest};
|
||||
use nu_protocol::{engine::StateWorkingSet, ByteStreamSource, OutDest};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Ignore;
|
||||
|
@ -32,8 +32,13 @@ impl Command for Ignore {
|
|||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
input: PipelineData,
|
||||
mut input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
if let PipelineData::ByteStream(stream, _) = &mut input {
|
||||
if let ByteStreamSource::Child(child) = stream.source_mut() {
|
||||
child.ignore_error(true);
|
||||
}
|
||||
}
|
||||
input.drain()?;
|
||||
Ok(PipelineData::empty())
|
||||
}
|
||||
|
|
|
@ -182,6 +182,8 @@ impl Command for Save {
|
|||
}
|
||||
(None, None) => {}
|
||||
};
|
||||
|
||||
child.wait()?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,12 +180,19 @@ impl Command for External {
|
|||
}
|
||||
|
||||
// Wrap the output into a `PipelineData::ByteStream`.
|
||||
let child = ChildProcess::new(
|
||||
let mut child = ChildProcess::new(
|
||||
child,
|
||||
merged_stream,
|
||||
matches!(stderr, OutDest::Pipe),
|
||||
call.head,
|
||||
)?;
|
||||
|
||||
if matches!(stdout, OutDest::Pipe | OutDest::PipeSeparate)
|
||||
|| matches!(stderr, OutDest::Pipe | OutDest::PipeSeparate)
|
||||
{
|
||||
child.ignore_error(true);
|
||||
}
|
||||
|
||||
Ok(PipelineData::ByteStream(
|
||||
ByteStream::child(child, call.head),
|
||||
None,
|
||||
|
|
|
@ -202,8 +202,8 @@ impl ChildProcess {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn ignore_error(&mut self) -> &mut Self {
|
||||
self.ignore_error = true;
|
||||
pub fn ignore_error(&mut self, ignore: bool) -> &mut Self {
|
||||
self.ignore_error = ignore;
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,14 @@ use pretty_assertions::assert_eq;
|
|||
#[test]
|
||||
fn doesnt_break_on_utf8() {
|
||||
let actual = nu!("echo ö");
|
||||
|
||||
assert_eq!(actual.out, "ö", "'{}' should contain ö", actual.out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_zero_exit_code_in_middle_of_pipeline_ignored() {
|
||||
let actual = nu!("nu -c 'print a b; exit 42' | collect");
|
||||
assert_eq!(actual.out, "ab");
|
||||
|
||||
let actual = nu!("nu -c 'print a b; exit 42' | nu --stdin -c 'collect'");
|
||||
assert_eq!(actual.out, "ab");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue