|
|
- #!/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"
- no_rehash=""
- no_push_path=""
- for args in "$@"
- do
- if [ "$args" = "-" ]; then
- mode="print"
- shift
- fi
-
- if [ "$args" = "--path" ]; then
- mode="path"
- shift
- fi
-
- if [ "$args" = "--detect-shell" ]; then
- mode="detect-shell"
- shift
- fi
-
- if [ "$args" = "--no-push-path" ]; then
- no_push_path=1
- shift
- fi
-
- if [ "$args" = "--no-rehash" ]; then
- no_rehash=1
- shift
- fi
- done
-
- shell="$1"
- 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
-
- root="${0%/*}/.."
-
- 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 - | 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 -)"'
- ;;
- 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="${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 )
- cat <<EOS
- 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
- EOS
- ;;
- ksh | ksh93 | mksh )
- cat <<EOS
- function pyenv {
- typeset command
- EOS
- ;;
- * )
- cat <<EOS
- pyenv() {
- local command
- EOS
- ;;
- esac
-
- if [ "$shell" != "fish" ]; then
- IFS="|"
- cat <<EOS
- command="\${1:-}"
- if [ "\$#" -gt 0 ]; then
- shift
- fi
-
- case "\$command" in
- ${commands[*]:-/})
- eval "\$(pyenv "sh-\$command" "\$@")"
- ;;
- *)
- command pyenv "\$command" "\$@"
- ;;
- esac
- }
- EOS
- fi
- }
-
- main
|