mirror of
https://github.com/nushell/nushell
synced 2025-01-14 06:04:09 +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) => {
|
Ok(pipeline) => {
|
||||||
let exit_code = pipeline.print(&engine_state, stack, false, false)?;
|
let exit_code = pipeline.print(&engine_state, stack, false, false)?;
|
||||||
if exit_code != 0 {
|
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) => {
|
Ok(pipeline) => {
|
||||||
let exit_code = pipeline.drain_with_exit_code()?;
|
let exit_code = pipeline.drain_with_exit_code()?;
|
||||||
if exit_code != 0 {
|
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) => {
|
Ok(pipeline) => {
|
||||||
let exit_code = pipeline.drain_with_exit_code()?;
|
let exit_code = pipeline.drain_with_exit_code()?;
|
||||||
if exit_code != 0 {
|
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) => {
|
Ok(pipeline) => {
|
||||||
let exit_code = pipeline.drain_with_exit_code()?;
|
let exit_code = pipeline.drain_with_exit_code()?;
|
||||||
if exit_code != 0 {
|
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`
|
// so our output will be `1`
|
||||||
assert_eq!(actual.out, "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`.
|
// so our output will be `1`.
|
||||||
assert_eq!(actual.out, "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`
|
// so our output will be `1`
|
||||||
assert_eq!(actual.out, "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)
|
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 {
|
pub fn empty() -> PipelineData {
|
||||||
PipelineData::Empty
|
PipelineData::Empty
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue