allow update to use metadata (#10264)

# Description

This PR is an attempt to fix the `update` command so that it passes
along metadata. I'm not really sure I did this right, so please feel
free to point out where it's wrong.

The point is to be able to do something like this and have it respect
your LS_COLORS.
```
ls | update modified { format date }
```
### Before

![image](https://github.com/nushell/nushell/assets/343840/fc3eb207-4f6f-42b1-b5a4-87a1fe194399)

### After

![image](https://github.com/nushell/nushell/assets/343840/19d58443-7c88-4dd6-9532-1f45f615ac7b)


# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# 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` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# 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.
-->
This commit is contained in:
Darren Schroeder 2023-09-09 13:47:42 -05:00 committed by GitHub
parent 7907dda8f7
commit 40eca52ed5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -116,6 +116,10 @@ fn update(
let engine_state = engine_state.clone(); let engine_state = engine_state.clone();
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
// Let's capture the metadata for ls_colors
let metadata = input.metadata();
let mdclone = metadata.clone();
// Replace is a block, so set it up and run it instead of using it as the replacement // Replace is a block, so set it up and run it instead of using it as the replacement
if replacement.as_block().is_ok() { if replacement.as_block().is_ok() {
let capture_block: Closure = FromValue::from_value(&replacement)?; let capture_block: Closure = FromValue::from_value(&replacement)?;
@ -125,7 +129,8 @@ fn update(
let orig_env_vars = stack.env_vars.clone(); let orig_env_vars = stack.env_vars.clone();
let orig_env_hidden = stack.env_hidden.clone(); let orig_env_hidden = stack.env_hidden.clone();
input.map( Ok(input
.map(
move |mut input| { move |mut input| {
// with_env() is used here to ensure that each iteration uses // with_env() is used here to ensure that each iteration uses
// a different set of environment variables. // a different set of environment variables.
@ -138,8 +143,8 @@ fn update(
} }
} }
let input_at_path = match input.clone().follow_cell_path(&cell_path.members, false) let input_at_path =
{ match input.clone().follow_cell_path(&cell_path.members, false) {
Err(e) => return Value::error(e, span), Err(e) => return Value::error(e, span),
Ok(v) => v, Ok(v) => v,
}; };
@ -147,15 +152,15 @@ fn update(
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
input_at_path.into_pipeline_data(), input_at_path.into_pipeline_data_with_metadata(metadata.clone()),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
); );
match output { match output {
Ok(pd) => { Ok(pd) => {
if let Err(e) = if let Err(e) = input
input.update_data_at_cell_path(&cell_path.members, pd.into_value(span)) .update_data_at_cell_path(&cell_path.members, pd.into_value(span))
{ {
return Value::error(e, span); return Value::error(e, span);
} }
@ -166,7 +171,8 @@ fn update(
} }
}, },
ctrlc, ctrlc,
) )?
.set_metadata(mdclone))
} else { } else {
if let Some(PathMember::Int { val, span, .. }) = cell_path.members.get(0) { if let Some(PathMember::Int { val, span, .. }) = cell_path.members.get(0) {
let mut input = input.into_iter(); let mut input = input.into_iter();
@ -192,20 +198,23 @@ fn update(
.into_iter() .into_iter()
.chain(vec![replacement]) .chain(vec![replacement])
.chain(input) .chain(input)
.into_pipeline_data(ctrlc)); .into_pipeline_data_with_metadata(metadata, ctrlc));
} }
input.map( Ok(input
.map(
move |mut input| { move |mut input| {
let replacement = replacement.clone(); let replacement = replacement.clone();
if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement) { if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement)
{
return Value::error(e, span); return Value::error(e, span);
} }
input input
}, },
ctrlc, ctrlc,
) )?
.set_metadata(metadata))
} }
} }