mirror of
https://github.com/nushell/nushell.git
synced 2026-10-28 08:54:52 +08:00
main
12071
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68b79ea0d6 |
test(run): drop the shared short flag that #19271 made a parse error (#19274)
## Description
`run_binds_flags_by_their_long_name` has failed on main since
|
||
|
|
973c590918 |
Fix the bugs found by the nu-conformance open questions (#19271)
## Description The [nu-conformance](https://github.com/Fikoko/nu-conformance) suite (#19206) recorded 35 behaviors as open questions. This PR fixes the ones that are bugs, plus five that needed a decision (T2, T4, T8, T12 and T13). The IDs are the question IDs in that repo's [`open-questions.md`](https://github.com/Fikoko/nu-conformance/blob/master/open-questions.md). ### Before and after | | Code | main | branch | |---|---|---|---| | S2 | `"\xFF"` | error `nu::parser::parse_mismatch`: expected any shape | error `nu::parser::error`: invalid UTF-8 from `\x` escapes in string | | S3 | `r#'abc` | error `nu::parser::unexpected_eof`: expected closing '# | error `nu::parser::unclosed_delimiter`: expected `'#` here | | T1 | `inf == 1` | `true` | `false` | | T1 | `inf > 1` | `false` | `true` | | T1 | `[1.0 inf] \| math max` | `1.0` | `inf` | | T2 | `let x = 5; -$x` | `-$x` | `-5` | | T2 | `let x = 5; 1 + -$x` | error `nu::parser::operator_incompatible_types`: string | `-4` | | T2 | `let x = 5sec; -$x` | `-$x` | `-5sec` | | T2 | `-(2 + 3) \| describe` | `string` | `int` | | T2 | `-(1)px` | `-1px` | `-1px` | | T3 | `-0x10` | `-0x10` | `-16` | | T3 | `+0b11` | error `nu::shell::external_command`: Command `+0b11` not found | `3` | | T4 | `9223372036854775808` | `9223372036854775808.0` | error `nu::parser::error`: number too large (add `.0` for a float) in int | | T4 | `9223372036854775808.0` | `9223372036854775808.0` | `9223372036854775808.0` | | T6 | `[INF Nan Infinity] \| to nuon` | `[inf, NaN, inf]` | `["INF", "Nan", "Infinity"]` | | T6 | `[inf nan NaN] \| to nuon` | `[inf, NaN, NaN]` | `[inf, NaN, NaN]` | | T7 | `9223372036854775808ns` | `15250wk 1day 23hr 47min 16sec 854ms 775µs 807ns` | error `nu::parser::literal_too_large`: duration too large | | T7 | `8EiB` | `9.2 EB` | error `nu::parser::literal_too_large`: filesize too large | | T8 | `[2023-02-29] \| to nuon` | `["2023-02-29"]` | error `nu::parser::error`: not a valid date in datetime | | T8 | `[2023-02-29.log] \| to nuon` | `["2023-02-29.log"]` | `["2023-02-29.log"]` | | T10 | `+5sec` | error `nu::shell::external_command`: Command `+5sec` not found | `5sec` | | T11 | `[1 2]] \| to nuon` | `[1, "2]"]` | error `nu::parser::unbalanced_delimiter`: unexpected `]` (unbalanced with `[`) | | T12 | `{true: 1, null: 2} \| to nuon` | error `nu::parser::parse_mismatch_with_full_string_msg`: expected string | `{"true": 1, "null": 2}` | | T12 | `[[1 2]; [3 4]] \| to nuon` | error `nu::parser::error`: must be a string | `[["1", "2"]; [3, 4]]` | | T13 | `print before; {a: 1, a: 2}` | error `nu::shell::column_defined_twice`: field first defined here | error `nu::parser::column_defined_twice`: field redefined here | | O1 | `not "a" == "b"` | error `nu::shell::cant_convert`: can't convert string to boolean | `true` | | O1 | `let x = 1; not $x == 2` | error `nu::shell::cant_convert`: can't convert int to boolean | `true` | | O3 | `(-9223372036854775808) mod -1` | error `nu::shell::operator_overflow`: modulo operation overflowed | `0` | | O4 | `1 in [1.0]` | error `nu::parser::operator_incompatible_types`: list<float> | `true` | | D1 | `const x = 1; unlet $x; $x` | `1` | error `nu::compile::invalid_literal`: constants cannot be deleted | | D2 | `unlet $in` | `nothing` | error `nu::compile::invalid_literal`: '$in' is a built-in variable and cannot be deleted | | D3 | `mut x = 0; [1 2 3] \| where {\|v\| $x += 1; true } \| ignore; $x` | `0` | error `nu::parser::expected_keyword`: capture of mutable variable | | F2 | `while false { } \| describe` | `nothing` | error `nu::parser::unexpected_keyword`: not allowed in pipeline | | F3 | `if 1 { }` | error `nu::shell::cant_convert`: can't convert int to boolean | error `nu::shell::type_mismatch`: expected bool | | F4 | `2.0 in 1.0..2.0` | `false` | `true` | | F4 | `2.0 in 1.0..<2.0` | `true` | `false` | | C1 | `def f [...r, a] { {r: $r, a: $a} }; f 1 2 3 \| to nuon` | `{r: [2, 3], a: 1}` | error `nu::parser::positional_after_rest`: parameter a after the rest parameter | | C2 | `def f [a, a] { $a }; f 1 2` | `2` | error `nu::parser::duplicate_parameter`: `a` uses a name that is already taken | | C2 | `def f [--x, --x] { $x }; f --x` | `false` | error `nu::parser::duplicate_parameter`: `--x` uses a name that is already taken | | C2 | `def f [--help] { 'mine' }; f --help \| lines \| first` | `Usage:` | error `nu::parser::error`: every command already has `--help` | C3, a script that calls two deprecated commands: ```nushell $ nu two_deprecated.nu # main Warning: nu::parser::deprecated : `-- g is deprecated and will be removed in a future release. ``` ```nushell $ nu two_deprecated.nu # branch Warning: nu::parser::deprecated : `-- g is deprecated and will be removed in a future release. Warning: nu::parser::deprecated : `-- k is deprecated and will be removed in a future release. ``` ## User-facing changes (Release notes) ### Breaking changes - `not` now has the precedence `help operators` lists: `not $a == $b` means `not ($a == $b)`. Before, `not` applied to the next value only. - `-$x` and `-(expr)` negate their value, also as a flag's value or an argument after `--`. Before, `-$x` was the string `"-$x"` and `-(2 + 3)` the string `"-5"`. Arguments to external commands are unchanged. - An integer literal too large for 64 bits, such as `9223372036854775808`, is an error. Add `.0` to write a float. - Filesize and duration literals that don't fit are a parse error (`nu::parser::literal_too_large`) instead of saturating to the largest value. - A word written like a date that isn't a valid date, such as `2023-02-29`, is an error. - `INF`, `Nan`, `Infinity` and other spellings of special floats are strings. Use `inf`, `nan` or `NaN`. `from nuon` reads them the same way. - A record or table literal that names a field twice is a parse error. - `[1 2]]` is an error instead of `[1, "2]"]`. - In a custom command, repeated parameter or flag names, repeated short flags, a parameter after `...rest`, and a `--help` flag are errors. - `while` and `loop` can't be piped, like `for`. - `unlet` errors on constants and on `$in`. - Assigning to a `mut` variable inside a `where` condition is an error; the assignment never took effect. ### Fixes - `inf` compares as larger than every finite number, and `[1.0 inf] | math max` is `inf`. - `2.0 in 1.0..2.0` is `true`, and `2.0 in 1.0..<2.0` is `false`. - `-0x10`, `+0b11`, `+5sec` and `+1kB` are numbers. - `1 in [1.0]` is `true`. - `{true: 1}` and `[[1 2]; [3 4]]` parse, with the keys `"true"`, `"1"` and `"2"`. - `(-9223372036854775808) mod -1` is `0`. - `if 1 { }` reports the same type mismatch as `while 1 { }`, and an `if` or `while` condition that fails while it runs reports its own error. - `9223372036854775807ns` and `9223372036854775807b` are exact, and integer filesize and duration literals no longer lose precision. - A script or `nu -c` command shows every parse warning once, not only the first. - Clearer errors for invalid UTF-8 from `\x` escapes and for unclosed raw strings. ## Additional notes |
||
|
|
de4d33d410 |
fix(run): reject script arguments that main doesn't accept (#19272)
## Description `run script.nu ...args` now checks the arguments after the script path against the script's `main`, the way a call to `main` does. Before, it dropped unknown flags and extra positional arguments, ignored `--flag=value`, and never checked types. `run`'s own flags (`--full-reparse`, `--help`) now only count before the script path. Everything after the path goes to `main`. `run` parses the arguments before it has seen `main`'s signature, so unlike `nu script.nu` it doesn't convert values to the parameter's type. `--foo 23` for a `string` flag is an error that tells you to quote the value. Fixes #19266 ### Before and after With `run-test.nu` from the issue, `def main [--foo(-f): string, --bar(-b)]`: | `run run-test.nu ...` | Before | After | | --- | --- | --- | | `--foo "23" --bar=true` | `bar` is `false` | `bar` is `true` | | `--foo=$v` | `foo` is `null` | `foo` is the value of `$v` | | `-f x` | `-f` goes to `run`, `foo` is `null` | `foo` is `x` | | `-bf x` | `foo` is `null`, `bar` is `false` | `foo` is `x`, `bar` is `true` | | `...{foo: "23"}` | Error: unknown flag `foo` in spread record | `foo` is `"23"` | | `--help` | `run`'s help | `main`'s help | | `--foo` | `foo` is `true` | Error: missing flag argument | | `--foo "23" --huh? hello` | `--huh?` and `hello` are dropped | Error: unknown flag `--huh?` | | `--foo "23" hello` | `hello` is dropped | Error: extra positional argument | | `--foo 23` | `foo` is the int `23` | the error below | ```nushell Error: nu::shell::cant_convert × Can't convert to string. ╭─[source:1:23] 1 │ run run-test.nu --foo 23 | to nuon · ─┬ · ╰── can't convert int to string ╰──── help: `run` doesn't convert script arguments; quote the value to pass a string ``` More cases. `deploy.nu` is `def main [target?: string, --dry-run]`, and `rec.nu` calls `run --full-reparse rec.nu ($n - 1)` until `$n` is 0: | Command | Before | After | | --- | --- | --- | | `run --foo x run-test.nu` | Error: file not found `--foo` | Error: `run` has no flag `--foo` | | `run ...{full-reparse: true} run-test.nu` | Error: cannot find column `block_id_name` | reparses and runs the script | | `let args = [--bar]; run run-test.nu ...$args` | `bar` is `true` | Error: `main` has no rest parameter for a list spread | | `run deploy.nu -dry-run` | runs for real with `target` set to `-dry-run` | Error: unknown flag `-d` | | `run --full-reparse rec.nu 1000` | nu crashes with a stack overflow | Error: recursion limit (50) reached | ## User-facing changes (Release notes) - `run script.nu ...args` rejects arguments the script's `main` doesn't accept: unknown flags, extra positional arguments, flags missing a value, and values of the wrong type. `--flag=value` now works. - `run` doesn't convert values to `main`'s parameter types the way `nu script.nu` does. Quote a number you pass to a `string` parameter, as in `run x.nu --name "23"`. - `run`'s own flags must come before the script path. After the path, `-f` and `--help` go to `main`. - Flags inside a list spread now stay values, so `run x.nu ...$args` no longer passes a `--foo` in `$args` as a flag. Use a record spread like `...{foo: "23"}` instead. - `run` counts toward `recursion_limit`, so a script that runs itself too deeply stops with an error instead of crashing nu. ## Additional notes - This can break scripts that relied on `run` ignoring arguments. For example, `run x.nu build` used to run plain `main` and drop `build`. `run` doesn't dispatch to `def "main build"` subcommands the way `nu x.nu build` does, so this is now an extra positional error. - Also fixed: with `def main [-a, -b]`, `run x.nu -b` failed with "variable not found", and `run` didn't find a `main` that has an attribute like `@example`. - Not in this PR: completing `main`'s flags after the script path. |
||
|
|
394445e89d |
feat(job spawn) auto-kill flag (#19141)
## Description closes #18896 when calling `exit`, if the flag is passed, we suppress the warning for quitting that job. if all remaining jobs have this flag enabled, we don't emit a warning. I chose the name `auto-kill` because we already use the terminology "kill" for jobs ## User-facing changes (Release notes) Allow using the flag `-k`/`--auto-kill` with `job spawn` for jobs that are expected to stay alive. This suppresses warnings about that job still running on `exit`. `job list` now shows which jobs have this `auto-kill` flag set, and a hint has been added to `exit`. |
||
|
|
e5ebc68190 |
Ignore the zip extraction advisories in cargo audit, since calamine never extracts (#19273)
## Description The `Security audit` job is failing on main and on every PR that touches `Cargo.lock` (for example #19141). RustSec filed three advisories against `zip 8.6.0` on 2026-10-09 and 2026-10-10, all fixed in `zip >= 9.0.0`: | Advisory | Issue | | --- | --- | | RUSTSEC-2026-0367 | `extract()` keeps SUID/SGID/sticky bits from the archive | | RUSTSEC-2026-0368 | `ZipArchive::extract` creates symlinks that point outside the destination | | RUSTSEC-2026-0369 | `extract()` applies Unix permissions through extracted symlinks | A version bump is not possible yet. `calamine 0.36.1` is the latest release and requires `zip = "^8.6"`, and the zip 9 upgrade (tafia/calamine#741) is still an open PR. Using that branch would make it a git dependency. None of the three advisories can be reached from nushell. All three are about writing an archive to disk (`ZipArchive::extract`, `ZipStreamReader::extract`, symlink creation, permission bits). calamine only opens the archive and reads entries into memory with `ZipArchive::new`, `by_name` and `by_index`. A search of calamine 0.36.1's `src/` finds no `extract`, `ZipStreamReader`, `set_permissions` or `symlink`. ## User-facing changes (Release notes) ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
7b893cbad5 |
roundup of fixes for {hide,load,with}-env (#19098)
## Description
this is a roundup of fixes meant to address the following issues:
1. `$env.config`
- `load-env { config: {} }` and `hide-env config` can make `$env.config`
inaccessible. with the way nushell works, the config isn't gone, and a
simple `$env.config = {}` will fix this. but (imo) it's still weird.
- it can also give the impression that `load-env` is able to set
`$env.config`, which it couldn't.
- therefore, I changed it so `hide-env` can't touch `config`.
- meanwhile, `load-env` and `with-env` (including the shorthand syntax
`FOO=bar command`) can now change `config`, which triggers a proper
config reload
2. automatic env vars
- automatic env vars like `PWD` are not supposed to be changed through
`load-env` and `hide-env`. a guard was implemented in `load-env` but not
`hide-env`. now both handle this.
- we had several manual impls of finding automatic env vars. changed to
use a shared impl.
- some env var-detecting logic still has the assumption that env vars
are case sensitive outside Windows, but `load-env` and `hide-env` don't
work like that. so although `load-env` tried to guard against changing
e.g. `$env.PWD` it would happily change `$env.PwD` so can still mess up
the environment.
## User-facing changes (Release notes)
Changes have been made around the interaction of `load-env`, `hide-env`
and `with-env` with some environment variables which are managed by
nushell.
Specifically:
* `load-env`, `hide-env` and `with-env` can no longer change `$env.PWD`,
regardless of casing (for example, `Pwd` is also rejected).
* `hide-env` can no longer hide `$env.FILE_PWD` or `$env.CURRENT_FILE`.
this was previously allowed.
* `load-env` and `with-env`, including the syntax `FOO=bar command`, can
now set `$env.config`.
* `hide-env` can no longer hide `$env.config`.
|
||
|
|
ae34b06666 |
Fix completion match indices, cursor edits, and IDE output (#19258)
Fix Unicode completion match indices, UTF-8 cursor normalization, command-head replacement spans, IDE JSON escaping, and execution of tests selected with `--ignored`. Regression tests reproduce the failures on main, and the relevant test suites, workspace CI checks, formatting, and lint pass. |
||
|
|
85aae22da8 |
Release plugin inputs on response completion or output drop (#19171)
## Description A plugin can stop processing while its input reader is still blocked on a connected, idle producer. Have the SDK release a call's original list or byte input automatically when its complete response finishes writing, or when the engine drops its output stream. Returning lazy output does not itself release input. Other calls and engine-call result streams are unaffected; no new public plugin API is needed. Defer both completion and output-drop cleanup while the SDK is forwarding stream input to an engine call. An early response from `call_decl` or `eval_closure_with_stream` must not truncate that input, including redirected output that closes before its input consumer finishes. The core reader owns a concrete hold, attached before publishing the engine-call header and released when the forwarding writer ends or its consumer sends `Drop`. Since `PipelineData` is opaque, forwarding an unrelated stream conservatively holds the original input too. Engine-call result readers remain outside this cleanup. Skip completion cleanup while the plugin has disabled GC through `set_gc_disabled(true)`, preserving background input reads after a response. This follows the last successfully written and flushed plugin-wide GC option, not Nushell's GC configuration. The setting is shared by all calls, so overlapping calls must coordinate updates: the last write wins for both GC and input retention. Completion reads the setting without waiting for transport I/O; concurrent GC updates retain their wire order. An early output `Drop` still requests input cleanup, regardless of GC, but honors active SDK forwarding holds. Remove the output/input association before sending `End`, so a normal EOF acknowledgement does not cancel those background reads. Keep the association in the output writer's signal, cancelling input before waking a dropped writer so concurrent `End` cannot lose the cleanup. Cancelled reads report `ShellError::Interrupted` once instead of successful EOF, so a consumer can distinguish interrupted input from a complete stream. The reader discards its local queue and sends `Drop` once. Its registration remains until the producer sends `End`, allowing in-flight messages to arrive safely. No wire protocol changes or new dependencies are needed. The interruption retains the input stream's span. A transport error dequeued by the current read takes precedence over cancellation; errors behind that message are discarded with the queue. Association setup and local cleanup are infallible. A poisoned writer mutex does not skip unlinking, releasing a hold, or the single terminal `End` attempt; normal flow-control errors and actual write/flush errors remain visible. Completion cleanup cannot introduce a second response after a successful one. Regression tests cover idle reads, cancellation races, late messages, GC opt-out, call isolation, engine-call forwarding, and interruption versus normal EOF, including both stream types through `serve_plugin_io`. ## User-facing changes (Release notes) Fixed Rust plugin input readers remaining blocked after a response finishes or its output is dropped. Background reads of original input without an explicit call to `set_gc_disabled(true)` are now interrupted when the complete response finishes, even if plugin GC is disabled in Nushell's configuration. Cancelled input reads report `ShellError::Interrupted`, not successful EOF. Calling `set_gc_disabled(true)` preserves background input reads after completion. This setting is plugin-wide and last write wins, so overlapping calls must coordinate their GC updates. Both completion and early output-drop cleanup preserve input forwarded by the SDK until forwarding finishes or its consumer drops it. An early output drop still requests cleanup when GC is disabled. Engine-call result readers are unaffected. ## Additional notes Related to #12129; this does not implement general pipeline interruption. Validated on Linux: 272 tests and 38 doctests across the five plugin crates, plus 121 root plugin integration tests (one Windows-only test ignored). The 40 SDK lifecycle tests also passed five repeated runs. Formatting, `cargo nuclippy`, `cargo nuclippy-tests`, and `typos` passed. Full workspace runtime tests and Windows/macOS CI have not been run. Cleanup wakes SDK-owned input reads; it does not interrupt arbitrary iterators, blocked transport writes, or independent work such as HTTP requests, or retract data already received. Output completion can still wait for that independent work. A producer that never sends `End` can leave a stream registration until the transport closes. Developed with AI assistance. |
||
|
|
190471268e |
fix(mcp): don't offer hidden commands, and leave out the arguments an alias already passes (#19270)
## Description Follow-up to #19262. Three problems remain in how the MCP server's `list_commands` and `command_help` tools, and the "Did you mean" hint for an unknown command, describe the commands in scope. - **Hidden commands are still offered.** `EngineState::get_decls_sorted(false)` checks each overlay only against that overlay's own visibility, but `hide` records the hide in the overlay that is active when it runs. After `alias st = str trim`, `overlay new x`, `hide st` (entered as separate lines), `st` can't be called, yet MCP lists it, `command_help st` documents it, and `' a ' | st` says "Did you mean `st`?". Module commands hidden the same way behave the same. - **`command_help` can describe the wrong command.** It searched the listed signatures for a matching name instead of resolving the name the way the parser does. When an overlay shadows `foo` and a later overlay hides that `foo`, a call to `foo` runs the original, but `command_help foo` documented the shadowing one. If a command was hidden and then imported again from a later overlay, `foo` ran but `command_help foo` said it didn't exist. - **An alias lists the arguments it already passes.** An alias of an internal command carries the wrapped command's full signature. `alias home = cd ~` was listed as `home {flags} (path)`, and `def "foo bar" [x: int] {}; alias fb = foo bar 1` as `fb <x>`. The parser starts matching an alias call's arguments after the positionals the alias passes (`parse_internal_call`), so `home /tmp` and `fb 2` fail. ## User-facing changes (Release notes) - The MCP server's `list_commands` and `command_help` tools, and the "Did you mean" hint for an unknown command, no longer offer a command that was hidden with `hide` while another overlay was active. - `command_help` now describes the command a name actually runs when overlays shadow or hide commands. - The MCP server's `list_commands` and `command_help` tools list an alias that passes positional arguments with only the parameters left for you to give. `alias home = cd ~` is listed as `home {flags}` instead of `home {flags} (path)`. `help home` is unchanged and still shows the expansion with `cd`'s usage. ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
2529074fc8 |
Fix some issues with how 'into string' handles ints/floats (#19265)
## Description This PR fixes the three issues mentioned in https://github.com/nushell/nushell/issues/19264. Passing i64::MIN to 'into string' causes a crash since we're taking the absolute of i64 and returning it as an i64. The absolute value of i64::MIN is equal to i64::MAX + 1. unsigned_abs() gives us u64, which can represent this value. When grouping digits we check for the length of the value as a string without taking into account the space the minus sign might take. Because of this, a negative value such as "-123" is counted as four numbers/characters instead of three. This goes above the threshold for grouping, which results in a weirdly formatted output. We correctly return early when a non-finite (infinite or NaN) value is given in the `action` function, but we don't do the same after formatting the input with the user-chosen amount of decimals. With some inputs we can avoid the first early return due to the input being a valid value, but still end up with a NaN after multiplying with `precision` and rounding. This can be avoided by moving the early return after the formatting. Lastly, in format_duration_as_timeperiod, we now clamp the duration to [-i64::MAX, i64::MAX] and then take the absolute value so that an error isn't thrown when a value <= i64::MIN is passed to 'into duration'. ## User-facing changes (Release notes) - Fixed multiple issues with how 'into string' handles ints/floats. Now i64::MIN doesn't cause a crash, NaN is returned for negative values with the `--decimal` argument set to a huge value and negative floats with three integers are correctly formatted when `--group-digits` is passed. - Fix an issue where 'into duration' overflows/panics when supplied with a value <= i64::MIN ## Additional notes Closes https://github.com/nushell/nushell/issues/19264 |
||
|
|
cf0c9a7734 |
fix(cli): correct the --mcp-host help text and example (#19268)
## Description Three gaps in type aliases (#19223), plus a typo in `nu --help`. - `hide` didn't know about type aliases. `hide Id` left the alias usable, `hide <module> *` left the module's aliases in scope, and `hide <module> Animal` failed with "Export not found." - `help modules <name>` and `scope modules` didn't list the type aliases a module exports, so the only way to find them was to read the module's source. - `type ls` is how Bash and cmd.exe show what a command is. In Nushell it failed with "type missing sign", a label that pointed at nothing, and no hint. - `nu --help` described `--mcp-host` as the "host for MCP HTTP transhost", and its example used `--mcp-transhost`, which isn't a flag. The typo came in with #18952. ## User-facing changes (Release notes) - `hide` now hides type aliases. `hide Name` hides the type alias `Name` when no alias or command has that name, and `hide <module> Name`, `hide <module> [Name ...]` and `hide <module> *` hide a module's exported type aliases along with its commands. - `help modules <name>` lists the type aliases a module exports, and `scope modules` has a new `type_aliases` column with each alias's `name`, `type` and `type_alias_id`. - `type ls` and other `type` statements without `=` now explain how to write a type alias, and for `type <name>` they point to `which <name>` and `^type <name>`. - Fixed the `--mcp-host` description and example in `nu --help`. ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
cfeea823ea |
fix: report missing closure blocks instead of panicking (#19159)
## Description When a job is spawned before a later input is parsed, the job retains an older `EngineState`. The later closure's `BlockId` is therefore unavailable in that job, which previously panicked in `EngineState::get_block`. - remove the infallible `ClosureEval` / `ClosureEvalOnce` constructors and make every `try_new*` constructor take a span pointing at the failing call or closure value, so a stale `BlockId` can no longer panic through any entry point (`do`, `each`, `zip`, `where`, …) - add `EngineState::get_closure_block` as the single fallible lookup with a span and actionable help (shared `MISSING_CLOSURE_BLOCK_HELP` const); direct `get_block` callers on runtime closure values (`tee`, `with-env`, `export-env`, `explain`, `view source`, `record where`, `job spawn`, `debug profile`, the hook runner and the tui `closure_arity`) now report the same error instead of panicking - `debug profile` checks the block before installing the profiler, and `job spawn` checks before registering the job, so the error reaches the caller's `try`/`catch` instead of the background thread - best-effort consumers degrade instead of panicking: `describe --detailed` omits the `signature` key, `to text` / `to toml --serialize` fall back to the existing placeholder string, `to yaml --serialize` returns the `closure_block_not_found` error, and `Closure::coerce_into_string` (`to msgpack`, `to kdl`) returns `CantConvert` - `par-each` builds the evaluator once in `run` (skipping empty input like `each`) and clones it into the workers, returning a single error instead of one error value per item - `default` propagates the construction error instead of storing it as the default value - `generate` reads the signature from the evaluator's `block()` instead of looking the block up twice - `ClosureEval` / `ClosureEvalOnce` expose `block()`, removing the remaining second lookups in `record where`, the tui `call_closure` and `generate` - convert the `record` commands from #19190 to the fallible constructors - add regression tests that reproduce the interactive, multi-input `job spawn` / `job send` flow from #19147 through `do`, `each`, `zip`, `tee`, `par-each`, `record each`, `view source`, `describe --detailed`, `to text --serialize`, `debug profile`, `job spawn`, and a combined test for `with-env`, `explain`, `generate`, `record where`, `record walk` and `sort-by` Removing the infallible constructors is a breaking change to nu-engine's public API without a deprecation step: a deprecated shim cannot avoid the panic, which is what this PR removes, so the break is intentional. ## User-facing changes (Release notes) - Fixed an issue where a closure created after a job was spawned panicked the job when used (`do`, `each`, `zip`, `tee`, `par-each`, `sort-by`, `explain`, `with-env`, `job spawn`, …). Nushell now reports `Closure cannot be evaluated` with a span and a hint instead, and `job spawn` / `debug profile` now surface the error to the caller. - Serializing such a closure no longer crashes: `describe --detailed` and `to text` / `to toml --serialize` degrade to the existing placeholder, while `to yaml --serialize` and `to msgpack` report a conversion error. ## Additional notes - fixes #19147 - rebase note: this branch now includes the conversion of the `record` commands merged in #19190, which called the removed constructors ## Validation - `cargo test -p nu-command --test tests job` (44 passed; do / each / zip / tee / par-each / record each / record where / record walk / view source / describe / to text / debug profile / job spawn / with-env / explain / generate / sort-by scenarios) - `cargo test -p nu-command --test tests` (3438 passed; the 21 failures are pre-existing Windows symlink-privilege environment failures, confirmed identical on upstream main) - `cargo test` for nu-engine, nu-cmd-lang, nu-protocol, nu-tui, nu-cmd-base, nu-color-config, nu-heavy-utils, nu-cli, nu-cmd-extra, nu-lsp, nu-dap, nu-plugin-engine (only the same symlink-privilege failures, confirmed on upstream main) - `cargo test -p nu-engine --doc`, `cargo test -p nu-protocol --doc` - `cargo fmt --all -- --check` - `cargo clippy -p nu-engine -p nu-cmd-lang -p nu-command -p nu-cli -p nu-cmd-extra -p nu-color-config -p nu-plugin-engine -p nu-tui -p nu-protocol -p nu-cmd-base -p nu-heavy-utils --tests --no-deps -- -D warnings` |
||
|
|
f97cd76f21 |
Rename fetch_update to try_update (#19267)
## Description `std::sync::atomic::Atomic::fetch_update` has been renamed to `try_update` with the former working as a [deprecated alias](https://github.com/rust-lang/rust/issues/135894) for the latter. This PR renames each mention of `fetch_update` with `try_update` in order to avoid displaying two warnings during each build. ## User-facing changes (Release notes) n/a ## Additional notes |
||
|
|
430207e98e |
fix(mcp): list and look up commands by the name they're called by (#19262)
## Description
The MCP server's `list_commands` and `command_help` tools name each
command by its signature, and a signature's name isn't always a name you
can call.
Driving `nu --mcp` over stdio. The session first runs the `evaluate`
tool with `alias st = str trim` and with `module spam { export def "foo
bar" [] {} }; use spam`. Before is main at
|
||
|
|
6112446c3c |
fix(help): drop hidden subcommands and fix multi-line, backticked, and script alias entries (#19261)
## Description
Follow-up to #19253, which lists an alias in `help <command>` under its
own name, right after the subcommand it runs. Four cases are still wrong
on main:
- A hidden custom subcommand is still listed. #19253 only dropped hidden
aliases.
- An alias written over several lines splits its entry across lines.
- With color on, backticks inside an alias's expansion confuse the
highlighter. The inner backticks disappear and the outer ones stay.
- A script's `alias mb = main bar` is missing from `script.nu --help`,
though `mb` works inside the script.
With this PR, `help` leaves out a hidden subcommand of any kind, joins
an alias's expansion onto one line and highlights it as a whole, and
lists a script alias of a `main` subcommand right after that subcommand.
Each example shows the Subcommands section of `help`. Before is main at
|
||
|
|
07b01e2f37 |
fix(parser): try string last in oneof so oneof<string, list<string>> parses [a b] as a list (#19238)
## Description
The order of the types in a `oneof` changed what a literal argument
parsed as:
```nushell
> def show [x: oneof<string, list<string>>] { $x | describe }
> show [foo bar]
string
> def show [x: oneof<list<string>, string>] { $x | describe }
> show [foo bar]
list<string>
```
`parse_oneof` returns the first shape that parses without error, and the
`string` shape accepts nearly any single token as a bare word. With
`string` listed first, every type after it was unreachable from a
literal:
| `oneof<string, X>` | literal | parsed as (before) | parsed as (after)
|
| --- | --- | --- | --- |
| `list<string>` | `[foo bar]` | `"[foo bar]"` | `[foo, bar]` |
| `table` | `[[a]; [1]]` | `"[[a]; [1]]"` | `table<a: int>` |
| `int` | `5` | `"5"` | `5` |
| `number` | `1.5` | `"1.5"` | `1.5` |
| `duration` | `5sec` | `"5sec"` | `5sec` |
| `filesize` | `5kb` | `"5kb"` | `5kb` |
| `range` | `1..5` | `"1..5"` | `1..5` |
| `datetime` | `2024-01-01` | `"2024-01-01"` | `2024-01-01` |
| `binary` | `0x[ff]` | `"0x[ff]"` | `0x[FF]` |
`oneof<path, list<path>>` and `oneof<glob, list<glob>>` had the same
problem, and so did parameter defaults and list elements: `[x:
oneof<string, int> = 5]` defaulted to the string `"5"`, and
`list<oneof<string, int>>` parsed `[1 a]` as `["1", a]`. Both now give
ints. The type check doesn't depend on order, so `let x = [foo bar];
show $x` already passed a list.
## User-facing changes (Release notes)
In `oneof<...>` parameter types, `string`, `path`, `directory`, `glob`,
`cell-path`, `external_arg` and `any` no longer claim a literal that
another listed type matches, whatever order the types are listed in.
`oneof<string, list<string>>` now parses `[foo bar]` as a list, and
`oneof<string, int>` parses `5` as the int `5` instead of the string
`"5"`. A bare word that no other listed type matches still parses as a
string, and arguments starting with `$`, `(` or `{` parse as before.
A literal that looks like one of the other types now gets that type, so
quote it if you need the text. With `oneof<string, int>`, `007` arrives
as `7` and `0x10` as `16`. With `oneof<string, number>`, `1.10` arrives
as `1.1` and `nan` as a float. With `oneof<string, list<string>>`, a
character class like `[0-9]` arrives as the list `["0-9"]`. This also
applies to `extern` parameters, which pass the converted value to the
external command.
Parameters declared as plain `string` are unchanged: `[foo bar]` passed
to one is still the string `"[foo bar]"`.
## Additional notes
closes https://github.com/nushell/nushell/issues/16445
|
||
|
|
356e7bc02f |
Preserve REPL background jobs on Ctrl-C and clean up jobs on non-REPL exit (#19163)
## Summary - Addresses #18989 by preserving REPL background and frozen jobs during foreground `Ctrl-C`, while non-REPL commands and scripts clean up jobs even when an interruption is caught - Determine execution mode once (REPL, command, script, server) without conflating `-i` with an interactive REPL; explicit `exit` in `-i -c` or `-i` script preserves requested exit code, while REPL retains first-exit warning and second-exit cleanup - Serialize OS process creation and PID registration against `ThreadJob` shutdown under the PID lock to eliminate an orphan-process race - Clear cloned `is_repl` flag in background job engine clones so `exit` terminates their closure instead of warning and continuing - Centralize forced cleanup and lock-poison recovery, completing non-REPL cleanup before publishing interrupts while preserving early signal-handler initialization - Windows combines `CREATE_NEW_PROCESS_GROUP` and `CREATE_NO_WINDOW` inside `ForegroundChild` without an extra exported preparation helper; new process groups isolate `Ctrl-C` but `Ctrl+Break` is NOT isolated - Cross-platform lifecycle tests use Nu as the child, bounded handshakes and Windows owned process handles opened before child exit to avoid PID reuse - Add tests for lock registration, chained spawns, explicit exit, REPL two exits and background exit; remove fixed 500ms sleep - Fix minimal-feature plugin-only import warning for `absolute_with` ## Testing Verified on macOS on top of `ca323a65bdb7c945488b75a5f7bf5d90a8f3bff1`: - 29 background job regressions, 3 `ThreadJob` tests, and 47 root unit tests passed - Shell suite: 320 passed, 6 ignored - Related crate tests and doctests ran with `--no-fail-fast` for `nu-protocol`, `nu-engine`, `nu-command`, `nu-system`, `nu-cli`; all passed except one existing `cp` debug test - Chained-spawn stress test produced 0/1000 leaks versus 5/50 on original head; `-i -c "exit 3"` returns 3 without running subsequent code - `cargo fmt --all --check` passed - Clippy passed with `-D warnings` on `--all-targets` for `nu`, `nu-protocol`, `nu-engine`, `nu-command`, `nu-system`, `nu-cli` - Minimal-feature check passed for `--bin nu` - WASM target checks passed for `nu-command`, `nu-engine`, `nu-protocol`, `nu-system` - Windows cross-compilation check passed for `nu-engine`, `nu-protocol`, `nu-system` libraries ## Remaining validation Open verification limits and pending checks: - Local `cp` debug test expects `reflink: unsupported` but this macOS returns `reflink: yes`, confirmed identically on original published head `ca323a65bdb7c945488b75a5f7bf5d90a8f3bff1` - `cargo check --no-default-features --all-targets` fails on existing `nu-plugin-engine` `ServerCommunicationIo::LocalSocket` non-exhaustive match, reproduced in an isolated original-head source and target tree - Windows real-console `GenerateConsoleCtrlEvent` integration test is still missing and `ping -t` reproduction has not been performed; compile-only Windows checks do not establish runtime behavior, so Windows review remains open - Updated GitHub CI validation is pending publication --------- Signed-off-by: akasakariko <148060537+akasakariko@users.noreply.github.com> |
||
|
|
776da6de47 |
Let metadata <expr> and stor insert/update record flags ignore pipeline input instead of erroring (#19254)
## Description
`metadata` with an argument fails when the call also has pipeline input:
```nushell
[1] | each {|x| let s = (metadata $x).span; $s }
# Error: nu::shell::incompatible_parameters
# pipeline input was provided / but a positional metadata expression was also given
```
The user never piped anything into `metadata` here. The first statement
of a block receives the block's input, which is intended (`"a" | do {
let x = (str uppercase); $x }` returns `A`), so `metadata` gets the
closure's input along with `$x` and refuses. The same check rejects `"a"
| metadata $in`, because `$in` stores the input in the variable and
still passes it to the call.
The check came in with another PR. A command can't tell implicit block
input from an explicit pipe at run time: both arrive as ordinary
`PipelineData` in the same register.
This PR removes the check. When `metadata` gets an argument, the result
describes only that argument: a record with its `span`. The input and
its pipeline metadata are ignored. Before #16049 the argument's span was
merged with the input's pipeline metadata, which attached the input's
metadata to an unrelated value:
```nushell
open Cargo.toml | metadata 5
# {span: ..., source: ".../Cargo.toml"} <- input's source reported for the literal 5
ls | do { let m = (metadata $env.PWD); $m }
# {span: ..., path_columns: [name], ...} <- ls's path columns reported for $env.PWD
```
`stor insert --data-record` and `stor update --update-record` had the
same input-versus-argument check and failed the same way inside a block:
```nushell
[{a: 1}] | each {|r| stor insert -t t -d $r }
# Error: Pipeline and Flag both being used
```
## User-facing changes (Release notes)
- `metadata <expression>` no longer errors when the call also has
pipeline input, such as the input a block's first statement receives
(`[1] | each {|x| let s = (metadata $x).span; $s }`) or `"a" | metadata
$in`. With an argument, `metadata` returns that argument's span and
ignores the input; `metadata` without an argument still reports the
input's pipeline metadata.
- `stor insert --data-record` and `stor update --update-record` no
longer error with "Pipeline and Flag both being used" when the call also
has pipeline input. The flag's record takes precedence and the input is
ignored.
## Additional notes
- Since the input is ignored whenever an argument is given, an explicit
pipe into these calls is now dropped without an error too (`ls |
metadata $x`, `ls | stor insert -t t -d {a: 1}`). Erroring only on an
explicit pipe would need the compiler to mark implicit block input,
which no command can see today.
- `metadata $in` returns only the span. The input's `path_columns`,
`content_type` and custom keys are not included; use `metadata` without
an argument for those. (`source` from `open` is already removed when the
input is collected into `$in`.)
|
||
|
|
9398108ce7 |
fix(help): list an alias in a command's subcommands under its own name (#19253)
## Description
`help <command>` lists aliases of the command's subcommands, which makes
`help str` a place to discover `st` after `alias st = str trim`. On main
the entry used the wrong name. It showed the alias under the name of the
command it wraps, so `str trim` appeared twice and `st` appeared
nowhere. A hidden alias stayed listed, and a script alias named like a
`main` subcommand was missing.
With this PR an alias is listed under the name you call it by, right
after the subcommand it runs, and its entry always says what it runs:
``st (alias) - Alias for `str trim` ``.
Each example shows the Subcommands section of `help`. Before is main at
|
||
|
|
c8095a3d10 |
fix(each): report the closure's error instead of "Eval block failed with pipeline input" (#19252)
## Description
The commands `each`, `par-each`, and `items` wrap an error raised by
their closure in `ShellError::EvalBlockWithInput`. That variant had its
own message, "Eval block failed with pipeline input", its own code,
`nu::shell::eval_block_with_input`, and kept the closure's error in
`#[related]`. So `catch` saw the wrapper's text, and the report printed
the generic wrapper first and the error that mattered second:
```nushell
> try { [1] | each { error make {msg: inner} } } catch {|e| $e.msg }
Eval block failed with pipeline input
> try { for x in [1] { error make {msg: inner} } } catch {|e| $e.msg }
inner
```
The variant now holds an `EvalBlockWithInputError`, a struct with a
hand-written `Diagnostic` impl in
`crates/nu-protocol/src/errors/shell_error/eval_block_with_input.rs`. It
forwards to the wrapped error the same way `ChainedError` does for a
single source, and adds one label.
## User-facing changes (Release notes)
When a closure passed to `each`, `par-each`, or `items` fails, Nushell
now reports the closure's error. The input value it was processing is
shown as an extra `source value` label. `$e.msg` in `catch` is the
closure's message, and the error code is the closure error's code
instead of `nu::shell::eval_block_with_input`.
Before:
```nushell
> [1 2] | each {|x| $x / 0 }
Error: nu::shell::eval_block_with_input
× Eval block failed with pipeline input
╭─[source:1:2]
1 │ [1 2] | each {|x| $x / 0 }
· ┬
· ╰── source value
╰────
Error: nu::shell::division_by_zero
× Division by zero.
╭─[source:1:22]
1 │ [1 2] | each {|x| $x / 0 }
· ┬
· ╰── division by zero
╰────
```
After:
```nushell
> [1 2] | each {|x| $x / 0 }
Error: nu::shell::division_by_zero
× Division by zero.
╭─[source:1:2]
1 │ [1 2] | each {|x| $x / 0 }
· ┬ ┬
· │ ╰── division by zero
· ╰── source value
╰────
```
## Additional notes
Two fixes for code running inside these closures:
- `exit` works. `[1] | each { exit 4 }` exits with 4, and `try { [1] |
each { exit 4 } } catch { ... }` no longer runs the `catch` block.
- An external's exit code survives. `try { [1] | each { ^sh -c 'exit 42'
} } catch {|e| $e.exit_code }` is `42`, and so is `$env.LAST_EXIT_CODE`.
Scripts that matched the code `nu::shell::eval_block_with_input`, or
read `$e.details.inner.0` to reach the closure's error, should use
`$e.msg` / `$e.details.msg` instead
|
||
|
|
b1bf5c4739 |
fix(parser): treat a bare word after and/or/xor in a row condition as a column (#19251)
## Description
In a row condition, a bare word on the right of `and`, `or` or `xor`
parsed as a string instead of a column:
```nushell
> [{a: false, b: false}] | where not a and not b
Error: nu::shell::cant_convert
× Can't convert to boolean.
```
```nushell
> [{a: true, b: true}] | where a and b
Error: nu::shell::operator_unsupported_type
× The 'and' operator does not work on values of type 'string'.
```
## User-facing changes (Release notes)
Fixed row conditions (`where`, `any`, `all`, `take while` and the
others) so a bare column name after `and`, `or` or `xor` refers to the
column, the same as the first term:
```nushell
[{a: false, b: false}] | where not a and not b # was a "can't convert string to boolean" error
[{a: true, b: true}] | where a and b # was "'and' does not work on values of type 'string'"
```
## Additional notes
<!--
Optional.
Examples:
- fixes #123
- closes #456
- related #789
Anything else reviewers should know.
Remove this section if not needed.
-->
|
||
|
|
b862a8121b |
Add type aliases with a type keyword (#19223)
## Description This PR adds `type Name = <type>` (#13484, and the type-alias part of #11108). A type alias gives a name to a type, and the parser replaces the name with that type wherever it appears. ```nushell type LsType = table<name: string, type: string, size: filesize, modified: datetime> def my-ls []: nothing -> LsType { ls } def process-files [files: LsType] { $files | where size > 1mb } ``` How it works: - An alias is pure expansion. The parser stores the right-hand side as a `SyntaxShape` and copies it at every use. `Type`, `SyntaxShape`, `describe` and the plugin protocol don't change, and `help`, `scope commands` and error messages show the expanded type. - An alias works in parameters, flags, rest parameters, closure parameters, input/output types, `let`/`mut`/`const` annotations, inside generic types such as `list<Point>`, and on the right-hand side of another `type`. - A completer stays on the parameter, unlike the `string@animals` sketch in #13484: `def paint [c: Color@[red green blue]]`. `type Color = string@[red green blue]` is an error, "Unexpected custom completer in type spec", as in a `let` annotation. Most places an alias can appear have no completer, such as `list<Color>`, input/output types and `let`, so one stored on the alias would apply in some uses and silently not in others. - Aliases are defined in order, like `alias` and `const`. Using one above its definition is an error that points at both places, and an alias can't refer to itself. - Scoping follows `alias` and `const`: local to a block, private in a module unless exported, and kept across REPL lines. - `export type` exports an alias. `use mod Name`, `use mod [Name]`, `use mod *`, `export use` and an unprefixed `overlay use` import it. A bare `use mod` doesn't, because a type name can't take the `mod ` prefix that commands get. - `type` and `export type` are reserved like `def`, `alias` and `const`. A `def type`, `extern "type"` or `alias type = ...` fails with "Can't use parser keyword `type` as command name", and `alias ty = type` is an error. #13484 asked for existing `type` commands to keep working; reserving the name breaks them, but at the definition, with an error that names it. A keyword that a `type` command could shadow fails later: every `type Foo = int` after it becomes "Assignment operations require a variable". nu_scripts' generated `custom-completions/auto-generate/completions/type.nu` declares `extern "type"`, so `source`-ing it is one way to hit that. ## User-facing changes (Release notes) You can now name a type with `type`: ```nushell type Point = record<x: float, y: float> type Polygon = list<Point> def first-x [poly: Polygon]: nothing -> float { $poly.0.x } ``` A type alias can be used anywhere a type annotation can, including inside other types. A parameter of an aliased type takes a completer like any other: `def paint [color: Color@[red green blue]]`. Export an alias from a module with `export type`, and import it by name, in a list, or with `*`. `type` is now a reserved word, like `def` and `let`. A script that defines its own `type` command, alias or extern stops with "Can't use parser keyword `type` as command name" until that definition is renamed. On macOS, a bare `type ls` no longer runs `/usr/bin/type`. Use `^type`, or nushell's `which`. ## Additional notes |
||
|
|
818d4ac064 |
update eml-parser version to 0.1.6 (#19257)
<!-- Thanks for contributing to Nushell! Before submitting, please read the contributing guide: https://github.com/nushell/nushell/blob/main/CONTRIBUTING.md This template helps reviewers understand your changes and allows us to generate high-quality release notes. --> ## Description <!-- Explain what this PR does and why. This section is intentionally flexible: - Describe the problem - Explain your approach - Include technical details if relevant Good examples: - "In this PR, I fixed..." - "In this PR, I added support for..." - "This change improves X by..." Write as much or as little as needed for reviewers to understand your changes. --> eml-parser updated from v0.1.5 to v0.1.6. this includes a bugfix for parsing mail addresses in email headers in the `from eml` command (From: To: etc.) https://github.com/aeshirey/EmlParser/pull/18 ## User-facing changes (Release notes) <!-- This section is used (mostly as-is) for https://www.nushell.sh/blog/ Describe how Nushell behavior changes from a user's perspective. Do NOT describe internal Rust changes here. Write in a release note style, for example: - "Added support for..." - "Fixed an issue where..." - "Nushell now supports..." - "Improved performance of..." If your changes do NOT affect users (internal refactors, cleanup, etc.), just write: - "n/a" - "nan" - or similar This tells us the change should not appear in the changelog. Tips: - Focus on observable behavior - Include examples if helpful - Keep it concise You can: - Write a short paragraph (will appear as a bullet point), OR - Use headings (###) if your change needs more structure Avoid writing things like: - "In this PR, I refactored..." - "This updates internal code..." You may leave this blank until the PR is ready. --> emails with unquoted names are now parsed into name-address records instead of plain strings. ## Additional Info input / output behaviour: | Input | Current behavior | New behavior | |---|---|---| | `"john doe" <john.doe@johnmail.com>` | `{ name: "john doe", address: "john.doe@johnmail.com" }` | `{ name: "john doe", address: "john.doe@johnmail.com" }` (unchanged) | | `john.doe@johnmail.com` | `{ name: "", address: "john.doe@johnmail.com" }` | `{ name: "", address: "john.doe@johnmail.com" }` (unchanged) | | `john doe <john.doe@johnmail.com>` | `"john.doe <john.doe@johnmail.com>"` (plain string) | `{ name: "john doe", address: "john.doe@johnmail.com" }` | while the new behaviour is "correct", it may be a breaking change for many users (including my own scripts) which expect senders / recipients to be parsed as plain strings. i still think this to be the correct thing to do. |
||
|
|
701dc77c9e |
fix(cli): accept /c as commands flag (#19148)
## Description Windows programs that use `ComSpec` commonly call the configured shell with `/c` to run a command. When `ComSpec` points to `nu.exe`, Nushell treated `/c` as a script path and reported that it could not open `/c`. On Windows, `/c` and `/C` are now recognized during CLI argument parsing as the ComSpec command switch. The text after `/c` is read from the raw process command line (`GetCommandLineW`) so the original quoting is preserved, and that text is run as Nushell code. This mirrors how `cmd /c` runs the rest of the command line, rather than Nushell's `-c`, which takes a single code argument. When the raw command line is unavailable, the remaining argv entries are joined with spaces as a best effort. This behavior is Windows-only. On other platforms `/c` remains a normal path, and `/c` after the `--` end-of-options delimiter is always treated as a script name. ## User-facing changes (Release notes) On Windows, Nushell now accepts `/c` and `/C` as the ComSpec command switch and runs the following command line as Nushell code, improving compatibility when `nu.exe` is used as `ComSpec`. This change does not affect other platforms. ## Additional notes Fixes #7993 Tests: - `cargo test -p nu --bin nu slash_c` - `cargo test -p nu --test tests log_` |
||
|
|
684d24b0ba |
fix(std/help): preserve external help arguments (#19149)
## Description `std/help` falls back to an external helper, usually `man` or `$env.NU_HELPER`, when the requested help target is not an internal command, alias, or module. Before this change, the fallback joined all requested words into one string and stripped every `^` and `%` from the target name. That broke multi-word external help targets and changed names such as `test-%.nu` into `test-.nu`. This change keeps the command target as separate words and strips only one leading `^` or `%` sigil from the first word. ## User-facing changes (Release notes) Fixed `std/help` external fallback so multi-word help targets are passed as separate arguments and `%` or `^` characters inside command names are preserved. ## Additional notes Fixes #18939 Tests: - `cargo run -- -c 'use crates/nu-std/testing.nu; testing run-tests --path crates/nu-std/tests --test external_help'` |
||
|
|
6a4027ff14 |
Fix conditional tutor text typos (#19218)
<!-- Thanks for contributing to Nushell! Before submitting, please read the contributing guide: https://github.com/nushell/nushell/blob/main/CONTRIBUTING.md This template helps reviewers understand your changes and allows us to generate high-quality release notes. --> ## Description <!-- Explain what this PR does and why. This section is intentionally flexible: - Describe the problem - Explain your approach - Include technical details if relevant Good examples: - "In this PR, I fixed..." - "In this PR, I added support for..." - "This change improves X by..." Write as much or as little as needed for reviewers to understand your changes. --> `tutor conditional` was introduced in 0.116.0 with these description text typos, which are now fixed. ## User-facing changes (Release notes) <!-- This section is used (mostly as-is) for https://www.nushell.sh/blog/ Describe how Nushell behavior changes from a user's perspective. Do NOT describe internal Rust changes here. Write in a release note style, for example: - "Added support for..." - "Fixed an issue where..." - "Nushell now supports..." - "Improved performance of..." If your changes do NOT affect users (internal refactors, cleanup, etc.), just write: - "n/a" - "nan" - or similar This tells us the change should not appear in the changelog. Tips: - Focus on observable behavior - Include examples if helpful - Keep it concise You can: - Write a short paragraph (will appear as a bullet point), OR - Use headings (###) if your change needs more structure Avoid writing things like: - "In this PR, I refactored..." - "This updates internal code..." You may leave this blank until the PR is ready. --> `tutor conditional` description text no longer has wording typos. ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> The 0.116.0 release notes list the command output. IMO it can stay "wrong" to match the version behavior. |
||
|
|
f443a4fbe4 |
build(deps): bump uuid from 1.27.0 to 1.28.0 (#19245)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.27.0 to 1.28.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>v1.28.0</h2> <h2>What's Changed</h2> <ul> <li>Add optional serde format adapters by <a href="https://github.com/RanaPriyansh"><code>@RanaPriyansh</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/916">uuid-rs/uuid#916</a></li> <li>Prepare for 1.28.0 release by <a href="https://github.com/KodrAus"><code>@KodrAus</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/918">uuid-rs/uuid#918</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/RanaPriyansh"><code>@RanaPriyansh</code></a> made their first contribution in <a href="https://redirect.github.com/uuid-rs/uuid/pull/916">uuid-rs/uuid#916</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/uuid-rs/uuid/compare/v1.27.0...v1.28.0">https://github.com/uuid-rs/uuid/compare/v1.27.0...v1.28.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/uuid-rs/uuid/commit/276c23628a669ca9fca637f3326c21b114e88049"><code>276c236</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/918">#918</a> from uuid-rs/cargo/v1.28.0</li> <li><a href="https://github.com/uuid-rs/uuid/commit/4b3b9f55260d402ed3184577bc35a054ba9a28f4"><code>4b3b9f5</code></a> prepare for 1.28.0 release</li> <li><a href="https://github.com/uuid-rs/uuid/commit/cbf9c818b89754a83d4ca54f2a9bf809e2476f67"><code>cbf9c81</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/916">#916</a> from RanaPriyansh/fix/optional-serde-adapters-840</li> <li><a href="https://github.com/uuid-rs/uuid/commit/784a0229388c3df8d729eb212f0580d2617191b2"><code>784a022</code></a> Inline expected tokens in optional compact serde test</li> <li><a href="https://github.com/uuid-rs/uuid/commit/a5678c3156831969fbd4573b7afdd0585d88e3a1"><code>a5678c3</code></a> Simplify optional serde adapter tests to option tokens</li> <li><a href="https://github.com/uuid-rs/uuid/commit/638a5180ba347d52cd7eb60518dc751b1dfb2f80"><code>638a518</code></a> Refactor optional serde adapter tests and share byte wrapper</li> <li><a href="https://github.com/uuid-rs/uuid/commit/654fa5b891d0346055d9d234599f80b06cf03a1c"><code>654fa5b</code></a> Add optional serde format adapters</li> <li>See full diff in <a href="https://github.com/uuid-rs/uuid/compare/v1.27.0...v1.28.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
4dd122d388 |
build(deps): bump lean_string from 0.7.0 to 0.8.0 (#19241)
Bumps [lean_string](https://github.com/ryota2357/lean_string) from 0.7.0 to 0.8.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ryota2357/lean_string/blob/main/CHANGELOG.md">lean_string's changelog</a>.</em></p> <blockquote> <h2>[0.8.0] - 2026-10-11</h2> <h3>Added</h3> <ul> <li>Case conversion methods: <code>to_lowercase()</code>, <code>to_uppercase()</code>, <code>to_ascii_lowercase()</code> and <code>to_ascii_uppercase()</code> for <code>LeanString</code> and <code>LeanStr</code>, and <code>make_ascii_lowercase()</code> and <code>make_ascii_uppercase()</code> for <code>LeanString</code>. The ASCII ones have fallible <code>try_</code> variants. If no character changes, they don't allocate: the <code>to_</code> methods return a clone, and the <code>make_</code> methods leave the string untouched, even if it is shared with its clones.</li> <li><code>LeanString::replace_range()</code>, <code>LeanString::extend_from_within()</code> and <code>LeanString::reserve_exact()</code>, with their fallible <code>try_</code> variants.</li> <li><code>LeanStr::repeat()</code> and <code>LeanStr::try_repeat()</code>.</li> <li><code>from_utf16le()</code>, <code>from_utf16be()</code>, <code>from_utf16le_lossy()</code> and <code>from_utf16be_lossy()</code> for <code>LeanString</code> and <code>LeanStr</code>, to decode UTF-16 from bytes.</li> <li><code>as_static_str()</code> for <code>LeanString</code> and <code>LeanStr</code>, which returns the underlying <code>&'static str</code> if the string holds one.</li> <li>Conversions from and to more types: <ul> <li><code>From<&mut str></code> for <code>LeanString</code> and <code>LeanStr</code>.</li> <li><code>From<&LeanString></code> for <code>LeanStr</code> and <code>From<&LeanStr></code> for <code>LeanString</code>.</li> <li><code>From<LeanString></code>, <code>From<LeanStr></code>, <code>From<&LeanString></code> and <code>From<&LeanStr></code> for <code>Cow<'_, str></code>. A string holding a <code>&'static str</code> converts into <code>Cow::Borrowed</code> without allocating.</li> <li><code>FromIterator<LeanStr></code> for <code>LeanString</code>, <code>FromIterator<LeanString></code> for <code>LeanStr</code>, and <code>FromIterator<LeanString></code> and <code>FromIterator<LeanStr></code> for <code>String</code>.</li> <li><code>AsRef<Path></code> for <code>LeanString</code> and <code>LeanStr</code>, with the <code>std</code> feature.</li> </ul> </li> </ul> <h3>Changed</h3> <ul> <li>The MSRV is now Rust 1.88.0 (was 1.85.1).</li> <li><strong>Breaking:</strong> <code>to_lowercase()</code>, <code>to_uppercase()</code>, <code>to_ascii_lowercase()</code> and <code>to_ascii_uppercase()</code> of <code>LeanString</code> and <code>LeanStr</code>, and <code>LeanStr::repeat()</code>, now return <code>LeanString</code> or <code>LeanStr</code> instead of <code>String</code>. They were previously resolved to the <code>str</code> methods through <code>Deref</code>.</li> <li><strong>Breaking:</strong> <code>FromUtf16Error</code> now matches <code>std</code>'s <code>FromUtf16Error</code>: it can no longer be constructed outside this crate, and its message tells a lone surrogate from an odd number of bytes.</li> <li>Added <code>#[must_use]</code> to constructors, getters and methods that return a new string, which may produce new warnings where their result is discarded.</li> <li>Modifying a string that shares its heap buffer with its clones now copies it into the inline storage, rather than a new heap buffer, if its contents fit there (e.g. after <code>truncate()</code>).</li> <li><code>retain()</code> no longer copies a string shared with its clones or created from a <code>&'static str</code> when the predicate keeps every character.</li> <li>Creating a string short enough to be stored inline is even faster on 64-bit little-endian targets, as it is now assembled in registers instead of copied with <code>memcpy</code> (about 2x for lengths near the inline limit on aarch64, and about 5x for most lengths on x86_64).</li> <li>Creating a string from a <code>char</code> is several times faster, as it is also built in registers.</li> <li><code>push()</code> and <code>insert()</code> of a <code>char</code>, and creating a heap-allocated string slightly over the inline limit from a <code>&str</code>, no longer call <code>memcpy</code> to copy the bytes.</li> <li><code>repeat()</code> fills the result by doubling the copied part instead of appending the string <code>n</code> times, which is much faster for a short string repeated many times.</li> <li>With the <code>serde</code> feature, deserializing <code>LeanString</code> and <code>LeanStr</code> asks the deserializer for a <code>&str</code> rather than an owned <code>String</code>, which may save an intermediate allocation with some formats.</li> </ul> <h3>Fixed</h3> <ul> <li><code>try_to_lean_string()</code> and <code>try_to_lean_str()</code> panicked on allocation failure for values converted through their <code>Display</code> implementation, instead of returning an error.</li> <li>A panic in <code>From<Cow<'_, str>></code> for <code>LeanString</code> and <code>LeanStr</code> now reports the caller's location.</li> <li>Corrected the documentation of <code>capacity()</code>, <code>shrink_to_fit()</code>, <code>shrink_to()</code> and <code>clear()</code> for strings created from a <code>&'static str</code>.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ryota2357/lean_string/commit/bf326fa5d9dfb848860ed46b1618fec51076d187"><code>bf326fa</code></a> v0.8.0</li> <li><a href="https://github.com/ryota2357/lean_string/commit/023ff048de562274f8f5a53f3aa97af65b27a9e9"><code>023ff04</code></a> chore: update deps</li> <li><a href="https://github.com/ryota2357/lean_string/commit/99b2573274bcadf10ab222723cc8c052151fdc4c"><code>99b2573</code></a> perf: outline grow path in push_str</li> <li><a href="https://github.com/ryota2357/lean_string/commit/8d0868ad7a2304c5c22bcd3b45e86d190cc8e9b1"><code>8d0868a</code></a> perf: add from_char benchmark</li> <li><a href="https://github.com/ryota2357/lean_string/commit/1fedeb4713a51e5ee23ca8ee18d9cb35b3d78234"><code>1fedeb4</code></a> docs: add performance mention to README Properties</li> <li><a href="https://github.com/ryota2357/lean_string/commit/acd13ba30194dd80ee8235394189f9816fc9a7dd"><code>acd13ba</code></a> docs: explain why Repr::as_bytes is compiled to a branch on x86</li> <li><a href="https://github.com/ryota2357/lean_string/commit/c2c6ff56ec6762428ea05c3724f0771d868369b5"><code>c2c6ff5</code></a> feat: add LeanString::{try_,}extend_from_within</li> <li><a href="https://github.com/ryota2357/lean_string/commit/479ce9113577c6e62cbdc877cdf3ef4c542fc129"><code>479ce91</code></a> docs: fix inaccurate statements in README and API docs</li> <li><a href="https://github.com/ryota2357/lean_string/commit/12948a658d9ce3a6b2e021ed1541064198ea19e7"><code>12948a6</code></a> perf: copy text just over the inline size without going through memcpy in Hea...</li> <li><a href="https://github.com/ryota2357/lean_string/commit/5b98e5b4265b3b809c42beb9c318efeec717c0bb"><code>5b98e5b</code></a> perf: insert a char without going through memcpy</li> <li>Additional commits viewable in <a href="https://github.com/ryota2357/lean_string/compare/v0.7.0...v0.8.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
8739de4fd5 |
build(deps): bump similar from 3.1.0 to 3.2.0 (#18905)
Bumps [similar](https://github.com/mitsuhiko/similar) from 3.1.0 to 3.2.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/mitsuhiko/similar/blob/main/CHANGELOG.md">similar's changelog</a>.</em></p> <blockquote> <h2>3.2.0</h2> <ul> <li>Added structured, line-oriented three-way merging through <code>TextMerge</code>, with merge and diff3 conflict output, configurable labels and marker sizes, owned and borrowed inputs, byte output, and whitespace-insensitive comparison.</li> <li>Added <code>WhitespaceMode</code> and <code>TextDiffConfig::whitespace_mode</code> for Git-style line comparisons that ignore changes in whitespace (<code>-b</code>) or all whitespace (<code>-w</code>).</li> <li>Changed <code>Algorithm::Myers</code> to reduce unmatched/confusing records and use Git-style bounded, non-minimal splits on expensive searches, and added <code>Algorithm::RawMyers</code> for the previous shortest-edit-script behavior without output-changing heuristics.</li> <li>Improved heuristics and performance for most algorithms other than LCS.</li> <li>Improved large-input performance by avoiding quadratic Histogram scans.</li> </ul> <h2>3.1.2</h2> <ul> <li>Fixed <code>Algorithm::Lcs</code> deadline fallback emitting edits twice, which produced out-of-bounds <code>DiffOp</code> ranges and panics when consuming timed-out diffs. <a href="https://redirect.github.com/mitsuhiko/similar/issues/97">#97</a></li> <li>Fixed <code>Algorithm::Lcs</code> reporting identical subranges with zero-based indices instead of preserving the supplied range offsets. <a href="https://redirect.github.com/mitsuhiko/similar/issues/98">#98</a></li> <li>Fixed <code>Algorithm::Lcs</code> and <code>Algorithm::Hunt</code> emitting zero-length delete operations when both inputs are empty. <a href="https://redirect.github.com/mitsuhiko/similar/issues/99">#99</a></li> </ul> <h2>3.1.1</h2> <ul> <li>Fixed <code>DiffOp</code> cursor positions when compacting adjacent inserts/deletes and in <code>Algorithm::Histogram</code> full-replacement output, ensuring operations form contiguous ranges. <a href="https://redirect.github.com/mitsuhiko/similar/issues/95">#95</a></li> <li>Renamed sample diff input files to a lexicographic <code>caseNN.01.before_*</code> / <code>caseNN.02.after_*</code> scheme.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/mitsuhiko/similar/commit/e3804055b844f5d0c3cb111f5f6276f60e07459a"><code>e380405</code></a> chore(release): prepare 3.2.0</li> <li><a href="https://github.com/mitsuhiko/similar/commit/9133b3d1e4799f984d178f6bda28806f910ddd1e"><code>9133b3d</code></a> ref: Update changelog</li> <li><a href="https://github.com/mitsuhiko/similar/commit/a56a53f4408cf50a0b3dd875d15f5075e187ae7d"><code>a56a53f</code></a> feat(merge): add three-way text merging</li> <li><a href="https://github.com/mitsuhiko/similar/commit/7130d064d5ed5f27bf8e9a8c5594e754f21405db"><code>7130d06</code></a> docs(examples): demonstrate whitespace-insensitive diffs</li> <li><a href="https://github.com/mitsuhiko/similar/commit/a635843e774d28f32778b4c0fe77f6485dab9a9f"><code>a635843</code></a> feat(text): add whitespace-insensitive line diffs</li> <li><a href="https://github.com/mitsuhiko/similar/commit/6301178fc0bf7f19af93b87cf270433f5f712580"><code>6301178</code></a> perf(myers): preserve sparse matches with record reduction</li> <li><a href="https://github.com/mitsuhiko/similar/commit/f16b309a57cba043570a5a1426bd5c17de2f544a"><code>f16b309</code></a> perf(myers): add bounded heuristic search</li> <li><a href="https://github.com/mitsuhiko/similar/commit/accea7d2ffb976515b21931a3a465e9082249c65"><code>accea7d</code></a> chore(clippy): resolve lint warnings</li> <li><a href="https://github.com/mitsuhiko/similar/commit/3a5162b43e3841350de703f67aef159ae74c00be"><code>3a5162b</code></a> perf(algorithms): fast-path nearly disjoint ranges</li> <li><a href="https://github.com/mitsuhiko/similar/commit/fc32411398e13d30ab3d45852a2bb9c2f9a056b9"><code>fc32411</code></a> feat(fuzzing): add isolated performance campaign runner</li> <li>Additional commits viewable in <a href="https://github.com/mitsuhiko/similar/compare/3.1.0...3.2.0">compare view</a></li> </ul> </details> <br /> > **Note** > Automatic rebases have been disabled on this pull request as it has been open for over 30 days. Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
c4c1aebfc2 |
build(deps): bump unicase from 2.9.0 to 2.10.0 (#19240)
Bumps [unicase](https://github.com/seanmonstar/unicase) from 2.9.0 to 2.10.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/seanmonstar/unicase/releases">unicase's releases</a>.</em></p> <blockquote> <h2>v2.10.0</h2> <h2>What's Changed</h2> <ul> <li>Miscellaneous code cleanups by <a href="https://github.com/Jules-Bertholet"><code>@Jules-Bertholet</code></a> in <a href="https://redirect.github.com/seanmonstar/unicase/pull/84">seanmonstar/unicase#84</a></li> <li>fix: yield three-character case folds in order by <a href="https://github.com/yuxi-liu-wired"><code>@yuxi-liu-wired</code></a> in <a href="https://redirect.github.com/seanmonstar/unicase/pull/85">seanmonstar/unicase#85</a></li> <li>update to Unicode v18.0.0 by <a href="https://github.com/seanmonstar"><code>@seanmonstar</code></a> in <a href="https://redirect.github.com/seanmonstar/unicase/pull/86">seanmonstar/unicase#86</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/Jules-Bertholet"><code>@Jules-Bertholet</code></a> made their first contribution in <a href="https://redirect.github.com/seanmonstar/unicase/pull/84">seanmonstar/unicase#84</a></li> <li><a href="https://github.com/yuxi-liu-wired"><code>@yuxi-liu-wired</code></a> made their first contribution in <a href="https://redirect.github.com/seanmonstar/unicase/pull/85">seanmonstar/unicase#85</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/seanmonstar/unicase/compare/v2.9.0...v2.10.0">https://github.com/seanmonstar/unicase/compare/v2.9.0...v2.10.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/seanmonstar/unicase/commit/1e739ff80fe2297c52efda9d05f0bea1038a7eb9"><code>1e739ff</code></a> v2.10.0</li> <li><a href="https://github.com/seanmonstar/unicase/commit/8813777f65b604b8b82022c5b05be83f29638260"><code>8813777</code></a> update to Unicode v18.0.0 (<a href="https://redirect.github.com/seanmonstar/unicase/issues/86">#86</a>)</li> <li><a href="https://github.com/seanmonstar/unicase/commit/afc3c16219c9720839f2f4c16a3ede52274df7d7"><code>afc3c16</code></a> fix: yield three-character case folds in order (<a href="https://redirect.github.com/seanmonstar/unicase/issues/85">#85</a>)</li> <li><a href="https://github.com/seanmonstar/unicase/commit/a8cbb74c20f05b2d5a89b3e43c89591a1871be4b"><code>a8cbb74</code></a> Miscellaneous code cleanups (<a href="https://redirect.github.com/seanmonstar/unicase/issues/84">#84</a>)</li> <li>See full diff in <a href="https://github.com/seanmonstar/unicase/compare/v2.9.0...v2.10.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
a58b75827c |
build(deps): bump vedantmgoyal2009/winget-releaser from 4ffc7888bffd451b357355dc214d43bb9f23917e to b7370d4d152efdce803a26cc6ca9eee58cb2ad54 (#19244)
Bumps [vedantmgoyal2009/winget-releaser](https://github.com/vedantmgoyal2009/winget-releaser) from 4ffc7888bffd451b357355dc214d43bb9f23917e to b7370d4d152efdce803a26cc6ca9eee58cb2ad54. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/b7370d4d152efdce803a26cc6ca9eee58cb2ad54"><code>b7370d4</code></a> docs(funding): remove patreon</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/f29ed1ffd34f91223a2aebaa71beaab0901ff9fd"><code>f29ed1f</code></a> docs: add Gedochao as a contributor for bug, code, and ideas (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/350">#350</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/c3648cc8cb02c1c6e612d8e87f7699142a34f1fe"><code>c3648cc</code></a> fix: add missing shell property, rm undefined variable (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/346">#346</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/8e1180065275ff8d815d981788ee8592c8735b8c"><code>8e11800</code></a> docs: add ReenigneArcher as a contributor for ideas (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/344">#344</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/d381fbbc8929b1fd92abcdd031ee0cff7bd517cd"><code>d381fbb</code></a> feat: mv action logic to pwsh, pr url output, support repos across owners (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/343">#343</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/a8fff44b123f115ce4c21543edf8b677376fc7e0"><code>a8fff44</code></a> docs: update required permissions (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/341">#341</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/b3a5dae0047c6180023acba3f548c55fdf6b7193"><code>b3a5dae</code></a> docs: fix allcontributors.com emoji key link (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/340">#340</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/7bd472be23763def6e16bd06cc8b1cdfab0e2fd5"><code>7bd472b</code></a> docs: add description to inputs (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/335">#335</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/a43926ed822e5a076ac8a81e0a794915cbad51d1"><code>a43926e</code></a> fix: cargo command not found in <code>ubuntu-slim</code> runner (<a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/334">#334</a>)</li> <li><a href="https://github.com/vedantmgoyal9/winget-releaser/commit/19e706d4c9121098010096f9c495a70a7518b30f"><code>19e706d</code></a> fix: pwsh doesn't sort sometimes (resolves <a href="https://redirect.github.com/vedantmgoyal2009/winget-releaser/issues/323">#323</a>)</li> <li>Additional commits viewable in <a href="https://github.com/vedantmgoyal2009/winget-releaser/compare/4ffc7888bffd451b357355dc214d43bb9f23917e...b7370d4d152efdce803a26cc6ca9eee58cb2ad54">compare view</a></li> </ul> </details> <br /> 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 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> |
||
|
|
fc518c96d5 |
build(deps): bump actions/upload-artifact from 7.0.1 to 7.0.2 (#19242)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's releases</a>.</em></p> <blockquote> <h2>v7.0.2</h2> <h2>What's Changed</h2> <ul> <li>Improves artifact download retries when the service returns HTTP 429 (rate limiting), including honoring valid Retry-After headers.</li> <li>Updates <code>@actions/artifact</code> to v6.3.1.</li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/tunc-d"><code>@tunc-d</code></a> made their first contribution in <a href="https://redirect.github.com/actions/upload-artifact/pull/821">actions/upload-artifact#821</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/upload-artifact/compare/v7.0.1...v7.0.2">https://github.com/actions/upload-artifact/compare/v7.0.1...v7.0.2</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/upload-artifact/commit/cf430e030ddbb5b0abf93d22962f4752f3646cd9"><code>cf430e0</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/822">#822</a> from actions/tunc-d-prepare-upload-v7-0-2</li> <li><a href="https://github.com/actions/upload-artifact/commit/c2acdedd35a8824a1552c7137f8c18288c3ea469"><code>c2acded</code></a> chore: prepare v7.0.2 release</li> <li><a href="https://github.com/actions/upload-artifact/commit/4687c1bbaa0a58abb517d90b4bbade6754c80c1a"><code>4687c1b</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/821">#821</a> from actions/tunc-d-upload-artifact-package-bump</li> <li><a href="https://github.com/actions/upload-artifact/commit/8cbe1bebdb858105d8fdd88f81404d4de4595719"><code>8cbe1be</code></a> Bump <code>@actions/artifact</code> to 6.3.1</li> <li>See full diff in <a href="https://github.com/actions/upload-artifact/compare/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a...cf430e030ddbb5b0abf93d22962f4752f3646cd9">compare view</a></li> </ul> </details> <br /> [](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 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> |
||
|
|
46042eced5 |
build(deps): bump taiki-e/install-action from 2.87.24 to 2.87.27 (#19243)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.87.24 to 2.87.27. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's releases</a>.</em></p> <blockquote> <h2>2.87.27</h2> <ul> <li> <p>Update <code>vacuum@latest</code> to 0.32.0.</p> </li> <li> <p>Update <code>uv@latest</code> to 0.12.24.</p> </li> <li> <p>Update <code>typos@latest</code> to 1.51.1.</p> </li> <li> <p>Update <code>tombi@latest</code> to 1.7.3.</p> </li> <li> <p>Update <code>syft@latest</code> to 1.54.1.</p> </li> <li> <p>Update <code>release-plz@latest</code> to 0.3.170.</p> </li> <li> <p>Update <code>mise@latest</code> to 2026.10.4.</p> </li> <li> <p>Update <code>kingfisher@latest</code> to 2.11.1.</p> </li> <li> <p>Update <code>hyperfine@latest</code> to 2.0.0.</p> </li> <li> <p>Update <code>dprint@latest</code> to 0.61.1.</p> </li> <li> <p>Update <code>cargo-nextest@latest</code> to 0.9.148.</p> </li> <li> <p>Update <code>cargo-neat@latest</code> to 0.6.0.</p> </li> <li> <p>Update <code>cargo-binstall@latest</code> to 1.25.2.</p> </li> </ul> <h2>2.87.26</h2> <ul> <li> <p>Update <code>tombi@latest</code> to 1.7.2.</p> </li> <li> <p>Update <code>prek@latest</code> to 0.5.5.</p> </li> <li> <p>Update <code>mise@latest</code> to 2026.10.3.</p> </li> <li> <p>Update <code>kache@latest</code> to 1.0.0.</p> </li> <li> <p>Update <code>hyperfine@latest</code> to 1.21.0.</p> </li> </ul> <h2>2.87.25</h2> <ul> <li> <p>Update <code>uv@latest</code> to 0.12.23.</p> </li> <li> <p>Update <code>mise@latest</code> to 2026.10.2.</p> </li> <li> <p>Update <code>kingfisher@latest</code> to 2.10.0.</p> </li> <li> <p>Update <code>dprint@latest</code> to 0.60.1.</p> </li> <li> <p>Update <code>cargo-semver-checks@latest</code> to 0.51.0.</p> </li> <li> <p>Update <code>cargo-binstall@latest</code> to 1.25.1.</p> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <p>All notable changes to this project will be documented in this file.</p> <p>This project adheres to <a href="https://semver.org">Semantic Versioning</a>.</p> <!-- raw HTML omitted --> <h2>[Unreleased]</h2> <h2>[2.87.28] - 2026-10-12</h2> <ul> <li> <p>Update <code>dprint@latest</code> to 0.62.0.</p> </li> <li> <p>Update <code>vacuum@latest</code> to 0.33.0.</p> </li> <li> <p>Update <code>uv@latest</code> to 0.13.0.</p> </li> <li> <p>Update <code>tombi@latest</code> to 1.8.1.</p> </li> <li> <p>Update <code>release-plz@latest</code> to 0.3.171.</p> </li> <li> <p>Update <code>rclone@latest</code> to 1.75.2.</p> </li> <li> <p>Update <code>mise@latest</code> to 2026.10.7.</p> </li> <li> <p>Update <code>cargo-binstall@latest</code> to 1.25.3.</p> </li> </ul> <h2>[2.87.27] - 2026-10-09</h2> <ul> <li> <p>Update <code>vacuum@latest</code> to 0.32.0.</p> </li> <li> <p>Update <code>uv@latest</code> to 0.12.24.</p> </li> <li> <p>Update <code>typos@latest</code> to 1.51.1.</p> </li> <li> <p>Update <code>tombi@latest</code> to 1.7.3.</p> </li> <li> <p>Update <code>syft@latest</code> to 1.54.1.</p> </li> <li> <p>Update <code>release-plz@latest</code> to 0.3.170.</p> </li> <li> <p>Update <code>mise@latest</code> to 2026.10.4.</p> </li> <li> <p>Update <code>kingfisher@latest</code> to 2.11.1.</p> </li> <li> <p>Update <code>hyperfine@latest</code> to 2.0.0.</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/taiki-e/install-action/commit/ab6895351a88b908e96a4697860d4ffea5e57dbe"><code>ab68953</code></a> Release 2.87.27</li> <li><a href="https://github.com/taiki-e/install-action/commit/62530fde5eae2d21742c80f8d06d4ddc2e1fc849"><code>62530fd</code></a> Update <code>vacuum@latest</code> to 0.32.0</li> <li><a href="https://github.com/taiki-e/install-action/commit/f684ea4ef45b30adbd27018b3a8c8eff832d693e"><code>f684ea4</code></a> Update <code>uv@latest</code> to 0.12.24</li> <li><a href="https://github.com/taiki-e/install-action/commit/8aa87a079f6df0fefe32ea81cbf89957adfc4fb2"><code>8aa87a0</code></a> Update <code>typos@latest</code> to 1.51.1</li> <li><a href="https://github.com/taiki-e/install-action/commit/5ffcf4325f316f6461163dbceae21814184cc867"><code>5ffcf43</code></a> Update <code>tombi@latest</code> to 1.7.3</li> <li><a href="https://github.com/taiki-e/install-action/commit/99266369a536fa5485f3e5b59913a332a0af45ff"><code>9926636</code></a> Update <code>syft@latest</code> to 1.54.1</li> <li><a href="https://github.com/taiki-e/install-action/commit/4647f42698f08ac3c2a60181bceea72db3556908"><code>4647f42</code></a> Update <code>release-plz@latest</code> to 0.3.170</li> <li><a href="https://github.com/taiki-e/install-action/commit/df0256079f1b5aae055d9e9826e16e43e37734d1"><code>df02560</code></a> Update rclone manifest</li> <li><a href="https://github.com/taiki-e/install-action/commit/d7c82f4c669484f523dfcd90e184702c32babdb1"><code>d7c82f4</code></a> Update <code>mise@latest</code> to 2026.10.4</li> <li><a href="https://github.com/taiki-e/install-action/commit/a6142d0c42332af2f8b733abb6a554272b9f5880"><code>a6142d0</code></a> Update <code>kingfisher@latest</code> to 2.11.1</li> <li>Additional commits viewable in <a href="https://github.com/taiki-e/install-action/compare/e407f7bafb71fd004bc5c2da3032e5470cbb6ef0...ab6895351a88b908e96a4697860d4ffea5e57dbe">compare view</a></li> </ul> </details> <br /> [](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 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> |
||
|
|
462f3f1436 |
build(deps): bump crate-ci/typos from 1.50.3 to 1.51.1 (#19246)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.50.3 to 1.51.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/crate-ci/typos/releases">crate-ci/typos's releases</a>.</em></p> <blockquote> <h2>v1.51.1</h2> <h2>[1.51.1] - 2026-10-06</h2> <h3>Features</h3> <ul> <li>Add ARM Windows builds</li> </ul> <h2>v1.51.0</h2> <h2>[1.51.0] - 2026-10-06</h2> <h3>Fixes</h3> <ul> <li>Don't correct <code>bimap</code></li> </ul> <h3>Features</h3> <ul> <li>Updated the dictionary with the <a href="https://redirect.github.com/crate-ci/typos/issues/1610">September 2026</a> changes</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/crate-ci/typos/blob/main/CHANGELOG.md">crate-ci/typos's changelog</a>.</em></p> <blockquote> <h1>Change Log</h1> <p>All notable changes to this project will be documented in this file.</p> <p>The format is based on <a href="https://keepachangelog.com/">Keep a Changelog</a> and this project adheres to <a href="https://semver.org/">Semantic Versioning</a>.</p> <!-- raw HTML omitted --> <h2>[Unreleased] - ReleaseDate</h2> <h2>[1.51.1] - 2026-10-06</h2> <h3>Features</h3> <ul> <li>Add ARM Windows builds</li> </ul> <h2>[1.51.0] - 2026-10-06</h2> <h3>Fixes</h3> <ul> <li>Don't correct <code>bimap</code></li> </ul> <h3>Features</h3> <ul> <li>Updated the dictionary with the <a href="https://redirect.github.com/crate-ci/typos/issues/1610">September 2026</a> changes</li> </ul> <h2>[1.50.3] - 2026-09-25</h2> <h3>Fixes</h3> <ul> <li>Don'y panicwhen case-converting non-ASCII corrections</li> </ul> <h2>[1.50.2] - 2026-09-15</h2> <h3>Fixes</h3> <ul> <li>Don't panic when files being examined are removed</li> </ul> <h2>[1.50.1] - 2026-09-01</h2> <h3>Fixes</h3> <ul> <li>Don't correct <code>asend</code> in Python code</li> </ul> <h2>[1.50.0] - 2026-08-28</h2> <h3>Features</h3> <ul> <li>Updated the dictionary with the <a href="https://redirect.github.com/crate-ci/typos/issues/1587">August 2026</a> changes</li> </ul> <h2>[1.49.1] - 2026-08-27</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/crate-ci/typos/commit/7f9d0819ca1c008ade73f4b41fa9d258d48f605b"><code>7f9d081</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/4fc41d700195865b784ee2e1c7fc2edbf0af1620"><code>4fc41d7</code></a> docs: Update changelog</li> <li><a href="https://github.com/crate-ci/typos/commit/eb4f2990517f8eaa0ed4c38c9d30287a52d9a8af"><code>eb4f299</code></a> Merge pull request <a href="https://redirect.github.com/crate-ci/typos/issues/1602">#1602</a> from meop/ci/platform-release-matrix</li> <li><a href="https://github.com/crate-ci/typos/commit/762326537dd08a8022c4491e5c21eccc582e74b9"><code>7623265</code></a> ci: release a win-arm64-msvc artifact</li> <li><a href="https://github.com/crate-ci/typos/commit/cf01e3f0560d97f2bc216d8dc04781d9a2c9f655"><code>cf01e3f</code></a> ci: match any windows runner when staging the release archive</li> <li><a href="https://github.com/crate-ci/typos/commit/dcea7116aaf94953292ab6ce0907fe483ef15406"><code>dcea711</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/73ce3427c24c4aceeb6d79e912a5b75b08fd862d"><code>73ce342</code></a> chore: Release</li> <li><a href="https://github.com/crate-ci/typos/commit/58d970f1aa80cfe709a3a3c33c3927ed433f8508"><code>58d970f</code></a> docs: Update changelog</li> <li><a href="https://github.com/crate-ci/typos/commit/d59c567de648226a873e409ba64c7d0b98f254cc"><code>d59c567</code></a> Merge pull request <a href="https://redirect.github.com/crate-ci/typos/issues/1634">#1634</a> from epage/bimap</li> <li><a href="https://github.com/crate-ci/typos/commit/3689e3c1985b6911bd0748cd2c72648906b65a68"><code>3689e3c</code></a> fix(dict): Remove bimap from being corrected</li> <li>Additional commits viewable in <a href="https://github.com/crate-ci/typos/compare/00f422f3b19c57bc6338715ebfe3316d38768461...7f9d0819ca1c008ade73f4b41fa9d258d48f605b">compare view</a></li> </ul> </details> <br /> [](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 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> |
||
|
|
49ec1fbfc8 |
Bump rustls to 0.23.46 to clear the RustSec audit (#19249)
## Description The `Security audit` job fails again. On 2026-10-14 RustSec filed four advisories against `rustls 0.23.45`, and `rustls 0.23.46` fixes all of them: | Advisory | Issue | | --- | --- | | RUSTSEC-2026-0346 | `Debug` impls for client session values print TLS secrets | | RUSTSEC-2026-0347 | Buffered application data goes to the outer server after an ECH rejection | | RUSTSEC-2026-0348 | Brotli certificate decompression can allocate up to 1 GiB before authentication | | RUSTSEC-2026-0349 | An unauthenticated ServerHello can downgrade later connections to classical key exchange | This PR raises the workspace floor from `~0.23.45` to `~0.23.46`, the same way #19026 did for the last rustls advisory, and runs `cargo update -p rustls`. In `Cargo.lock` only the version and checksum of `rustls` change. Its dependency list stays the same. ## User-facing changes (Release notes) ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
f5affecddc |
Optimize module reloading check (#19228)
Check each module once when deciding whether to reload a cached module ## Description When a module that has already been parsed is imported again, `parse_module_file` calls `module_needs_reloading` to check whether any file in the module's tree has changed on disk. That walk recurses through `submodules` and `imported_modules` without tracking which modules it has visited, so a module reachable through several paths is re-read once per *path*. That's common in practice: a `mod.nu` that `export use`s its sibling files, where most siblings also `use` a few shared helpers. In the repro from the issue, every extra `use nested` of a 9-file module re-reads its files ~133 times; with a real 22-file library it's ~412 reads per import. Linux mostly hides this because file opens are cheap, but on Windows it dominates parse time, and the LSP pays it on every keystroke. This PR adds a `seen` set for the duration of the walk, so each reachable module's file is read at most once per check. Skipping an already-seen module is safe: `any()` short-circuits on the first change, so a module seen again has already been found unchanged. I also extracted the read-and-compare into a separate `module_file_changed` function. Measured on Windows with the repro script from the issue (`nu -n repro.nu`): | importers | before | after | | --------: | -----: | ----: | | 1 | 34.9 ms | 28.4 ms | | 2 | 51.2 ms | 29.2 ms | | 5 | 97.5 ms | 32.4 ms | | 10 | 179.0 ms | 38.3 ms | Per extra importer: **16.0 ms → 1.1 ms**. In my real-world case (a 13-file module importing a 22-file library from most of its files), parsing on Windows went from ~3.1 s to the point where the LSP is responsive again. ## User-facing changes (Release notes) Improved performance when the same module is imported from many places. Nushell no longer re-reads a module's files once for every import path when checking whether a cached module has changed. This especially speeds up parsing and the language server on Windows for libraries whose files import each other. ## Additional notes - fixes #19226 - `cargo test -p nu-parser` and `cargo test --test tests -- modules::` pass; the second runs the module reload tests, including the new `reload_module_reached_through_several_imports`. - Behaviour is unchanged: a modified file anywhere in the tree still triggers a reload. Only repeat visits of the same module within one check are skipped. |
||
|
|
d88d4fe0e1 |
Faster startup: chained fixups on Apple silicon, a cheaper banner, and async prompt pushes that survive (#19236)
## Description Three independent changes make the REPL ready to type into sooner. With the default config, launching `nu` until the first prompt is drawn drops from 15.7 ms to 13.1 ms (−17%). `$nu.startup-time` is measured the same way as before. Measurements: | default config, from `~` | main | this PR | | --- | --- | --- | | launch to first prompt | 15.70 ms | 13.10 ms | | `$nu.startup-time` | 8.03 ms | 7.36 ms | | instructions retired by the first prompt | 149.3M | 119.8M | 1. Change the linker on Apple silicon to `"cargo:rustc-link-arg-bins=-Wl,-fixup_chains"` 2. Make `banner` cheaper (all architectures) 3. Keep prompt pushes that land before the prompt is rebuilt (all architectures) ## User-facing changes (Release notes) - Improved startup time. On Apple silicon Macs, `nu` is now linked with chained fixups, so less work happens before Nushell's own code starts and each `nu` process uses about 3 MiB less memory. The startup banner no longer computes the welcome message when it only prints the startup time. - `date to-timezone` (all architectures) now accepts IANA time zone names in any letter case, for example `date now | date to-timezone america/new_york`. Before, some lowercase names were rejected as invalid. - Background jobs that update the prompt with `commandline set-prompt` (all architectures), started from a `pre_prompt` or `env_change` hook or from a prompt closure such as `$env.PROMPT_COMMAND`, no longer lose that update when they finish before the prompt is drawn. A `commandline set-prompt` called directly inside one of those hooks or prompt closures now also shows on that prompt, in place of the value the prompt variables give that segment. Before, the prompt evaluation that follows the hooks always replaced it. ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
d211796628 |
fix: count closure calls toward recursion_limit so infinite closure recursion errors instead of crashing (#19229)
## Description
A closure that calls itself crashes Nushell:
```nushell
> let M = {|x| do $x $x}
> do $M $M
thread 'main' has overflowed its stack
fatal runtime error: stack overflow, aborting
```
`$env.config.recursion_limit` (default 50) exists for this, but only
custom command calls added to `Stack::recursion_count`. A closure call
copied the caller's count unchanged, so the check at the top of
`eval_ir_block` never fired for closures. The recursion ran until the
Rust stack overflowed and the process aborted.
## User-facing changes (Release notes)
Fixed a crash when a closure recursed without end, for example `let M =
{|x| do $x $x}; do $M $M`. Closure calls (`do`, `each`, `where`, hooks,
and so on) now count toward `$env.config.recursion_limit` the same way
custom command calls do. Deep recursion raises a
`nu::shell::recursion_limit_reached` error instead of overflowing the
stack.
A recursive custom command that calls itself from inside a closure now
uses two levels of the limit per recursion. With the default limit of
50, it stops at 25 levels instead of 50. Raise
`$env.config.recursion_limit` in your config file if you need deeper
recursion.
```nushell
Error: nu::shell::recursion_limit_reached
× Recursion limit (50) reached
╭─[source:1:9]
1 │ let M = {|x| do $x $x}
· ───────┬──────
· ╰── This called itself too many times
2 │ do $M $M
╰────
```
## Additional notes
|
||
|
|
4b60dee2f6 |
fix(gstat): stop wrapping counts and reporting unreadable status as clean, fill ignored and wt_renamed, link libgit2 statically (#19233)
## Description `gstat` gave wrong answers in several situations, all from the plugin's own code rather than from libgit2. I compared it with `git status` on fixture repos (built with git 2.56) and confirmed each case on the 0.116 plugin. ## User-facing changes (Release notes) - `gstat` no longer wraps its counts above 65,535. A repository with 70,000 untracked files used to report 4,464. - When `gstat` can't read a repository's status (a split or sparse index, a damaged index, or a bare repository), the status counts (`idx_*`, `wt_*`, `ignored`, `conflicts`) are now -1 instead of 0, so the repository no longer looks clean. The other fields are still filled. - `gstat` now fills `ignored` (an ignored directory counts once) and `wt_renamed`. A file renamed without `git mv` now counts as one `wt_renamed` instead of one `wt_deleted` plus one `wt_untracked`, and also as `wt_modified` if it was edited after the move. - In a repository with no commits yet, `branch` shows the branch `HEAD` points to instead of `master` or `HEAD`. - `repo_name` is now the name of the working directory in linked worktrees and submodules (it used to be `worktrees` or `modules`) and the repository's own directory name for bare repositories. - The gstat plugin starts faster on systems where it used to link a system libgit2, such as a `cargo install` on macOS with Homebrew's libgit2. ## Additional notes Replacing git2 with gitoxide (`gix`) would make each call about 2x faster, but it adds 60 crates. I measured it separately and left it out of this PR. |
||
|
|
92165027ce |
fix: clarify empty-content access diagnostics (#19234)
## Description AccessEmptyContent now reports "Cannot access empty content." under nu::shell::access_empty_content, labels the span "content is empty", and its resolution note asks the caller to confirm the content has items and try again. Strict-mode tests for first and last assert that code, message, and label for an empty list, an empty list stream, and empty binary, and they reject wording that calls the row or index too large. first and last on empty input report nu::shell::access_beyond_end with the message "Row number too large (empty content)." and a span label "index too large (empty content)." The failure is presented as an index past the end of the input. ShellError::AccessEmptyContent was defined with that beyond-end code, message, and span label. Its docs described the case as an index access on an empty value and told the caller to check lengths. Closes #16034 ## User-facing changes (Release notes) Covered in the summary above. ## Additional notes Nothing beyond what is described above. Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> |
||
|
|
3a4e666326 |
Bump locked dependencies to clear the RustSec audit (#19235)
<!-- Thanks for contributing to Nushell! Before submitting, please read the contributing guide: https://github.com/nushell/nushell/blob/main/CONTRIBUTING.md This template helps reviewers understand your changes and allows us to generate high-quality release notes. --> ## Description The `Security audit` job fails on every PR that touches `Cargo.toml` or `Cargo.lock`, because the advisory database now flags five vulnerabilities in `quinn-proto 0.11.15`. It also raises warnings for unsound and yanked crates. This PR only changes `Cargo.lock`. `cargo update -p` moves each flagged crate to its latest release that is compatible with Rust 1.97.1, and every one of those releases contains the fix: | Crate | Old | New | Advisory | | --- | --- | --- | --- | | `quinn-proto` | 0.11.15 | 0.11.19 | RUSTSEC-2026-0338, -0339, -0340, -0341, -0342 (vulnerabilities) | | `event-listener` | 5.4.1 | 5.4.2 | RUSTSEC-2026-0221 (unsound) | | `memmap2` | 0.9.10 | 0.9.11 | RUSTSEC-2026-0186 (unsound) | | `rand` | 0.8.5 | 0.8.8 | RUSTSEC-2026-0097 (unsound) | | `rand` | 0.9.2 | 0.9.5 | RUSTSEC-2026-0097 (unsound) | | `chacha20` | 0.10.0 | 0.10.2 | yanked | | `der` | 0.8.0 | 0.8.2 | yanked | <!-- Explain what this PR does and why. This section is intentionally flexible: - Describe the problem - Explain your approach - Include technical details if relevant Good examples: - "In this PR, I fixed..." - "In this PR, I added support for..." - "This change improves X by..." Write as much or as little as needed for reviewers to understand your changes. --> ## User-facing changes (Release notes) <!-- This section is used (mostly as-is) for https://www.nushell.sh/blog/ Describe how Nushell behavior changes from a user's perspective. Do NOT describe internal Rust changes here. Write in a release note style, for example: - "Added support for..." - "Fixed an issue where..." - "Nushell now supports..." - "Improved performance of..." If your changes do NOT affect users (internal refactors, cleanup, etc.), just write: - "n/a" - "nan" - or similar This tells us the change should not appear in the changelog. Tips: - Focus on observable behavior - Include examples if helpful - Keep it concise You can: - Write a short paragraph (will appear as a bullet point), OR - Use headings (###) if your change needs more structure Avoid writing things like: - "In this PR, I refactored..." - "This updates internal code..." You may leave this blank until the PR is ready. --> ## Additional notes <!-- Optional. Examples: - fixes #123 - closes #456 - related #789 Anything else reviewers should know. Remove this section if not needed. --> |
||
|
|
3752732c0e |
fix(ci): preserve warnings in nightly release builds (#19232)
fixes: https://github.com/nushell/nushell/issues/19168 Restore the warning policy used before setup-rust-toolchain v2. - Set build-warnings to warn while retaining the pinned v2 action. - Keep static glibc linker warnings visible without failing release builds. Upgrading setup-rust-toolchain to v2 introduced CARGO_BUILD_WARNINGS=deny by default. The existing rustflags: '' no longer disables this policy, causing LoongArch GNU builds to fail on glibc static-linking warnings. Explicitly setting build-warnings: warn restores the previous behavior: warnings remain visible, while actual compilation and linking errors still fail the build. |
||
|
|
b23af9f490 |
open/save: give a clear error suggesting def when the from/to converter is an alias (#19205)
## Description
`open` and `save` pick a converter by name at runtime: `open file.jsonc`
looks up `from jsonc`, and `save file.jsonc` looks up `to jsonc`. When
that name is an alias, for example `alias "from jsonc" = from json`,
both commands call the alias itself. Aliases only exist while parsing,
so this ends in an internal error that asks the user to file an issue:
```
Error: nu::shell::nushell_failed_spanned
× Nushell failed: Can't run alias directly. Unwrap it first.
help: This shouldn't happen. Please file an issue
```
As discussed in this PR, aliases aren't supported as converters. Both
commands now check whether the converter they found is an alias, and if
it is they return a normal error that suggests a `def` instead. The
suggestion reuses the text the alias wraps, so the alias's flags are
kept:
```
Error: nu::shell::error
x Can't open file with alias `from jsonc`
,-[source:1:38]
1 | alias "from jsonc" = from json; open deno.jsonc
: ^^^^^|^^^^
: `-- `from jsonc` is an alias, not a command
`----
help: `open` can only use a command as a converter. Define one with `def`
instead: `def 'from jsonc' [] { from json }`
```
`save` gives the same error. It's raised before anything is written, so
no file is created.
Tests:
- `commands::open::open_with_a_from_alias_suggests_def`: a plain `from`
alias, and one with `--noheaders` to check that the suggested `def`
keeps the flag.
- `commands::save::save_with_a_to_alias_suggests_def`: `alias "to jsonc"
= to json --raw` suggests `def 'to jsonc' [] { to json --raw }` and
doesn't create the file.
`cargo fmt --all`, `cargo nuclippy` and `typos` are clean.
## User-facing changes (Release notes)
`open` and `save` no longer fail with an internal "Nushell failed: Can't
run alias directly" error when the converter for a file's extension is
an alias, such as `alias "from jsonc" = from json`. They now explain
that the converter must be a command and suggest the matching `def`, for
example `def 'from jsonc' [] { from json }`.
## Additional notes
Fixes #18725
---
Reply to fdncred (comment on the PR):
Done. Switched to option 2: `open`/`save` now give a normal error when
the converter is an alias and suggest the equivalent `def` (e.g. `def
'from jsonc' [] { from json }`). I updated the description and tests
too.
|
||
|
|
afc9a5d49f |
fix(tui): error when a closure has no table, tree, or select to follow (#19220)
## Description
A closure on `tui log`, `tui table`, `tui tree`, `tui progress`, or `tui
label` runs on the highlighted row of a table, tree, or select. `--from`
names which one. Without `--from`, the widget follows the focused one,
else the nearest. When there was none, the widget drew empty and the
piped data disappeared.
The closure wasn't ignored. With no row to run on,
`Session::refresh_one` stored `nothing` as the widget's derived value,
and `data_for` returns that before it falls back to the piped data. So
the closure hid the stream.
## User-facing changes (Release notes)
A `tui` widget with a closure and nothing to follow used to draw empty
and hide the piped data. `tui run` and `tui debug` now report an error
that points at that widget's builder: for example when `tui log {|row|
...}` has no `tui table`, `tui tree`, or `tui select` to follow, when
`--from` names a widget that has no rows or names the widget itself, or
when followers could only follow each other. `--data`, and `--value` on
`tui progress`, can no longer be combined with `--from` or a closure,
because the closure's output never showed. A closure now follows a
table, tree, or select on another `tui tab` page when the shown page has
none. Inside a child list such as `tui split [([a b] | tui table | tui
log {|row| ...})]`, the log now shows the closure's output instead of
the piped data.
```nushell
Error: nu::shell::error
× nothing for the closure to follow
╭─[source:1:65]
1 │ 1..5 | each {|n| $"tick ($n)"} | tui label --titlebar "ticks" | tui log { $in } | tui run
· ───┬───
· ╰── `log-0` runs its closure on the highlighted row of a table, tree, or select, but none can be followed: a widget never follows its own row, or one that follows it. Add one, or drop the closure
╰────
```
```nushell
Error: nu::shell::incompatible_parameters
× Incompatible parameters.
╭─[source:1:9]
1 │ tui log --data [a b] {|x| $x }
· ──────┬─────
· ╰── use either --data or --from/a closure, not both
╰────
```
## Additional notes
closes https://github.com/nushell/nushell/issues/19217
|
||
|
|
60c9ed7471 |
Don't let lifted columns overwrite normal columns while flattening (#19201)
During flattening we check if the nested records can be lifted straight to the root level. If that's not possible due to a colliding column name, we rename the lifted column with a name containing the nested record's name. After this rename, the column is added to the table without checking if the new name collides with any of its elements. This allows silently overwriting existing elements, which is not ideal. I fixed the issue by checking if the entry added to "out" overwrote an entry or not. Since "out" is an IndexMap, we can easily obtain this information by checking if the return value is Some. This check is done after each insert unless we've explicitly verified that the column name we're adding doesn't exist in the table. If an entry would be overwritten, an error is thrown. Before merging, could someone verify whether the error type, the tag and the span are correct? ## User-facing changes (Release notes) Fixed an issue where lifting a column from a nested record collided with the existing columns, but was nevertheless added to the table by overwriting the existing column. ## Additional notes Closes https://github.com/nushell/nushell/issues/19200 |
||
|
|
687d7bcac5 |
fix: support IPv6 zone IDs in http commands (#19213)
Fixes #9065 ## Description `http get 'http://[fe80::13%eth0]'` (and the other `http *` commands) fail because `url::Url::parse` does not support IPv6 zone IDs (e.g. `%eth0`), per the WHATWG URL standard. `curl` handles these URLs fine. The fix now validates and drives requests with `http::Uri`, the same parser ureq uses, so nushell and ureq agree on which URLs are valid. 1. **`crates/nu-command/src/network/http/client.rs`** - `http_parse_url` validates with `http::Uri` instead of `url::Url` (which rejects zone IDs). It returns the raw URL string; the `strip_ipv6_zone_id` helper and the returned `Url` are gone. - A new `authority_is_well_formed` check rejects URLs that `http::Uri` would otherwise accept leniently, e.g. trailing garbage after an IPv6 literal (`[fe80::13%eth0]foo`) or non-numeric/out-of-range ports (`host:abc`, `host:99999`). These would silently send the request to a different host or port. - `request_set_host_header` sets the `Host` header without the zone ID (matching curl) when the authority contains one, so strict servers don't reject the request. A user-provided `Host` header is left untouched. - `transform_response_using_content_type` derives the `text/plain` file extension from `http::Uri::path()` so zone-ID URLs no longer fail after the request has been sent. 2. **`crates/nu-command/src/network/http/resolver.rs`** - `uri.host()` returns IPv6 addresses wrapped in square brackets (e.g. `[fe80::13%eth0]`), which `dns_lookup::getaddrinfo` cannot resolve. The brackets are stripped before resolution, so `getaddrinfo` handles the zone ID natively (converting the interface name to a scope ID). - The RFC 6874 `%25` form (e.g. `[fe80::1%25lo0]`) is decoded to a literal `%` before `getaddrinfo`. - `host` stays an `Option` and is passed to `getaddrinfo` as-is. ## User-facing changes (Release notes) `http get`, `http post`, and the other `http *` commands now accept **`http://`** URLs with IPv6 literals and link-local zone IDs, e.g. `http get 'http://[fe80::13%eth0]'`. Plain IPv6 literals (e.g. `http get 'http://[::1]:8080/a.txt'`) work as well. Previously these URLs failed to parse or resolve. Note: `https://` URLs with a zone ID are **not** supported. ureq builds the rustls `ServerName` from the bracket-stripped host, and `fe80::13%eth0` is neither a valid IP nor a valid DNS name, so TLS handshakes fail. This is a ureq/rustls limitation and cannot be fixed from nushell. ## Tests - `cargo check -p nu-command` passes - `cargo test -p nu-command --lib network::http` — 20 tests pass, including: - `test_http_parse_url_with_ipv6_zone_id` - `test_http_parse_url_rejects_invalid_ipv6_with_zone_id` - `test_authority_is_well_formed` - `test_request_set_host_header_strips_zone_id` - `test_request_set_host_header_leaves_other_urls_alone` - `cargo test -p nu-command --test tests -- commands::network::http` — 87 tests pass, including the new `http_get_ipv6_literal`, which binds `[::1]` and makes a real `text/plain` request through `DnsLookupResolver`. - `cargo fmt --all -- --check`, `cargo clippy -p nu-command --all-targets -D warnings` and `typos` are clean. ## Review feedback All findings from the review have been addressed: 1. **Text/plain responses fail after the request is sent** — `transform_response_using_content_type` now uses `http::Uri::path()` instead of `url::Url::parse`. 2. **Zone ID ends up in the `Host` header** — `request_set_host_header` strips it (like curl); a user-set `Host` header is respected. 3. **Validate with `http::Uri` instead of strip-and-reparse** — done; `strip_ipv6_zone_id` and the returned `Url` are removed. URLs that ureq rejects (e.g. `http://[fe80::1%lo 0]:18913/`) are now rejected up front by `http_parse_url`. 4. **RFC 6874 `%25` form can't resolve** — the resolver decodes `%25` to `%` before `getaddrinfo`. 5. **No test makes a real request to an IPv6 literal** — added `http_get_ipv6_literal`. 6. **Keep `host` as an `Option`** — done. 7. **HTTPS zone-ID URLs still fail** — a ureq/rustls limitation; the release notes above are now scoped to `http://`. --------- Co-authored-by: Jarvis-AI-42 <skyfireitdiy@gmail.com> |
||
|
|
af58d1426b |
fix(join): error when a table has no rows with the join column (#19219)
## Description
`join` accepted a join column that its tables don't have. Depending on
the join type, it returned an empty list or rows padded with `null`:
```nushell
> [[a b]; [1 2] [3 4]] | join [[a c]; [1 3] [4 5]] d | to nuon
[]
> [[a b]; [1 2] [3 4]] | join --left [[a c]; [1 3] [4 5]] a z | to nuon
[[a, b, a_, c]; [1, 2, null, null], [3, 4, null, null]]
```
`join_rows` returned early when the table it was iterating had no row
with the key, and the lookup table built from the other side came out
empty when that side lacked the key. Neither path reported anything.
## User-facing changes (Release notes)
`join` now raises a `column_not_found` error when the input table or the
right table has rows but none of them contain the join column. Before, a
misspelled column name silently produced an empty result or rows full of
`null`. Empty tables and tables where only some rows lack the column
behave as before.
```nushell
Error: nu::shell::column_not_found
× Cannot find column 'd'
╭─[source:1:1]
1 │ [[a b]; [1 2] [3 4]] | join [[a c]; [1 3] [4 5]] d
· ──────────┬───────── ┬
· │ ╰── column 'd' is missing in one or more values
· ╰── value originates here
╰────
help: If some rows have this column, try using 'd?' for optional access, or
pre-fill using the `default` command
```
## Additional notes
closes https://github.com/nushell/nushell/issues/19215
|
||
|
|
fab6af9c2b |
Use builtin command sigil to avoid bugs when user aliases shadow builtin (#19224)
## Description User aliases should have no effect on nu's STD, but if you alias `alias metadata = /non/exist/bin` you'll get a load error `Command `/non/exist/bin` not found This PR fixes that smaller issue by adding `%`, but doesn't resolve the more general issue of other commands potentially having the same conflict ## User-facing changes (Release notes) - Fixed an issue where aliasing `metadata` would break its use in `std` ## Additional notes Ideally there should be some linter that forces `%` to all .nu scripts used in nushell |
||
|
|
4faa823718 |
anti join (#19208)
## Description Add a new `Join` kind with the following semantics: in `Inner` mode, append no rows. In non-inner mode, append all rows and include no new columns from `rhs` table. ## User-facing changes (Release notes) Add `join --anti`, which selects rows not present in the right table by the join column. `$lhs | join --anti $rhs ref` is equivalent in behavior to `$lhs | where ref not-in $rhs`. ## Additional notes Closes #19207 |
||
|
|
09eae32199 |
strict clocktime regex (#19210)
## Description
Instead of binding the clock time parsing to `str.contains(":")`, add a
dedicated regex. Note: the regex does not _validate_ clock strings. It
just defines the pattern for strings that we want to parse.
## User-facing changes (Release notes)
`into duration` rejects odd-length composite fields in the clock format,
such as `11:0:22` or `11:000:2`
This PR depends on #19209
|