Fix path add bug when given a record (#15379)

`path add`, when given a record, sets `$env.PATH` according to the value
of the key matching `$nu.os-info.name`. There already existed a check in
place to ensure the correct column existed, but it was never reached
because of an early error on `path expand`ing `null`. This has been
fixed, as well as the out-of-date reference to "darwin" instead of
"macos" in the example.

# User-Facing Changes

`path add` now simply ignores a record that doesn't include a key for the current OS

`path add` also will no longer add duplicate paths.
This commit is contained in:
Firegem 2025-03-22 08:42:20 -04:00 committed by GitHub
parent 7c160725ed
commit f33a26123c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 25 deletions

View File

@ -7,14 +7,14 @@
path add "returned" --ret path add "returned" --ret
} }
} --result [returned bar baz foo fooo] } --result [returned bar baz foo fooo]
@example "adding paths based on the operating system" { @example "adding paths based on $nu.os-info.name" {
path add {linux: "foo", windows: "bar", darwin: "baz"} path add {linux: "foo", windows: "bar", macos: "baz"}
} }
export def --env "path add" [ export def --env "path add" [
--ret (-r) # return $env.PATH, useful in pipelines to avoid scoping. --ret (-r) # return $env.PATH, useful in pipelines to avoid scoping.
--append (-a) # append to $env.PATH instead of prepending to. --append (-a) # append to $env.PATH instead of prepending to.
...paths # the paths to add to $env.PATH. ...paths: any # the paths to add to $env.PATH.
] { ]: [nothing -> nothing, nothing -> list<path>] {
let span = (metadata $paths).span let span = (metadata $paths).span
let paths = $paths | flatten let paths = $paths | flatten
@ -25,34 +25,36 @@ export def --env "path add" [
}} }}
} }
for path in $paths {
if ($path | describe -d).type not-in ['string', 'record'] {
error make {msg: 'Invalid input', label: {
text: 'Path must be a string or record',
span: (metadata $path).span
}}
}
}
let path_name = if "PATH" in $env { "PATH" } else { "Path" } let path_name = if "PATH" in $env { "PATH" } else { "Path" }
let paths = $paths | each {|p| let paths = $paths | each {|p|
let p = match ($p | describe | str replace --regex '<.*' '') { match ($p | describe -d).type {
"string" => $p, 'string' => { $p | path expand --no-symlink },
"record" => { $p | get --ignore-errors $nu.os-info.name }, 'record' => {
if $nu.os-info.name in ($p | columns) {
$p | get $nu.os-info.name | path expand --no-symlink
}
}
} }
} | compact
$p | path expand --no-symlink
}
if null in $paths or ($paths | is-empty) {
error make {msg: "Empty input", label: {
text: $"Received a record, that does not contain a ($nu.os-info.name) key",
span: $span
}}
}
load-env {$path_name: ( load-env {$path_name: (
$env $env | get $path_name
| get $path_name | split row (char esep)
| split row (char esep) | if $append { append $paths } else { prepend $paths }
| if $append { append $paths } else { prepend $paths } | uniq
)} )}
if $ret { if $ret { $env | get $path_name }
$env | get $path_name
}
} }
# The cute and friendly mascot of Nushell :) # The cute and friendly mascot of Nushell :)

View File

@ -39,6 +39,12 @@ def path_add [] {
path add $target_paths path add $target_paths
assert equal (get_path) ([($target_paths | get $nu.os-info.name)] | path expand) assert equal (get_path) ([($target_paths | get $nu.os-info.name)] | path expand)
load-env {$path_name: []}
path add {}
assert equal (get_path) []
assert error {|| path add 1 }
load-env {$path_name: [$"(["/foo", "/bar"] | path expand | str join (char esep))"]} load-env {$path_name: [$"(["/foo", "/bar"] | path expand | str join (char esep))"]}
path add "~/foo" path add "~/foo"
assert equal (get_path) (["~/foo", "/foo", "/bar"] | path expand) assert equal (get_path) (["~/foo", "/foo", "/bar"] | path expand)

View File

@ -39,6 +39,12 @@ def path_add [] {
path add $target_paths path add $target_paths
assert equal (get_path) ([($target_paths | get $nu.os-info.name)] | path expand) assert equal (get_path) ([($target_paths | get $nu.os-info.name)] | path expand)
load-env {$path_name: []}
path add {}
assert equal (get_path) ([])
assert error {|| path add 1 }
load-env {$path_name: [$"(["/foo", "/bar"] | path expand | str join (char esep))"]} load-env {$path_name: [$"(["/foo", "/bar"] | path expand | str join (char esep))"]}
path add "~/foo" path add "~/foo"
assert equal (get_path) (["~/foo", "/foo", "/bar"] | path expand) assert equal (get_path) (["~/foo", "/foo", "/bar"] | path expand)