From db3177a5aa5cf8a4c712fc17ef1407dd1e4f883e Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Wed, 14 Dec 2022 23:20:18 +0800 Subject: [PATCH] break `for`, `loop`, `while` execution when external command runs to failed (#7475) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: #7467 # User-Facing Changes ## for ``` ❯ for i in 1..2 { echo 1; ^false } 1 ``` ## loop ``` ❯ loop { echo bb; ^false } bb ``` ## while ``` ❯ mut x = 1; while $x < 3 { $x = $x + 1; echo bb; ^false } bb ``` --- crates/nu-command/src/core_commands/for_.rs | 10 +++++++-- crates/nu-command/src/core_commands/loop_.rs | 5 ++++- crates/nu-command/src/core_commands/while_.rs | 6 +++++- crates/nu-command/tests/commands/for_.rs | 15 +++++++++++++ crates/nu-command/tests/commands/loop_.rs | 21 +++++++++++++++++++ crates/nu-command/tests/commands/while_.rs | 11 ++++++++++ 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/crates/nu-command/src/core_commands/for_.rs b/crates/nu-command/src/core_commands/for_.rs index 3889d9ec7c..c56fd1fca6 100644 --- a/crates/nu-command/src/core_commands/for_.rs +++ b/crates/nu-command/src/core_commands/for_.rs @@ -118,7 +118,10 @@ impl Command for For { return Err(err); } Ok(pipeline) => { - let _ = pipeline.print(&engine_state, stack, false, false)?; + let exit_code = pipeline.print(&engine_state, stack, false, false)?; + if exit_code != 0 { + break; + } } } } @@ -157,7 +160,10 @@ impl Command for For { return Err(err); } Ok(pipeline) => { - let _ = pipeline.print(&engine_state, stack, false, false)?; + let exit_code = pipeline.print(&engine_state, stack, false, false)?; + if exit_code != 0 { + break; + } } } } diff --git a/crates/nu-command/src/core_commands/loop_.rs b/crates/nu-command/src/core_commands/loop_.rs index 3ca8188f71..1b4befd871 100644 --- a/crates/nu-command/src/core_commands/loop_.rs +++ b/crates/nu-command/src/core_commands/loop_.rs @@ -69,7 +69,10 @@ impl Command for Loop { return Err(err); } Ok(pipeline) => { - let _ = pipeline.print(engine_state, stack, false, false)?; + let exit_code = pipeline.print(engine_state, stack, false, false)?; + if exit_code != 0 { + break; + } } } } diff --git a/crates/nu-command/src/core_commands/while_.rs b/crates/nu-command/src/core_commands/while_.rs index eb4237a85c..57b4da9b4c 100644 --- a/crates/nu-command/src/core_commands/while_.rs +++ b/crates/nu-command/src/core_commands/while_.rs @@ -77,7 +77,11 @@ impl Command for While { return Err(err); } Ok(pipeline) => { - let _ = pipeline.print(engine_state, stack, false, false)?; + let exit_code = + pipeline.print(engine_state, stack, false, false)?; + if exit_code != 0 { + break; + } } } } else { diff --git a/crates/nu-command/tests/commands/for_.rs b/crates/nu-command/tests/commands/for_.rs index 0e480db355..2a6e3ca83f 100644 --- a/crates/nu-command/tests/commands/for_.rs +++ b/crates/nu-command/tests/commands/for_.rs @@ -14,3 +14,18 @@ fn for_auto_print_in_each_iteration() { // that's ok, our main concern is it auto print value in each iteration. assert_eq!(actual.out, "11"); } + +#[test] +fn for_break_on_external_failed() { + let actual = nu!( + cwd: ".", + r#" + for i in 1..2 { + echo 1; + nu --testbin fail + }"# + ); + // Note: nu! macro auto repalce "\n" and "\r\n" with "" + // so our output will be `1` + assert_eq!(actual.out, "1"); +} diff --git a/crates/nu-command/tests/commands/loop_.rs b/crates/nu-command/tests/commands/loop_.rs index fef9ce78a2..c61ad6cf78 100644 --- a/crates/nu-command/tests/commands/loop_.rs +++ b/crates/nu-command/tests/commands/loop_.rs @@ -20,3 +20,24 @@ fn loop_auto_print_in_each_iteration() { // that's ok, our main concern is it auto print value in each iteration. assert_eq!(actual.out, "111"); } + +#[test] +fn loop_break_on_external_failed() { + let actual = nu!( + cwd: ".", + r#" + mut total = 0; + loop { + if $total == 3 { + break; + } else { + $total += 1; + } + echo 1; + nu --testbin fail; + }"# + ); + // Note: nu! macro auto repalce "\n" and "\r\n" with "" + // so our output will be `1`. + assert_eq!(actual.out, "1"); +} diff --git a/crates/nu-command/tests/commands/while_.rs b/crates/nu-command/tests/commands/while_.rs index 77b430ec56..66556f45e1 100644 --- a/crates/nu-command/tests/commands/while_.rs +++ b/crates/nu-command/tests/commands/while_.rs @@ -21,3 +21,14 @@ fn while_auto_print_in_each_iteration() { // that's ok, our main concern is it auto print value in each iteration. assert_eq!(actual.out, "11"); } + +#[test] +fn while_break_on_external_failed() { + let actual = nu!( + cwd: ".", + "mut total = 0; while $total < 2 { $total = $total + 1; echo 1; nu --testbin fail }" + ); + // Note: nu! macro auto repalce "\n" and "\r\n" with "" + // so our output will be `1` + assert_eq!(actual.out, "1"); +}