mirror of
https://github.com/pyenv/pyenv.git
synced 2025-01-03 03:11:14 +00:00
Add --no-push-path option (#2526)
In some advanced shell setups, the order of custom-added PATH entries is important. We disregard it by default, always pushing shims to the front of PATH, to ensure that Pyenv works even in poorly maintained shell environments and with minimal hassle for non-export users (an attempt to do the opposite (#1898) has ended in a disaster). Some advanced users are however ready and able to carefully maintain their environment and deal with breakages and inconvenience. This option is for them.
This commit is contained in:
parent
4c261e6ea1
commit
cc56f76733
3 changed files with 104 additions and 25 deletions
|
@ -386,11 +386,12 @@ List existing pyenv shims.
|
||||||
|
|
||||||
Configure the shell environment for pyenv
|
Configure the shell environment for pyenv
|
||||||
|
|
||||||
Usage: eval "$(pyenv init [-|--path] [--no-rehash] [<shell>])"
|
Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])"
|
||||||
|
|
||||||
- Initialize shims directory, print PYENV_SHELL variable, completions path
|
- Initialize shims directory, print PYENV_SHELL variable, completions path
|
||||||
and shell function
|
and shell function
|
||||||
--path Print shims path
|
--path Print shims path
|
||||||
|
--no-push-path Do not push shim to the start of PATH if they're already there
|
||||||
--no-rehash Add no rehash command to output
|
--no-rehash Add no rehash command to output
|
||||||
|
|
||||||
## `pyenv completions`
|
## `pyenv completions`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Summary: Configure the shell environment for pyenv
|
# Summary: Configure the shell environment for pyenv
|
||||||
# Usage: eval "$(pyenv init [-|--path] [--no-rehash] [<shell>])"
|
# Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
@ -9,6 +9,7 @@ set -e
|
||||||
if [ "$1" = "--complete" ]; then
|
if [ "$1" = "--complete" ]; then
|
||||||
echo -
|
echo -
|
||||||
echo --path
|
echo --path
|
||||||
|
echo --no-push-path
|
||||||
echo --no-rehash
|
echo --no-rehash
|
||||||
echo bash
|
echo bash
|
||||||
echo fish
|
echo fish
|
||||||
|
@ -19,6 +20,7 @@ fi
|
||||||
|
|
||||||
mode="help"
|
mode="help"
|
||||||
no_rehash=""
|
no_rehash=""
|
||||||
|
no_push_path=""
|
||||||
for args in "$@"
|
for args in "$@"
|
||||||
do
|
do
|
||||||
if [ "$args" = "-" ]; then
|
if [ "$args" = "-" ]; then
|
||||||
|
@ -31,6 +33,11 @@ do
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$args" = "--no-push-path" ]; then
|
||||||
|
no_push_path=1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$args" = "--no-rehash" ]; then
|
if [ "$args" = "--no-rehash" ]; then
|
||||||
no_rehash=1
|
no_rehash=1
|
||||||
shift
|
shift
|
||||||
|
@ -141,11 +148,27 @@ function init_dirs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function print_path() {
|
function print_path() {
|
||||||
|
# if no_push_path is set, guard the PATH manipulation with a check on whether
|
||||||
|
# the shim is already in the PATH.
|
||||||
|
if [ -n "$no_push_path" ]; then
|
||||||
case "$shell" in
|
case "$shell" in
|
||||||
fish )
|
fish )
|
||||||
echo 'while set index (contains -i -- '\'"${PYENV_ROOT}/shims"\'' $PATH)'
|
echo 'if not contains -- "'"${PYENV_ROOT}/shims"'" $PATH'
|
||||||
echo 'set -eg PATH[$index]; end; set -e index'
|
print_path_prepend_shims
|
||||||
echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH'
|
echo 'end'
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'if [[ ":$PATH:" != *'\':"${PYENV_ROOT}"/shims:\''* ]]; then'
|
||||||
|
print_path_prepend_shims
|
||||||
|
echo 'fi'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
case "$shell" in
|
||||||
|
fish )
|
||||||
|
echo 'while set pyenv_index (contains -i -- "'"${PYENV_ROOT}/shims"'" $PATH)'
|
||||||
|
echo 'set -eg PATH[$pyenv_index]; end; set -e pyenv_index'
|
||||||
|
print_path_prepend_shims
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
# Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option
|
# Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option
|
||||||
|
@ -160,6 +183,18 @@ function print_path() {
|
||||||
echo 'if [[ ${paths[i]} == "'\'\'"${PYENV_ROOT}/shims"\'\''" ]]; then unset '\'\\\'\''paths[i]'\'\\\'\''; '
|
echo 'if [[ ${paths[i]} == "'\'\'"${PYENV_ROOT}/shims"\'\''" ]]; then unset '\'\\\'\''paths[i]'\'\\\'\''; '
|
||||||
echo 'fi; done; '
|
echo 'fi; done; '
|
||||||
echo 'echo "${paths[*]}"'\'')"'
|
echo 'echo "${paths[*]}"'\'')"'
|
||||||
|
print_path_prepend_shims
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_path_prepend_shims() {
|
||||||
|
case "$shell" in
|
||||||
|
fish )
|
||||||
|
echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH'
|
||||||
|
;;
|
||||||
|
* )
|
||||||
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
|
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -98,7 +98,6 @@ echo "\$PATH"
|
||||||
command -v fish >/dev/null || skip "-- fish not installed"
|
command -v fish >/dev/null || skip "-- fish not installed"
|
||||||
OLDPATH="$PATH"
|
OLDPATH="$PATH"
|
||||||
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
|
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
|
||||||
# fish 2 (Ubuntu Bionic) adds spurious messages when setting PATH, messing up the output
|
|
||||||
run fish <<!
|
run fish <<!
|
||||||
set -x PATH "$PATH"
|
set -x PATH "$PATH"
|
||||||
pyenv init - | source
|
pyenv init - | source
|
||||||
|
@ -108,6 +107,50 @@ echo "\$PATH"
|
||||||
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
|
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "adds shims to PATH with --no-push-path if they're not on PATH" {
|
||||||
|
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||||
|
run bash -e <<!
|
||||||
|
eval "\$(pyenv-init - --no-push-path)"
|
||||||
|
echo "\$PATH"
|
||||||
|
!
|
||||||
|
assert_success
|
||||||
|
assert_output "${PYENV_ROOT}/shims:${PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "adds shims to PATH with --no-push-path if they're not on PATH (fish)" {
|
||||||
|
command -v fish >/dev/null || skip "-- fish not installed"
|
||||||
|
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
|
||||||
|
run fish <<!
|
||||||
|
set -x PATH "$PATH"
|
||||||
|
pyenv-init - --no-push-path| source
|
||||||
|
echo "\$PATH"
|
||||||
|
!
|
||||||
|
assert_success
|
||||||
|
assert_output "${PYENV_ROOT}/shims:${PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "doesn't change PATH with --no-push-path if shims are already on PATH" {
|
||||||
|
export PATH="${BATS_TEST_DIRNAME}/../libexec:${PYENV_ROOT}/shims:/usr/bin:/bin:/usr/local/bin"
|
||||||
|
run bash -e <<!
|
||||||
|
eval "\$(pyenv-init - --no-push-path)"
|
||||||
|
echo "\$PATH"
|
||||||
|
!
|
||||||
|
assert_success
|
||||||
|
assert_output "${PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "doesn't change PATH with --no-push-path if shims are already on PATH (fish)" {
|
||||||
|
command -v fish >/dev/null || skip "-- fish not installed"
|
||||||
|
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:${PYENV_ROOT}/shims:/bin:/usr/local/bin"
|
||||||
|
run fish <<!
|
||||||
|
set -x PATH "$PATH"
|
||||||
|
pyenv-init - --no-push-path| source
|
||||||
|
echo "\$PATH"
|
||||||
|
!
|
||||||
|
assert_success
|
||||||
|
assert_output "${PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
@test "outputs sh-compatible syntax" {
|
@test "outputs sh-compatible syntax" {
|
||||||
run pyenv-init - bash
|
run pyenv-init - bash
|
||||||
assert_success
|
assert_success
|
||||||
|
|
Loading…
Reference in a new issue