Commit Graph

8573 Commits

Author SHA1 Message Date
Wind
2046912160
remove str escape-glob command (#12241)
This is a follow up to #12018
2024-03-20 14:15:02 +01:00
Devyn Cairns
c810f5e3da
Refactor PluginCustomValue::render_to_base_value_in (#12244)
# Description

Changed to use `Value::recurse_mut` like the other functions.

# User-Facing Changes
None

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-20 17:22:25 +08:00
Devyn Cairns
dcf2e8ce9a
Refactor PipelineDataHeader ⇄ PipelineData mapping (#12248)
# Description
It was a bit ugly that when new `EngineCall`s or response types were
added, they needed to be added to multiple places with redundant code
just to change the types, even if they didn't have any stream content.

This fixes that and locates all of that logic in one place.

# User-Facing Changes
None

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
2024-03-20 16:57:22 +08:00
YizhePKU
f8c1e03ea7
Fix inaccurate sleep duration (#12235)
# Description
Improves the accuracy of sleep when the duration is larger than 100ms.
Fixes #12223.

# User-Facing Changes
Sleeping for 150ms should work now.

```nushell
~/nushell> timeit { sleep 150ms }                                                                                                                                          03/19/2024 10:41:55 AM AM
151ms 344µs 201ns
```
2024-03-20 16:45:33 +08:00
Stefan Holderbach
f56070cbcd
Respond to nightly clippy (#12174)
Babe, wake up new nightly clippy just dropped

- Move `catch_unwind` block out of `match` scrutinee
- Remove unused members in `PluginExecutionContext`
2024-03-20 09:46:39 +08:00
dependabot[bot]
b267a9c1ba
Bump uuid from 1.7.0 to 1.8.0 (#12246)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.7.0 to 1.8.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/uuid-rs/uuid/releases">uuid's
releases</a>.</em></p>
<blockquote>
<h2>1.8.0</h2>
<h2>⚠️ Potential Breakage ⚠️</h2>
<p>A new <code>impl AsRef&lt;Uuid&gt; for Uuid</code> bound has been
added, which can break inference on code like:</p>
<pre lang="rust"><code>let b = uuid.as_ref();
</code></pre>
<p>You can fix these by explicitly typing the result of the
conversion:</p>
<pre lang="rust"><code>let b: &amp;[u8] = uuid.as_ref();
</code></pre>
<p>or by calling <code>as_bytes</code> instead:</p>
<pre lang="rust"><code>let b = uuid.as_bytes();
</code></pre>
<h2>What's Changed</h2>
<ul>
<li>docs: fix small spelling mistake by <a
href="https://github.com/bengsparks"><code>@​bengsparks</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/737">uuid-rs/uuid#737</a></li>
<li>serde serialize_with support by <a
href="https://github.com/dakaizou"><code>@​dakaizou</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/735">uuid-rs/uuid#735</a></li>
<li>Fix up CI builds by <a
href="https://github.com/KodrAus"><code>@​KodrAus</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/744">uuid-rs/uuid#744</a></li>
<li>Only add <code>wasm-bindgen</code> as a dependency on
<code>wasm32-unknown-unknown</code> by <a
href="https://github.com/emilk"><code>@​emilk</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/738">uuid-rs/uuid#738</a></li>
<li>impl AsRef<!-- raw HTML omitted --> for Uuid by <a
href="https://github.com/koshell"><code>@​koshell</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/743">uuid-rs/uuid#743</a></li>
<li>Add v6 to v8 draft link to README by <a
href="https://github.com/KodrAus"><code>@​KodrAus</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/746">uuid-rs/uuid#746</a></li>
<li>Add a workflow for running cargo outdated by <a
href="https://github.com/KodrAus"><code>@​KodrAus</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/745">uuid-rs/uuid#745</a></li>
<li>Prepare for 1.8.0 release by <a
href="https://github.com/KodrAus"><code>@​KodrAus</code></a> in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/747">uuid-rs/uuid#747</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/bengsparks"><code>@​bengsparks</code></a> made
their first contribution in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/737">uuid-rs/uuid#737</a></li>
<li><a href="https://github.com/dakaizou"><code>@​dakaizou</code></a>
made their first contribution in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/735">uuid-rs/uuid#735</a></li>
<li><a href="https://github.com/emilk"><code>@​emilk</code></a> made
their first contribution in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/738">uuid-rs/uuid#738</a></li>
<li><a href="https://github.com/koshell"><code>@​koshell</code></a> made
their first contribution in <a
href="https://redirect.github.com/uuid-rs/uuid/pull/743">uuid-rs/uuid#743</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/uuid-rs/uuid/compare/1.7.0...1.8.0">https://github.com/uuid-rs/uuid/compare/1.7.0...1.8.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0f2aaaeab9"><code>0f2aaae</code></a>
Merge pull request <a
href="https://redirect.github.com/uuid-rs/uuid/issues/747">#747</a> from
uuid-rs/cargo/1.8.0</li>
<li><a
href="01d16c32ba"><code>01d16c3</code></a>
prepare for 1.8.0 release</li>
<li><a
href="e4746bcbd5"><code>e4746bc</code></a>
Merge pull request <a
href="https://redirect.github.com/uuid-rs/uuid/issues/745">#745</a> from
uuid-rs/ci/outdated</li>
<li><a
href="d0396ad254"><code>d0396ad</code></a>
Merge pull request <a
href="https://redirect.github.com/uuid-rs/uuid/issues/746">#746</a> from
uuid-rs/chore/draft-link</li>
<li><a
href="9415ed4017"><code>9415ed4</code></a>
Merge pull request <a
href="https://redirect.github.com/uuid-rs/uuid/issues/743">#743</a> from
koshell/main</li>
<li><a
href="951e8e325e"><code>951e8e3</code></a>
Merge pull request <a
href="https://redirect.github.com/uuid-rs/uuid/issues/738">#738</a> from
rerun-io/emilk/wasm-bindgen-only-on-web</li>
<li><a
href="101aa84c43"><code>101aa84</code></a>
add v6 to v8 draft link to README</li>
<li><a
href="84dcbba1bd"><code>84dcbba</code></a>
run outdated on a schedule</li>
<li><a
href="ca952b14a8"><code>ca952b1</code></a>
add a workflow for running cargo outdated</li>
<li><a
href="abe995a258"><code>abe995a</code></a>
Make the toml longer, more complicated, and functional</li>
<li>Additional commits viewable in <a
href="https://github.com/uuid-rs/uuid/compare/1.7.0...1.8.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=uuid&package-manager=cargo&previous-version=1.7.0&new-version=1.8.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-20 09:45:18 +08:00
Devyn Cairns
cf321ab510
Make EngineState clone cheaper with Arc on all of the heavy objects (#12229)
# Description
This makes many of the larger objects in `EngineState` into `Arc`, and
uses `Arc::make_mut` to do clone-on-write if the reference is not
unique. This is generally very cheap, giving us the best of both worlds
- allowing us to mutate without cloning if we have an exclusive
reference, and cloning if we don't.

This started as more of a curiosity for me after remembering that
`Arc::make_mut` exists and can make using `Arc` for mostly immutable
data that sometimes needs to be changed very convenient, and also after
hearing someone complain about memory usage on Discord - this is a
somewhat significant win for that.

The exact objects that were wrapped in `Arc`:

- `files`, `file_contents` - the strings and byte buffers
- `decls` - the whole `Vec`, but mostly to avoid lots of individual
`malloc()` calls on Clone rather than for memory usage
- `blocks` - the blocks themselves, rather than the outer Vec
- `modules` - the modules themselves, rather than the outer Vec
- `env_vars`, `previous_env_vars` - the entire maps
- `config`

The changes required were relatively minimal, but this is a breaking API
change. In particular, blocks are added as Arcs, to allow the parser
cache functionality to work.

With my normal nu config, running on Linux, this saves me about 15 MiB
of process memory usage when running interactively (65 MiB → 50 MiB).

This also makes quick command executions cheaper, particularly since
every REPL loop now involves a clone of the engine state so that we can
recover from a panic. It also reduces memory usage where engine state
needs to be cloned and sent to another thread or kept within an
iterator.

# User-Facing Changes
Shouldn't be any, since it's all internal stuff, but it does change some
public interfaces so it's a breaking change
2024-03-19 19:07:00 +01:00
Devyn Cairns
a29efe28f7
Merge stream_example into example plugin and clean up names (#12234)
# Description

As suggested by @WindSoilder, since plugins can now contain both simple
commands that produce `Value` and commands that produce `PipelineData`
without having to choose one or the other for the whole plugin, this
change merges `stream_example` into `example`.

# User-Facing Changes

All of the example plugins are renamed.

# Tests + Formatting

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

- [ ] Check nushell/nushell.github.io for any docs that match the
command names changed
2024-03-19 12:36:46 -05:00
Devyn Cairns
02551c416c
Fix broken build: replace value_string() straggler (#12237)
# Description

Fix after #12230 and #12231 crossed wires and broke the build
2024-03-19 07:52:49 -05:00
Devyn Cairns
6795ad7e33
Make custom value type handling more consistent (#12230)
[Context on
Discord](https://discord.com/channels/601130461678272522/855947301380947968/1219425984990806207)

# Description

- Rename `CustomValue::value_string()` to `type_name()` to reflect its
usage better.
- Change print behavior to always call `to_base_value()` first, to give
the custom value better control over the output.
- Change `describe --detailed` to show the type name as the subtype,
rather than trying to describe the base value.
- Change custom `Type` to use `type_name()` rather than `typetag_name()`
to make things like `PluginCustomValue` more transparent

One question: should `describe --detailed` still include a description
of the base value somewhere? I'm torn on it, it seems possibly useful
for some things (maybe sqlite databases?), but having `describe -d` not
include the custom type name anywhere felt weird. Another option would
be to add another method to `CustomValue` for info to be displayed in
`describe`, so that it can be more type-specific?

# User-Facing Changes
Everything above has implications for printing and `describe` on custom
values

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
2024-03-19 11:09:59 +01:00
Devyn Cairns
931f522616
Support into string for custom values (#12231)
Context: @abusch is working on a semver plugin with custom values and
wants users to be able to convert them back to strings

# Description
This allows `into string` to work on custom values if their base value
representation could be converted into a string with the same rules.

# User-Facing Changes
`into string` works on custom values.

Unfortunately, I couldn't really demo this with an example, because
there aren't any custom values that can be represented that way
included.

# Tests + Formatting
I was able to write a test using the custom values plugin.

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
2024-03-19 11:00:22 +01:00
Ian Manske
6e37ad0275
Use rest argument in export use to match use (#12228)
# Description
Fixes #12057 where it was pointed out that `export use` takes an
**optional** `members` positional argument whereas `use` takes a
**rest** `members` argument.
2024-03-18 20:37:53 +01:00
Ian Manske
127c4a9e63
Fix wrong stdout with e>| (#12227)
# Description
Fixes a bug where stdout would not be the terminal if a `e>|` pipe was
used.
2024-03-18 15:03:30 +00:00
Devyn Cairns
992359a191
Support for custom values in plugin examples (#12213)
# Description
@ayax79 says that the dataframe commands all have dataframe custom
values in their examples, and they're used for tests.

Rather than send the custom values to the engine, if they're in
examples, this change just renders them using `to_base_value()` first.
That way we avoid potentially having to hold onto custom values in
`plugins.nu` that might not be valid indefinitely - as will be the case
for dataframes in particular - but we still avoid forcing plugin writers
to not use custom values in their examples.

# User-Facing Changes
- Custom values usable in plugin examples

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-18 07:34:21 -05:00
Devyn Cairns
a5d03b1d6e
Fix zip signature to mention closure input type (#12216)
# Description

`help zip` now reports:

```
other <one_of(any, closure())>: The other input, or closure returning a stream.
```

Thanks to @edhowland for pointing this out ❤️

# User-Facing Changes

- Doc change for zip

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-16 16:01:09 -05:00
Devyn Cairns
1cb5221f01
Add Value::recurse_mut() to save duplicated code in PluginCustomValue (#12218)
# Description

We do a lot of visiting contained values in the serialization / validity
functions within `PluginCustomValue` utils. This adds
`Value::recurse_mut()` which wraps up most of that logic into something
that can be reused.
2024-03-16 15:54:42 +01:00
Tastaturtaste
c7e0d4b1e5
Use the system clipboard only for explicit copy/paste operations. Addresses issue 11907 (#12179)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->
With the introduction of the system clipboard to nushell, many commands
changed their behavior from using a local cut buffer to the system
clipboard, perhaps surprisingly for many users. (See #11907)
This PR changes most of them back to using the local cut buffer and
introduces three commands (`CutSelectionSystem`, `CopySelectionSystem`
and `PasteSystem`) to explicitly use the system clipboard.


# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
Users who in the meantime already used the system clipboard now default
back to the local clipboard. To be able to use the system clipboard
again they have to append the suffix `system` to their current edit
command specified in their keybindings.

# 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
> ```
-->
The commands themselves are tested in `reedline`. The changes introduces
in nushell are minimal and simply forward from a match on the keybinding
name to the command.
# 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.
-->

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
2024-03-15 08:59:21 -05:00
Devyn Cairns
f6faf73e02
Allow plugins to set environment variables in their caller's scope (#12204)
# Description

Adds the `AddEnvVar` plugin call, which allows plugins to set
environment variables in the caller's scope. This is the first engine
call that mutates the caller's stack, and opens the door to more
operations like this if needed.

This also comes with an extra benefit: in doing this, I needed to
refactor how context was handled, and I was able to avoid cloning
`EngineInterface` / `Stack` / `Call` in most cases that plugin calls are
used. They now only need to be cloned if the plugin call returns a
stream. The performance increase is welcome (5.5x faster on `inc`!):

```nushell
# Before
> timeit { 1..100 | each { |i| $"2.0.($i)" | inc -p } }
405ms 941µs 952ns
# After
> timeit { 1..100 | each { |i| $"2.0.($i)" | inc -p } }
73ms 68µs 749ns
```

# User-Facing Changes
- New engine call: `add_env_var()`
- Performance enhancement for plugin calls

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [x] Document env manipulation in plugins guide
- [x] Document `AddEnvVar` in plugin protocol
2024-03-15 06:45:45 -05:00
sarubo
687fbc49c8
Adjust permissions using umask in mkdir (#12207)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

With this change, `mkdir` mirrors coreutils works. Closes #12161

I referred to the implementation of `mkdir` in uutils/coreutils. I add
`uucore` required for implementation to dependencies. Since `uucore` is
already included in dependencies of `uu_mkdir`, I don't think there will
be any additional dependencies.

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

- Directories are created according to `umask` except for Windows.

# 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
> ```
-->

I add `mkdir` test considering permissions. The test assumes that the
default `umask` is `022`.

# 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.
-->
2024-03-14 16:43:42 -05:00
Ian Manske
c950269575
Fix $in value for insert closure (#12209)
# Description
Fixes #12193 where the `$in` value may be null for closures provided to
`insert`.

# User-Facing Changes
The `$in` value will now always be the same as the closure parameter for
`insert`.
2024-03-14 16:43:03 -05:00
Devyn Cairns
9cf2e873b5
Reorganize plugin API around commands (#12170)
[Context on
Discord](https://discord.com/channels/601130461678272522/855947301380947968/1216517833312309419)

# Description
This is a significant breaking change to the plugin API, but one I think
is worthwhile. @ayax79 mentioned on Discord that while trying to start
on a dataframes plugin, he was a little disappointed that more wasn't
provided in terms of code organization for commands, particularly since
there are *a lot* of `dfr` commands.

This change treats plugins more like miniatures of the engine, with
dispatch of the command name being handled inherently, each command
being its own type, and each having their own signature within the trait
impl for the command type rather than having to find a way to centralize
it all into one `Vec`.

For the example plugins that have multiple commands, I definitely like
how this looks a lot better. This encourages doing code organization the
right way and feels very good.

For the plugins that have only one command, it's just a little bit more
boilerplate - but still worth it, in my opinion.

The `Box<dyn PluginCommand<Plugin = Self>>` type in `commands()` is a
little bit hairy, particularly for Rust beginners, but ultimately not so
bad, and it gives the desired flexibility for shared state for a whole
plugin + the individual commands.

# User-Facing Changes
Pretty big breaking change to plugin API, but probably one that's worth
making.

```rust
use nu_plugin::*;
use nu_protocol::{PluginSignature, PipelineData, Type, Value};

struct LowercasePlugin;
struct Lowercase;

// Plugins can now have multiple commands
impl PluginCommand for Lowercase {
    type Plugin = LowercasePlugin;

    // The signature lives with the command
    fn signature(&self) -> PluginSignature {
        PluginSignature::build("lowercase")
            .usage("Convert each string in a stream to lowercase")
            .input_output_type(Type::List(Type::String.into()), Type::List(Type::String.into()))
    }

    // We also provide SimplePluginCommand which operates on Value like before
    fn run(
        &self,
        plugin: &LowercasePlugin,
        engine: &EngineInterface,
        call: &EvaluatedCall,
        input: PipelineData,
    ) -> Result<PipelineData, LabeledError> {
        let span = call.head;
        Ok(input.map(move |value| {
            value.as_str()
                .map(|string| Value::string(string.to_lowercase(), span))
                // Errors in a stream should be returned as values.
                .unwrap_or_else(|err| Value::error(err, span))
        }, None)?)
    }
}

// Plugin now just has a list of commands, and the custom value op stuff still goes here
impl Plugin for LowercasePlugin {
    fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin=Self>>> {
        vec![Box::new(Lowercase)]
    }
}

fn main() {
    serve_plugin(&LowercasePlugin{}, MsgPackSerializer)
}
```

Time this however you like - we're already breaking stuff for 0.92, so
it might be good to do it now, but if it feels like a lot all at once,
it could wait.

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [ ] Update examples in the book
- [x] Fix #12088 to match - this change would actually simplify it a
lot, because the methods are currently just duplicated between `Plugin`
and `StreamingPlugin`, but they only need to be on `Plugin` with this
change
2024-03-14 16:40:02 -05:00
Ian Manske
b6c7656194
IO and redirection overhaul (#11934)
# Description
The PR overhauls how IO redirection is handled, allowing more explicit
and fine-grain control over `stdout` and `stderr` output as well as more
efficient IO and piping.

To summarize the changes in this PR:
- Added a new `IoStream` type to indicate the intended destination for a
pipeline element's `stdout` and `stderr`.
- The `stdout` and `stderr` `IoStream`s are stored in the `Stack` and to
avoid adding 6 additional arguments to every eval function and
`Command::run`. The `stdout` and `stderr` streams can be temporarily
overwritten through functions on `Stack` and these functions will return
a guard that restores the original `stdout` and `stderr` when dropped.
- In the AST, redirections are now directly part of a `PipelineElement`
as a `Option<Redirection>` field instead of having multiple different
`PipelineElement` enum variants for each kind of redirection. This
required changes to the parser, mainly in `lite_parser.rs`.
- `Command`s can also set a `IoStream` override/redirection which will
apply to the previous command in the pipeline. This is used, for
example, in `ignore` to allow the previous external command to have its
stdout redirected to `Stdio::null()` at spawn time. In contrast, the
current implementation has to create an os pipe and manually consume the
output on nushell's side. File and pipe redirections (`o>`, `e>`, `e>|`,
etc.) have precedence over overrides from commands.

This PR improves piping and IO speed, partially addressing #10763. Using
the `throughput` command from that issue, this PR gives the following
speedup on my setup for the commands below:
| Command | Before (MB/s) | After (MB/s) | Bash (MB/s) |
| --------------------------- | -------------:| ------------:|
-----------:|
| `throughput o> /dev/null` | 1169 | 52938 | 54305 |
| `throughput \| ignore` | 840 | 55438 | N/A |
| `throughput \| null` | Error | 53617 | N/A |
| `throughput \| rg 'x'` | 1165 | 3049 | 3736 |
| `(throughput) \| rg 'x'` | 810 | 3085 | 3815 |

(Numbers above are the median samples for throughput)

This PR also paves the way to refactor our `ExternalStream` handling in
the various commands. For example, this PR already fixes the following
code:
```nushell
^sh -c 'echo -n "hello "; sleep 0; echo "world"' | find "hello world"
```
This returns an empty list on 0.90.1 and returns a highlighted "hello
world" on this PR.

Since the `stdout` and `stderr` `IoStream`s are available to commands
when they are run, then this unlocks the potential for more convenient
behavior. E.g., the `find` command can disable its ansi highlighting if
it detects that the output `IoStream` is not the terminal. Knowing the
output streams will also allow background job output to be redirected
more easily and efficiently.

# User-Facing Changes
- External commands returned from closures will be collected (in most
cases):
  ```nushell
  1..2 | each {|_| nu -c "print a" }
  ```
This gives `["a", "a"]` on this PR, whereas this used to print "a\na\n"
and then return an empty list.

  ```nushell
  1..2 | each {|_| nu -c "print -e a" }
  ```
This gives `["", ""]` and prints "a\na\n" to stderr, whereas this used
to return an empty list and print "a\na\n" to stderr.

- Trailing new lines are always trimmed for external commands when
piping into internal commands or collecting it as a value. (Failure to
decode the output as utf-8 will keep the trailing newline for the last
binary value.) In the current nushell version, the following three code
snippets differ only in parenthesis placement, but they all also have
different outputs:

  1. `1..2 | each { ^echo a }`
     ```
     a
     a
     ╭────────────╮
     │ empty list │
     ╰────────────╯
     ```
  2. `1..2 | each { (^echo a) }`
     ```
     ╭───┬───╮
     │ 0 │ a │
     │ 1 │ a │
     ╰───┴───╯
     ```
  3. `1..2 | (each { ^echo a })`
     ```
     ╭───┬───╮
     │ 0 │ a │
     │   │   │
     │ 1 │ a │
     │   │   │
     ╰───┴───╯
     ```

  But in this PR, the above snippets will all have the same output:
  ```
  ╭───┬───╮
  │ 0 │ a │
  │ 1 │ a │
  ╰───┴───╯
  ```

- All existing flags on `run-external` are now deprecated.

- File redirections now apply to all commands inside a code block:
  ```nushell
  (nu -c "print -e a"; nu -c "print -e b") e> test.out
  ```
This gives "a\nb\n" in `test.out` and prints nothing. The same result
would happen when printing to stdout and using a `o>` file redirection.

- External command output will (almost) never be ignored, and ignoring
output must be explicit now:
  ```nushell
  (^echo a; ^echo b)
  ```
This prints "a\nb\n", whereas this used to print only "b\n". This only
applies to external commands; values and internal commands not in return
position will not print anything (e.g., `(echo a; echo b)` still only
prints "b").

- `complete` now always captures stderr (`do` is not necessary).

# After Submitting
The language guide and other documentation will need to be updated.
2024-03-14 15:51:55 -05:00
Wind
e2907e7e3a
remove test warnings (#12201)
# Description
I get warnings message when running tests:
```
warning: unused import: `Feature`
  --> crates/nu-plugin/src/protocol/mod.rs:21:25
   |
21 | pub use protocol_info::{Feature, Protocol};
   |                         ^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default
```
I think it's useless can can be removed.
2024-03-14 22:34:00 +08:00
Wind
64bab4b6a6
clean cp tests (#12202)
# Description
There are lots of duplicate test for `cp`, it's because we once have
`old-cp` command.

Today `old-cp` is removed, so there is no need to keep these tests.
2024-03-14 06:30:50 -05:00
Darren Schroeder
8abc7e6d5e
remove stdlib logging env variables (#12196)
# Description

This PR removes the environment variables associated with stdlib
logging. We need not pollute the environment since it contains a finite
amount of space. This PR changes the env vars to exported custom
commands.
 
# 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.
-->
2024-03-14 06:28:13 -05:00
Stefan Holderbach
3c4ae7b1a6
Update contributor image generation with new upper bound (#12198)
We are close to breaking the 600 users! 
Let's hope the service can cope with having to render this large an
image.
2024-03-13 19:42:47 +01:00
Stefan Holderbach
d3f22588f0
Disable fmt feature of polars(-core) (#12151)
In normal operations we don't display the dataframes directly.
The `fmt` feature on `polars-core` pulls in the `comfy-table` crate with
its own dependencies on `crossterm` and `strum(_macros)`.
This has the chance to duplicate dependencies. (currently strum version
divergence)

Without this feature only the shapes should be displayed.

May degrade the error output during testing.
2024-03-13 19:42:31 +01:00
Thomas Simmer
bb1fe958b4
Fix histogram error message (#12197)
This PR improves the error message for issue #12194 


Co-authored-by: Thomas Simmer <thomas.simmer@arsene-innovation.com>
2024-03-13 19:00:45 +01:00
Devyn Cairns
ad2fd520ca
MsgPack deserializer: improve handling of EOF (#12183)
# Description

`rmp_serde` has two kinds of errors that contain I/O errors, and an EOF
can occur inside either of them, but we were only treating an EOF inside
an `InvalidMarkerRead` as an EOF, which would make sense for the
beginning of a message.

However, we should also treat an incomplete message + EOF as an EOF.
There isn't really any point in reporting that an EOF was received
mid-message.

This should fix the issue where the
`seq_describe_no_collect_succeeds_without_error` test would sometimes
fail, as doing a `describe --no-collect` followed by nushell exiting
could (but was not guaranteed to) cause this exact scenario.

# User-Facing Changes
Will probably remove useless `read error` messages from plugins after
exit of `nu`

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-13 06:49:53 -05:00
Devyn Cairns
be841d88d7
More robustness improvements to plugin persistence tests (#12185)
# Description

These tests have been causing some pain, so I've done a few more things
to try to make them a bit more tolerant of running slowly.

- `plugin_process_exits_after_stop`: using timeout strategy, allows the
process 5 seconds to exit.

- generally don't use sleep to test anything less than 100ms

# User-Facing Changes


# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-13 06:43:17 -05:00
Yash Thakur
0ff36dfe42
Canonicalize each component of config files (#12167)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

Because `std::fs::canonicalize` requires the path to exist, this PR
makes it so that when canonicalizing any config file, the
`$nu.default-config-dir/nushell` part is canonicalized first, then
`$nu.default-config-dir/nushell/foo.nu` is canonicalized.

This should also fix the issue @devyn pointed out
[here](https://github.com/nushell/nushell/pull/12118#issuecomment-1989546708)
where a couple of the tests failed if one's `~/.config/nushell` folder
was actually a symlink to a different folder. The tests previously
didn't canonicalize the expected paths.

I was going to make a PR that caches the config directory on startup (as
suggested by fdncred and Ian in Discord), but I can make that part of
this PR if we want to avoid creating unnecessary PRs. I think it
probably makes more sense to separate them though.

# 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.
-->
2024-03-13 06:26:06 -05:00
dependabot[bot]
8725bd3112
Bump rayon from 1.8.1 to 1.9.0 (#12186)
Bumps [rayon](https://github.com/rayon-rs/rayon) from 1.8.1 to 1.9.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rayon-rs/rayon/blob/main/RELEASES.md">rayon's
changelog</a>.</em></p>
<blockquote>
<h1>Release rayon 1.9.0 (2024-02-27)</h1>
<ul>
<li>The new methods
<code>IndexedParallelIterator::by_exponential_blocks</code> and
<code>by_uniform_blocks</code> allow processing items in smaller groups
at a time.</li>
<li>The new <code>iter::walk_tree</code>, <code>walk_tree_prefix</code>,
and <code>walk_tree_postfix</code>
functions enable custom parallel iteration over tree-like
structures.</li>
<li>The new method <code>ParallelIterator::collect_vec_list</code>
returns items as a linked
list of vectors, which is an efficient mode of parallel collection used
by
many of the internal implementations of <code>collect</code>.</li>
<li>The new methods
<code>ParallelSliceMut::par_split_inclusive_mut</code>,
<code>ParallelSlice::par_split_inclusive</code>, and
<code>ParallelString::par_split_inclusive</code> all work like a normal
split but
keeping the separator as part of the left slice.</li>
<li>The new <code>ParallelString::par_split_ascii_whitespace</code>
splits only on ASCII
whitespace, which is faster than including Unicode multi-byte
whitespace.</li>
<li><code>OsString</code> now implements
<code>FromParallelIterator&lt;_&gt;</code> and
<code>ParallelExtend&lt;_&gt;</code>
for a few item types similar to the standard <code>FromIterator</code>
and <code>Extend</code>.</li>
<li>The internal <code>Pattern</code> trait for string methods is now
implemented for
<code>[char; N]</code> and <code>&amp;[char; N]</code>, matching any of
the given characters.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="dc13cb7875"><code>dc13cb7</code></a>
Merge <a
href="https://redirect.github.com/rayon-rs/rayon/issues/810">#810</a></li>
<li><a
href="67eeea6f2a"><code>67eeea6</code></a>
Release rayon 1.5.0 / rayon-core 1.9.0</li>
<li><a
href="4828f30eef"><code>4828f30</code></a>
Merge <a
href="https://redirect.github.com/rayon-rs/rayon/issues/808">#808</a></li>
<li><a
href="eeb0d1ad5e"><code>eeb0d1a</code></a>
update ci/compat-Cargo.lock</li>
<li><a
href="12f0d202b8"><code>12f0d20</code></a>
Update glium so that rayon-demo runs on Gnome Wayland</li>
<li><a
href="1f069d7710"><code>1f069d7</code></a>
Merge <a
href="https://redirect.github.com/rayon-rs/rayon/issues/807">#807</a></li>
<li><a
href="9691328a5a"><code>9691328</code></a>
Use Iterator::copied</li>
<li><a
href="e81835c074"><code>e81835c</code></a>
Update crossbeam dependencies (requires Rust 1.36)</li>
<li><a
href="5b3d917d6c"><code>5b3d917</code></a>
Merge <a
href="https://redirect.github.com/rayon-rs/rayon/issues/804">#804</a></li>
<li><a
href="5c55033950"><code>5c55033</code></a>
Release rayon 1.4.1</li>
<li>Additional commits viewable in <a
href="https://github.com/rayon-rs/rayon/compare/rayon-core-v1.8.1...rayon-core-v1.9.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rayon&package-manager=cargo&previous-version=1.8.1&new-version=1.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-13 09:36:09 +08:00
dependabot[bot]
32529433fb
Bump miette from 7.1.0 to 7.2.0 (#12189)
Bumps [miette](https://github.com/zkat/miette) from 7.1.0 to 7.2.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/zkat/miette/blob/main/CHANGELOG.md">miette's
changelog</a>.</em></p>
<blockquote>
<h2>7.2.0 (2024-03-07)</h2>
<h3>Features</h3>
<ul>
<li><strong>wasm:</strong> add feature &quot;fancy-no-syscall&quot; for
wasm targets (<a
href="https://redirect.github.com/zkat/miette/issues/349">#349</a>) (<a
href="328bf37922">328bf379</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>label-collections:</strong> Label collection fixes and
cleanup (<a
href="https://redirect.github.com/zkat/miette/issues/343">#343</a>) (<a
href="75fea0935e">75fea093</a>)</li>
<li><strong>invalid span:</strong> skip the snippet when read_span fails
(<a href="https://redirect.github.com/zkat/miette/issues/347">#347</a>)
(<a
href="7d9dfc6e8e">7d9dfc6e</a>)</li>
<li><strong>redundant-import:</strong> fix a warning and CI failure in
nightly (<a
href="https://redirect.github.com/zkat/miette/issues/348">#348</a>) (<a
href="6ea86a2248">6ea86a22</a>)</li>
</ul>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca646f3119"><code>ca646f3</code></a>
chore: Release</li>
<li><a
href="ff7baae70c"><code>ff7baae</code></a>
docs: update changelog</li>
<li><a
href="24a7bf4f4e"><code>24a7bf4</code></a>
ci(doc consistency): check that lib.rs and README.md are consistent (<a
href="https://redirect.github.com/zkat/miette/issues/353">#353</a>)</li>
<li><a
href="22b29eec38"><code>22b29ee</code></a>
docs: use <code>cargo readme</code> to update (<a
href="https://redirect.github.com/zkat/miette/issues/351">#351</a>)</li>
<li><a
href="62cfd221ba"><code>62cfd22</code></a>
docs: add <code>severity</code> example (<a
href="https://redirect.github.com/zkat/miette/issues/350">#350</a>)</li>
<li><a
href="328bf37922"><code>328bf37</code></a>
feat(wasm): add feature &quot;fancy-no-syscall&quot; for wasm targets
(<a
href="https://redirect.github.com/zkat/miette/issues/349">#349</a>)</li>
<li><a
href="6ea86a2248"><code>6ea86a2</code></a>
fix(redundant-import): fix a warning and CI failure in nightly (<a
href="https://redirect.github.com/zkat/miette/issues/348">#348</a>)</li>
<li><a
href="7d9dfc6e8e"><code>7d9dfc6</code></a>
fix(invalid span): skip the snippet when read_span fails (<a
href="https://redirect.github.com/zkat/miette/issues/347">#347</a>)</li>
<li><a
href="75fea0935e"><code>75fea09</code></a>
fix(label-collections): Label collection fixes and cleanup (<a
href="https://redirect.github.com/zkat/miette/issues/343">#343</a>)</li>
<li>See full diff in <a
href="https://github.com/zkat/miette/compare/miette-derive-v7.1.0...miette-derive-v7.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=miette&package-manager=cargo&previous-version=7.1.0&new-version=7.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-13 09:35:40 +08:00
dependabot[bot]
a404af8ce9
Bump softprops/action-gh-release from 2.0.1 to 2.0.4 (#12191) 2024-03-13 09:23:24 +08:00
dependabot[bot]
96b4b91b2d
Bump actions/checkout from 4.1.1 to 4.1.2 (#12192) 2024-03-13 09:23:05 +08:00
Devyn Cairns
e1cfc96ee8
Fix locking soundness in PersistentPlugin (#12182)
# Description

There were two problems in `PersistentPlugin` which could cause a
deadlock:

1. There were two mutexes being used, and `get()` could potentially hold
both simultaneously if it had to spawn. This won't necessarily cause a
deadlock on its own, but it does mean that lock order is sensitive

2. `set_gc_config()` called `flush()` while still holding the lock,
meaning that the GC thread had to proceed before the lock was released.
However, waiting for the GC thread to proceed could mean waiting for the
GC thread to call `stop()`, which itself would try to lock the mutex.
So, it's not safe to wait for the GC thread while the lock is held. This
is fixed now.

I've also reverted #12177, as @IanManske reported that this was also
happening for him on Linux, and it seems to be this problem which should
not be platform-specific at all. I believe this solves it.

# User-Facing Changes
None

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
2024-03-12 18:22:29 -05:00
Stefan Holderbach
cd71372ea9
Minor refactor in to html (#12172)
Extract the generation of the theme overview into its own function and
elide an else block with early return
2024-03-12 23:13:32 +01:00
Stefan Holderbach
b95cdd9705
Remove the rarely used std-lib issue template (#12173)
Reduce potential for confusion and steer towards the issue templates
with additional requested fields.

Closes https://github.com/nushell/nushell/issues/12110
2024-03-12 23:10:23 +01:00
Stefan Holderbach
bb265c5310
Bump arboard from 3.3.0 to 3.3.2 (#12178)
Reduces the system dependency footprint slightly
2024-03-12 23:10:11 +01:00
Devyn Cairns
ad4ca61860
Disable plugin GC tests on macOS (#12177)
# Description
These are hanging the CI sometimes, and that's no good. I'll try to
figure out how to make these tests pass consistently in the meantime.

# User-Facing Changes
I haven't heard any feedback so far that the plugin GC doesn't actually
work on macOS, so hopefully it's not a big problem, but we won't know
until I'm able to track down the problem.


# After Submitting
- [ ] Fix the tests so they don't get stuck
2024-03-12 20:43:26 +01:00
Stefan Holderbach
13cbfd3cee
Refactor benches for more command benchmarks (#12171)
- Refactor command benchmark
  - should simplify addition of more command benchmarks
  - just provide the pipeline you want to run/ choose potential scaling
- Bench engine state with ctrlc set
  - `None` vs `AtomicBool` behind `Arc`
2024-03-12 13:10:37 +01:00
Devyn Cairns
390a7e3f0b
Add environment engine calls for plugins (#12166)
# Description

This adds three engine calls: `GetEnvVar`, `GetEnvVars`, for getting
environment variables from the plugin command context, and
`GetCurrentDir` for getting the current working directory.

Plugins are now launched in the directory of their executable to try to
make improper use of the current directory without first setting it more
obvious. Plugins previously launched in whatever the current directory
of the engine was at the time the plugin command was run, but switching
to persistent plugins broke this, because they stay in whatever
directory they launched in initially.

This also fixes the `gstat` plugin to use `get_current_dir()` to
determine its repo location, which was directly affected by this
problem.

# User-Facing Changes
- Adds new engine calls (`GetEnvVar`, `GetEnvVars`, `GetCurrentDir`)
- Runs plugins in a different directory from before, in order to catch
bugs
- Plugins will have to use the new engine calls if they do filesystem
stuff to work properly

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [ ] Document the working directory behavior on plugin launch
- [ ] Document the new engine calls + response type (`ValueMap`)
2024-03-12 06:34:32 -05:00
Devyn Cairns
37a9f21b2a
Sync with the plugin garbage collector when setting config (#12152)
# Description
This causes `PersistentPlugin` to wait for the plugin garbage collector
to actually receive and process its config when setting it in
`set_gc_config`.

The motivation behind doing this is to make setting GC config in scripts
more deterministic. Before this change we couldn't really guarantee that
the GC could see your config before you started doing other things.

There is a slight cost to performance to doing this - we set config
before each plugin call because we don't necessarily know that it
reflects what's in `$env.config`, and now to do that we have to
synchronize with the GC thread.

This was probably the cause of spuriously failing tests as mentioned by
@sholderbach. Hopefully this fixes it. It might be the case that
launching threads on some platforms (or just on a really busy test
runner) sometimes takes a significant amount of time.

# User-Facing Changes
- possibly slightly worse performance for plugin calls
2024-03-12 10:50:13 +01:00
Devyn Cairns
73f3c0b60b
Support for all custom value operations on plugin custom values (#12088)
# Description

Adds support for the following operations on plugin custom values, in
addition to `to_base_value` which was already present:

- `follow_path_int()`
- `follow_path_string()`
- `partial_cmp()`
- `operation()`
- `Drop` (notification, if opted into with
`CustomValue::notify_plugin_on_drop`)

There are additionally customizable methods within the `Plugin` and
`StreamingPlugin` traits for implementing these functions in a way that
requires access to the plugin state, as a registered handle model such
as might be used in a dataframes plugin would.

`Value::append` was also changed to handle custom values correctly.

# User-Facing Changes

- Signature of `CustomValue::follow_path_string` and
`CustomValue::follow_path_int` changed to give access to the span of the
custom value itself, useful for some errors.
- Plugins using custom values have to be recompiled because the engine
will try to do custom value operations that aren't supported
- Plugins can do more things 🎉 

# Tests + Formatting
Tests were added for all of the new custom values functionality.

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [ ] Document protocol reference `CustomValueOp` variants:
  - [ ] `FollowPathInt`
  - [ ] `FollowPathString`
  - [ ] `PartialCmp`
  - [ ] `Operation`
  - [ ] `Dropped`
- [ ] Document `notify_on_drop` optional field in `PluginCustomValue`
2024-03-12 10:37:08 +01:00
Stefan Holderbach
8a250d2e08
Include benchmarks in the CI clippy run (#12165)
Make sure the benchmarks don't go out of date and are nice.
2024-03-11 23:20:22 +01:00
Stefan Holderbach
f3a4f10b46
Bump iana-time-zone due to yanked locked version (#12162)
`0.1.59` -> `0.1.60`

e.g. observed in
https://github.com/nushell/nushell/actions/runs/8238152611/job/22528639253#step:4:18
2024-03-11 21:37:34 +01:00
Ian Manske
26786a759e
Fix ignored clippy lints (#12160)
# Description
Fixes some ignored clippy lints.

# User-Facing Changes
Changes some signatures and return types to `&dyn Command` instead of
`&Box<dyn Command`, but I believe this is only an internal change.
2024-03-11 19:46:04 +01:00
Stefan Holderbach
77379d7b3d
Remove outdated doccomment on EngineState (#12158)
Part of the doccomment was an implementation note on the `im` crate that
hasn't been used for ages.
(If I recall we maybe even received a comment on discord on this)
2024-03-11 14:57:28 +00:00
Yash Thakur
f6853fd636
Use XDG_CONFIG_HOME before default config directory (#12118)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

Closes #12103

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

As described in #12103, this PR makes Nushell use `XDG_CONFIG_HOME` as
the config directory if it exists. Otherwise, it uses the old behavior,
which was to use `dirs_next::config_dir()`.

Edit: We discussed choosing between `XDG_CONFIG_HOME` and the default
config directory in Discord and decided against it, at least for now.

<s>@kubouch also suggested letting users choose between
`XDG_CONFIG_HOME` and the default config directory if config files
aren't found on startup and `XDG_CONFIG_HOME` is set to a value
different from the default config directory</s>

On Windows and MacOS, if the `XDG_CONFIG_HOME` variable is set but
`XDG_CONFIG_HOME` is either empty or doesn't exist *and* the old config
directory is non-empty, Nushell will issue a warning on startup saying
that it won't move files from the old config directory to the new one.
To do this, I had to add a `nu_path::config_dir_old()` function. I
assume that at some point, we will remove the warning message and the
function can be removed too. Alternatively, instead of having that
function there, `main.rs` could directly call `dirs_next::config_dir()`.

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

When `$env.XDG_CONFIG_HOME` is set to an absolute path, Nushell will use
`$"($env.XDG_CONFIG_HOME)/nushell"` as its config directory (previously,
this only worked on Linux).

To use `App Data\Roaming` (Windows) or `Library/Application Support`
(MacOS) instead (the old behavior), one can either leave
`XDG_CONFIG_HOME` unset or set it to an empty string.

If `XDG_CONFIG_HOME` is set, but to a non-absolute/invalid path, Nushell
will report an error on startup and use the default config directory
instead:


![image](https://github.com/nushell/nushell/assets/45539777/a434fe04-b7c8-4e95-b50c-80628008ad08)

On Windows and MacOS, if the `XDG_CONFIG_HOME` variable is set but
`XDG_CONFIG_HOME` is either empty or doesn't exist *and* the old config
directory is non-empty, Nushell will issue a warning on startup saying
that it won't move files from the old config directory to the new one.


![image](https://github.com/nushell/nushell/assets/45539777/1686cc17-4083-4c12-aecf-1d832460ca57)


# 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
> ```
-->

The existing config path tests have been modified to use
`XDG_CONFIG_HOME` to change the config directory on all OSes, not just
Linux.

# 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.
-->

The documentation will have to be updated to note that Nushell uses
`XDG_CONFIG_HOME` now. As @fdncred pointed out, it's possible for people
to set `XDG_CONFIG_HOME` to, say, `~/.config/nushell` rather than
`~/.config`, so the documentation could warn about that mistake.
2024-03-11 06:15:46 -05:00
Devyn Cairns
afce380530
Make the plugin persistence GC delay test more reliable (#12153)
# Description

This makes the test a bit more complicated, but implements a timeout
loop in the script. As long as the test completes in 5 seconds it's
considered to be ok. The default is 10 seconds, so that would still be
half that.

This should help with running on the busy CI where things sometimes take
a while. Unfortunately this is a timing sensitive test. The alternative
is basically to just not test this at all because it's too difficult to
guarantee that it will complete in time. If we continue to have issues,
I might just have to take that route instead.
2024-03-11 12:01:48 +01:00