From 1b2916988ef22bb69d8df90e0108cc75e2bff24c Mon Sep 17 00:00:00 2001 From: Reilly Wood <26268125+rgwood@users.noreply.github.com> Date: Thu, 16 Mar 2023 11:50:04 -0700 Subject: [PATCH] Add `-i` flag back to `get` and `select` (#8488) https://github.com/nushell/nushell/pull/8379 removed the `-i` flag from `get` and `select` because the new `?` functionality covers most of the same use cases. However, https://github.com/nushell/nushell/issues/8480 made me realize that `-i` is still useful when dealing with cell paths in variables. This PR re-adds the `-i` flag to `get` and `select`. It works by just marking every member in the cell path as optional, which will behave _slightly_ differently than `-i` used to (previously it would suppress any errors, even type errors) but IMO that's OK. --- crates/nu-command/src/filters/get.rs | 12 +++++++++++- crates/nu-command/src/filters/select.rs | 14 +++++++++++++- crates/nu-command/tests/commands/get.rs | 13 +++++++++++++ crates/nu-command/tests/commands/select.rs | 13 +++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 50f9d5e140..1a5be9fb96 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -41,6 +41,11 @@ If multiple cell paths are given, this will produce a list of values."# "the cell path to the data", ) .rest("rest", SyntaxShape::CellPath, "additional cell paths") + .switch( + "ignore-errors", + "ignore missing data (make all cell path members optional)", + Some('i'), + ) .switch( "sensitive", "get path in a case sensitive manner", @@ -57,12 +62,17 @@ If multiple cell paths are given, this will produce a list of values."# input: PipelineData, ) -> Result { let span = call.head; - let cell_path: CellPath = call.req(engine_state, stack, 0)?; + let mut cell_path: CellPath = call.req(engine_state, stack, 0)?; let rest: Vec = call.rest(engine_state, stack, 1)?; + let ignore_errors = call.has_flag("ignore-errors"); let sensitive = call.has_flag("sensitive"); let ctrlc = engine_state.ctrlc.clone(); let metadata = input.metadata(); + if ignore_errors { + cell_path.make_optional(); + } + if rest.is_empty() { input .follow_cell_path(&cell_path.members, call.head, !sensitive) diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index 8e91cb9ae3..6084771f1f 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -22,6 +22,11 @@ impl Command for Select { (Type::Record(vec![]), Type::Record(vec![])), (Type::Table(vec![]), Type::Table(vec![])), ]) + .switch( + "ignore-errors", + "ignore missing data (make all cell path members optional)", + Some('i'), + ) .rest( "rest", SyntaxShape::CellPath, @@ -51,9 +56,16 @@ produce a table, a list will produce a list, and a record will produce a record. call: &Call, input: PipelineData, ) -> Result { - let columns: Vec = call.rest(engine_state, stack, 0)?; + let mut columns: Vec = call.rest(engine_state, stack, 0)?; + let ignore_errors = call.has_flag("ignore-errors"); let span = call.head; + if ignore_errors { + for cell_path in &mut columns { + cell_path.make_optional(); + } + } + select(engine_state, span, columns, input) } diff --git a/crates/nu-command/tests/commands/get.rs b/crates/nu-command/tests/commands/get.rs index a1a3f9c0e7..dea8e64336 100644 --- a/crates/nu-command/tests/commands/get.rs +++ b/crates/nu-command/tests/commands/get.rs @@ -241,3 +241,16 @@ fn get_does_not_delve_too_deep_in_nested_lists() { assert!(actual.err.contains("cannot find column")); } + +#[test] +fn ignore_errors_works() { + let actual = nu!( + cwd: ".", + r#" + let path = "foo"; + {} | get -i $path | to nuon + "# + ); + + assert_eq!(actual.out, "null"); +} diff --git a/crates/nu-command/tests/commands/select.rs b/crates/nu-command/tests/commands/select.rs index f72a131439..02a606364d 100644 --- a/crates/nu-command/tests/commands/select.rs +++ b/crates/nu-command/tests/commands/select.rs @@ -256,3 +256,16 @@ fn select_failed4() { assert!(actual.err.contains("Select can't get the same row twice")); } + +#[test] +fn ignore_errors_works() { + let actual = nu!( + cwd: ".", + r#" + let path = "foo"; + [{}] | select -i $path | to nuon + "# + ); + + assert_eq!(actual.out, "[[foo]; [null]]"); +}