From 8f4807020f9053e6fa16d30bc181f6b5c9bb4ff3 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Thu, 2 Feb 2023 07:04:53 +0800 Subject: [PATCH] make do -i works with liststream (#7889) # Description Fixes: #7874 It's because `do -i` doesn't handles `Pipeline::ListStream` data(especially there is Value::Error inside the stream) To fix it, we need to iterate through `ListStream`, check if there is `Value::Error`. If so, just returns `Pipeline::empty()` # User-Facing Changes ``` help commands | find arg | get search_terms | do -i { ansi strip } ``` No longer raises error. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --- crates/nu-command/src/core_commands/do_.rs | 34 +++++++++++++++++----- crates/nu-command/tests/commands/do_.rs | 6 ++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/crates/nu-command/src/core_commands/do_.rs b/crates/nu-command/src/core_commands/do_.rs index 79dfb29c0a..0fa103865b 100644 --- a/crates/nu-command/src/core_commands/do_.rs +++ b/crates/nu-command/src/core_commands/do_.rs @@ -215,17 +215,35 @@ impl Command for Do { span, metadata, trim_end_newline, - }) if ignore_program_errors => Ok(PipelineData::ExternalStream { - stdout, - stderr, - exit_code: None, - span, - metadata, - trim_end_newline, - }), + }) if ignore_program_errors && !call.redirect_stdout => { + Ok(PipelineData::ExternalStream { + stdout, + stderr, + exit_code: None, + span, + metadata, + trim_end_newline, + }) + } Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => { Ok(PipelineData::empty()) } + Ok(PipelineData::ListStream(ls, metadata)) if ignore_shell_errors => { + // check if there is a `Value::Error` in given list stream first. + let mut values = vec![]; + let ctrlc = ls.ctrlc.clone(); + for v in ls { + if let Value::Error { .. } = v { + values.push(Value::nothing(call.head)); + } else { + values.push(v) + } + } + Ok(PipelineData::ListStream( + ListStream::from_stream(values.into_iter(), ctrlc), + metadata, + )) + } r => r, } } diff --git a/crates/nu-command/tests/commands/do_.rs b/crates/nu-command/tests/commands/do_.rs index edb83c647e..c78093c483 100644 --- a/crates/nu-command/tests/commands/do_.rs +++ b/crates/nu-command/tests/commands/do_.rs @@ -187,3 +187,9 @@ fn capture_error_with_both_stdout_stderr_messages_not_hang_nushell() { }, ) } + +#[test] +fn ignore_error_works_with_list_stream() { + let actual = nu!(cwd: ".", pipeline(r#"do -i { ["a", $nothing, "b"] | ansi strip }"#)); + assert!(actual.err.is_empty()); +}