functions/export: fix for path variables

Commit f38646593c (Allow `export` to set colon-separated `PATH`, `CDPATH`
and `MANPATH`., 2017-02-10)
did something very weird for «export PATH=foo».
It essentially does

	set -gx PATH (string replace -- "$PATH" (string join ":" -- $PATH) foo)

which makes no sense.  It should set PATH to "foo", no need to involve the
existing value of $PATH.

Additionally, the string split / string join dance is unnecessary.  Nowadays,
builtin set already handles path variables as is needed here, so get rid of
this special case.

Fixes #11434
This commit is contained in:
Johannes Altmanninger
2025-05-04 17:34:27 +02:00
parent dd4c04e2ff
commit cb92a5530f
2 changed files with 36 additions and 9 deletions

View File

@@ -5,18 +5,13 @@ function export --description 'Set env variable. Alias for `set -gx` for bash co
end
for arg in $argv
set -l v (string split -m 1 "=" -- $arg)
set -l value
switch (count $v)
case 1
set -gx $v $$v
set value $$v[1]
case 2
if contains -- $v[1] PATH CDPATH MANPATH
set -l colonized_path (string replace -- "$$v[1]" (string join ":" -- $$v[1]) $v[2])
set -gx $v[1] (string split ":" -- $colonized_path)
else
# status is 1 from the contains check, and `set` does not change the status on success: reset it.
true
set -gx $v[1] $v[2]
end
set value $v[2]
end
set -gx $v[1] $value
end
end

32
tests/checks/export.fish Normal file
View File

@@ -0,0 +1,32 @@
#RUN: %fish %s
false
export FOO=bar
echo $status
# CHECK: 0
set -S FOO
# CHECK: $FOO: set in global scope, exported, with 1 elements
# CHECK: $FOO[1]: |bar|
## Test path variable that is not already set.
set -eg MANPATH
export MANPATH=":/path/to/man/pages"
echo $status
# CHECK: 0
set -S MANPATH
# CHECK: $MANPATH: set in global scope, exported, a path variable with 2 elements
# CHECK: $MANPATH[1]: ||
# CHECK: $MANPATH[2]: |/path/to/man/pages|
## Re-set a path variable that is already set.
export MANPATH="/some/path:/some/other/path"
echo $status
# CHECK: 0
set -S MANPATH
# CHECK: $MANPATH: set in global scope, exported, a path variable with 2 elements
# CHECK: $MANPATH[1]: |/some/path|
# CHECK: $MANPATH[2]: |/some/other/path|
## Test that it's exported properly.
env | string match 'MANPATH*'
# CHECK: MANPATH=/some/path:/some/other/path