mirror of
https://github.com/nushell/nushell
synced 2025-01-13 21:55:07 +00:00
Loops return external stream when external command failed. (#8646)
This commit is contained in:
parent
1fcb98289a
commit
54a18991ab
7 changed files with 83 additions and 4 deletions
|
@ -122,7 +122,9 @@ impl Command for For {
|
|||
Ok(pipeline) => {
|
||||
let exit_code = pipeline.print(&engine_state, stack, false, false)?;
|
||||
if exit_code != 0 {
|
||||
break;
|
||||
return Ok(PipelineData::new_external_stream_with_only_exit_code(
|
||||
exit_code,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +166,9 @@ impl Command for For {
|
|||
Ok(pipeline) => {
|
||||
let exit_code = pipeline.drain_with_exit_code()?;
|
||||
if exit_code != 0 {
|
||||
break;
|
||||
return Ok(PipelineData::new_external_stream_with_only_exit_code(
|
||||
exit_code,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,9 @@ impl Command for Loop {
|
|||
Ok(pipeline) => {
|
||||
let exit_code = pipeline.drain_with_exit_code()?;
|
||||
if exit_code != 0 {
|
||||
break;
|
||||
return Ok(PipelineData::new_external_stream_with_only_exit_code(
|
||||
exit_code,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,11 @@ impl Command for While {
|
|||
Ok(pipeline) => {
|
||||
let exit_code = pipeline.drain_with_exit_code()?;
|
||||
if exit_code != 0 {
|
||||
break;
|
||||
return Ok(
|
||||
PipelineData::new_external_stream_with_only_exit_code(
|
||||
exit_code,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,3 +28,27 @@ fn for_break_on_external_failed() {
|
|||
// so our output will be `1`
|
||||
assert_eq!(actual.out, "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_for_should_break_running() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
for i in 1..2 {
|
||||
nu --testbin fail
|
||||
}
|
||||
print 3"#
|
||||
);
|
||||
assert!(!actual.out.contains('3'));
|
||||
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
let x = [1 2]
|
||||
for i in $x {
|
||||
nu --testbin fail
|
||||
}
|
||||
print 3"#
|
||||
);
|
||||
assert!(!actual.out.contains('3'));
|
||||
}
|
||||
|
|
|
@ -40,3 +40,22 @@ fn loop_break_on_external_failed() {
|
|||
// so our output will be `1`.
|
||||
assert_eq!(actual.out, "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_loop_should_break_running() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
mut total = 0;
|
||||
loop {
|
||||
if $total == 3 {
|
||||
break;
|
||||
} else {
|
||||
$total += 1;
|
||||
}
|
||||
nu --testbin fail;
|
||||
}
|
||||
print 3"#
|
||||
);
|
||||
assert!(!actual.out.contains('3'));
|
||||
}
|
||||
|
|
|
@ -31,3 +31,12 @@ fn while_break_on_external_failed() {
|
|||
// so our output will be `1`
|
||||
assert_eq!(actual.out, "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_while_should_break_running() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
"mut total = 0; while $total < 2 { $total = $total + 1; nu --testbin fail }; print 3"
|
||||
);
|
||||
assert!(!actual.out.contains('3'));
|
||||
}
|
||||
|
|
|
@ -72,6 +72,23 @@ impl PipelineData {
|
|||
PipelineData::Value(Value::Nothing { span }, metadata)
|
||||
}
|
||||
|
||||
/// create a `PipelineData::ExternalStream` with proper exit_code
|
||||
///
|
||||
/// It's useful to break running without raising error at user level.
|
||||
pub fn new_external_stream_with_only_exit_code(exit_code: i64) -> PipelineData {
|
||||
PipelineData::ExternalStream {
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
exit_code: Some(ListStream::from_stream(
|
||||
[Value::int(exit_code, Span::unknown())].into_iter(),
|
||||
None,
|
||||
)),
|
||||
span: Span::unknown(),
|
||||
metadata: None,
|
||||
trim_end_newline: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> PipelineData {
|
||||
PipelineData::Empty
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue