forked from extern/nushell
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:
parent
7907dda8f7
commit
40eca52ed5
@ -116,6 +116,10 @@ fn update(
|
||||
let engine_state = engine_state.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
|
||||
if replacement.as_block().is_ok() {
|
||||
let capture_block: Closure = FromValue::from_value(&replacement)?;
|
||||
@ -125,48 +129,50 @@ fn update(
|
||||
let orig_env_vars = stack.env_vars.clone();
|
||||
let orig_env_hidden = stack.env_hidden.clone();
|
||||
|
||||
input.map(
|
||||
move |mut input| {
|
||||
// with_env() is used here to ensure that each iteration uses
|
||||
// a different set of environment variables.
|
||||
// Hence, a 'cd' in the first loop won't affect the next loop.
|
||||
stack.with_env(&orig_env_vars, &orig_env_hidden);
|
||||
Ok(input
|
||||
.map(
|
||||
move |mut input| {
|
||||
// with_env() is used here to ensure that each iteration uses
|
||||
// a different set of environment variables.
|
||||
// Hence, a 'cd' in the first loop won't affect the next loop.
|
||||
stack.with_env(&orig_env_vars, &orig_env_hidden);
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
stack.add_var(*var_id, input.clone())
|
||||
}
|
||||
}
|
||||
|
||||
let input_at_path = match input.clone().follow_cell_path(&cell_path.members, false)
|
||||
{
|
||||
Err(e) => return Value::error(e, span),
|
||||
Ok(v) => v,
|
||||
};
|
||||
let output = eval_block(
|
||||
&engine_state,
|
||||
&mut stack,
|
||||
&block,
|
||||
input_at_path.into_pipeline_data(),
|
||||
redirect_stdout,
|
||||
redirect_stderr,
|
||||
);
|
||||
|
||||
match output {
|
||||
Ok(pd) => {
|
||||
if let Err(e) =
|
||||
input.update_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
||||
{
|
||||
return Value::error(e, span);
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
stack.add_var(*var_id, input.clone())
|
||||
}
|
||||
|
||||
input
|
||||
}
|
||||
Err(e) => Value::error(e, span),
|
||||
}
|
||||
},
|
||||
ctrlc,
|
||||
)
|
||||
|
||||
let input_at_path =
|
||||
match input.clone().follow_cell_path(&cell_path.members, false) {
|
||||
Err(e) => return Value::error(e, span),
|
||||
Ok(v) => v,
|
||||
};
|
||||
let output = eval_block(
|
||||
&engine_state,
|
||||
&mut stack,
|
||||
&block,
|
||||
input_at_path.into_pipeline_data_with_metadata(metadata.clone()),
|
||||
redirect_stdout,
|
||||
redirect_stderr,
|
||||
);
|
||||
|
||||
match output {
|
||||
Ok(pd) => {
|
||||
if let Err(e) = input
|
||||
.update_data_at_cell_path(&cell_path.members, pd.into_value(span))
|
||||
{
|
||||
return Value::error(e, span);
|
||||
}
|
||||
|
||||
input
|
||||
}
|
||||
Err(e) => Value::error(e, span),
|
||||
}
|
||||
},
|
||||
ctrlc,
|
||||
)?
|
||||
.set_metadata(mdclone))
|
||||
} else {
|
||||
if let Some(PathMember::Int { val, span, .. }) = cell_path.members.get(0) {
|
||||
let mut input = input.into_iter();
|
||||
@ -192,20 +198,23 @@ fn update(
|
||||
.into_iter()
|
||||
.chain(vec![replacement])
|
||||
.chain(input)
|
||||
.into_pipeline_data(ctrlc));
|
||||
.into_pipeline_data_with_metadata(metadata, ctrlc));
|
||||
}
|
||||
input.map(
|
||||
move |mut input| {
|
||||
let replacement = replacement.clone();
|
||||
Ok(input
|
||||
.map(
|
||||
move |mut input| {
|
||||
let replacement = replacement.clone();
|
||||
|
||||
if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement) {
|
||||
return Value::error(e, span);
|
||||
}
|
||||
if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement)
|
||||
{
|
||||
return Value::error(e, span);
|
||||
}
|
||||
|
||||
input
|
||||
},
|
||||
ctrlc,
|
||||
)
|
||||
input
|
||||
},
|
||||
ctrlc,
|
||||
)?
|
||||
.set_metadata(metadata))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user