
print_shell_function(). -> Maintainers prefer single quotes instead of double quotes, since it allows us to look away from tracking what to escape.
294 lines
6.7 KiB
Bash
Executable File
294 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Summary: Configure the shell environment for pyenv
|
|
# Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--detect-shell] [--no-rehash] [<shell>])"
|
|
|
|
set -e
|
|
[ -n "$PYENV_DEBUG" ] && set -x
|
|
|
|
# Provide pyenv completions
|
|
if [ "$1" = "--complete" ]; then
|
|
echo -
|
|
echo --path
|
|
echo --no-push-path
|
|
echo --no-rehash
|
|
echo --detect-shell
|
|
echo bash
|
|
echo fish
|
|
echo ksh
|
|
echo zsh
|
|
exit
|
|
fi
|
|
|
|
mode="help"
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
-)
|
|
mode="print"
|
|
;;
|
|
--path)
|
|
mode="path"
|
|
;;
|
|
--detect-shell)
|
|
mode="detect-shell"
|
|
;;
|
|
--no-push-path)
|
|
no_push_path=1
|
|
;;
|
|
--no-rehash)
|
|
no_rehash=1
|
|
;;
|
|
*)
|
|
shell="$1"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# If shell is not provided, detect it.
|
|
if [ -z "$shell" ]; then
|
|
shell="$(ps -p "$PPID" -o 'args=' 2>/dev/null || true)"
|
|
shell="${shell%% *}"
|
|
shell="${shell##-}"
|
|
shell="${shell:-$SHELL}"
|
|
shell="${shell##*/}"
|
|
shell="${shell%%-*}"
|
|
fi
|
|
|
|
function main() {
|
|
case "$mode" in
|
|
"help")
|
|
help_
|
|
exit 1
|
|
;;
|
|
"path")
|
|
print_path
|
|
print_rehash
|
|
exit 0
|
|
;;
|
|
"print")
|
|
init_dirs
|
|
print_path
|
|
print_env
|
|
print_completion
|
|
print_rehash
|
|
print_shell_function
|
|
exit 0
|
|
;;
|
|
"detect-shell")
|
|
detect_profile 1
|
|
print_detect_shell
|
|
exit 0
|
|
;;
|
|
esac
|
|
# should never get here
|
|
exit 2
|
|
}
|
|
|
|
function detect_profile() {
|
|
local detect_for_detect_shell="$1"
|
|
|
|
case "$shell" in
|
|
bash )
|
|
if [ -e '~/.bash_profile' ]; then
|
|
profile='~/.bash_profile'
|
|
else
|
|
profile='~/.profile'
|
|
fi
|
|
profile_explain="~/.bash_profile if it exists, otherwise ~/.profile"
|
|
rc='~/.bashrc'
|
|
;;
|
|
zsh )
|
|
profile='~/.zprofile'
|
|
rc='~/.zshrc'
|
|
;;
|
|
ksh | ksh93 | mksh )
|
|
# There are two implementations of Korn shell: AT&T (ksh93) and Mir (mksh).
|
|
# Systems may have them installed under those names, or as ksh, so those
|
|
# are recognized here. The obsolete ksh88 (subsumed by ksh93) and pdksh
|
|
# (subsumed by mksh) are not included, since they are unlikely to still
|
|
# be in use as interactive shells anywhere.
|
|
profile='~/.profile'
|
|
rc='~/.profile'
|
|
;;
|
|
* )
|
|
if [ -n "$detect_for_detect_shell" ]; then
|
|
profile=
|
|
rc=
|
|
else
|
|
profile='your shell'\''s login startup file'
|
|
rc='your shell'\''s interactive startup file'
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function print_detect_shell() {
|
|
echo "PYENV_SHELL_DETECT=$shell"
|
|
echo "PYENV_PROFILE_DETECT=$profile"
|
|
echo "PYENV_RC_DETECT=$rc"
|
|
}
|
|
|
|
function help_() {
|
|
detect_profile
|
|
{
|
|
case "$shell" in
|
|
fish )
|
|
echo "# Add pyenv executable to PATH by running"
|
|
echo "# the following interactively:"
|
|
echo
|
|
echo 'set -Ux PYENV_ROOT $HOME/.pyenv'
|
|
echo 'set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths'
|
|
echo
|
|
echo "# Load pyenv automatically by appending"
|
|
echo "# the following to ~/.config/fish/config.fish:"
|
|
echo
|
|
echo 'pyenv init - fish | source'
|
|
echo
|
|
;;
|
|
* )
|
|
echo '# Load pyenv automatically by appending'
|
|
echo -n "# the following to "
|
|
if [ "$profile" == "$rc" ]; then
|
|
echo "$profile :"
|
|
else
|
|
echo
|
|
echo "# ${profile_explain:-$profile} (for login shells)"
|
|
echo "# and $rc (for interactive shells) :"
|
|
fi
|
|
echo
|
|
echo 'export PYENV_ROOT="$HOME/.pyenv"'
|
|
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"'
|
|
echo 'eval "$(pyenv init -'$shell')"'
|
|
;;
|
|
esac
|
|
echo
|
|
echo '# Restart your shell for the changes to take effect.'
|
|
echo
|
|
} >&2
|
|
}
|
|
|
|
function init_dirs() {
|
|
mkdir -p "${PYENV_ROOT}/"{shims,versions}
|
|
}
|
|
|
|
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
|
|
fish )
|
|
echo 'if not contains -- "'"${PYENV_ROOT}/shims"'" $PATH'
|
|
print_path_prepend_shims
|
|
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
|
|
# that makes it source `bashrc` under SSH even when not interactive.
|
|
# This is inhibited by a guard in Debian's stock `bashrc` but some people remove it
|
|
# in order to get proper environment for noninteractive remote commands
|
|
# (SSH provides /etc/ssh/sshrc and ~/.ssh/rc for that but no-one seems to use them for some reason).
|
|
# This has caused an infinite `bashrc` execution loop for those people in the below nested Bash invocation (#2367).
|
|
# --norc negates this behavior of such a customized Bash.
|
|
echo 'PATH="$(bash --norc -ec '\''IFS=:; paths=($PATH); '
|
|
echo 'for i in ${!paths[@]}; do '
|
|
echo 'if [[ ${paths[i]} == "'\'\'"${PYENV_ROOT}/shims"\'\''" ]]; then unset '\'\\\'\''paths[i]'\'\\\'\''; '
|
|
echo 'fi; done; '
|
|
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}"'
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function print_env() {
|
|
case "$shell" in
|
|
fish )
|
|
echo "set -gx PYENV_SHELL $shell"
|
|
;;
|
|
* )
|
|
echo "export PYENV_SHELL=$shell"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function print_completion() {
|
|
completion="${PYENV_ROOT}/completions/pyenv.${shell}"
|
|
if [ -r "$completion" ]; then
|
|
echo "source '$completion'"
|
|
fi
|
|
}
|
|
|
|
function print_rehash() {
|
|
if [ -z "$no_rehash" ]; then
|
|
echo 'command pyenv rehash 2>/dev/null'
|
|
fi
|
|
}
|
|
|
|
function print_shell_function() {
|
|
commands=(`pyenv-commands --sh`)
|
|
case "$shell" in
|
|
fish )
|
|
echo 'function pyenv
|
|
set command $argv[1]
|
|
set -e argv[1]
|
|
|
|
switch "$command"
|
|
case '"${commands[*]}"'
|
|
source (pyenv "sh-$command" $argv|psub)
|
|
case "*"
|
|
command pyenv "$command" $argv
|
|
end
|
|
end'
|
|
;;
|
|
ksh | ksh93 | mksh )
|
|
echo 'function pyenv {
|
|
typeset command=$1'
|
|
;;
|
|
* )
|
|
echo 'pyenv() {
|
|
local command=$1'
|
|
;;
|
|
esac
|
|
|
|
if [ "$shell" != "fish" ]; then
|
|
IFS="|"
|
|
echo ' [ "$#" -gt 0 ] && shift
|
|
case "$command" in
|
|
'"${commands[*]:-/}"')
|
|
eval "$(pyenv "sh-$command" "$@")"
|
|
;;
|
|
*)
|
|
command pyenv "$command" "$@"
|
|
;;
|
|
esac
|
|
}'
|
|
fi
|
|
}
|
|
|
|
main
|