Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

199 рядки
5.3 KiB

  1. #!/usr/bin/env bash
  2. #
  3. # Summary: Install a Python version using the python-build plugin
  4. #
  5. # Usage: pyenv install [-f|--force] [-g|--debug] [-k|--keep] [-v|--verbose] <version>
  6. # pyenv install [-f|--force] [-g|--debug] [-k|--keep] [-v|--verbose] <definition-file>
  7. # pyenv install -l|--list
  8. #
  9. # -l/--list List all available versions
  10. # -f/--force Install even if the version appears to be installed already
  11. # -k/--keep Keep source tree in $PYENV_BUILD_ROOT after installation
  12. # (defaults to $PYENV_ROOT/sources)
  13. # -g/--debug Build a debug version
  14. # -v/--verbose Verbose mode: print compilation status to stdout
  15. #
  16. # For detailed information on installing Python versions with
  17. # python-build, including a list of environment variables for adjusting
  18. # compilation, see: https://github.com/yyuu/pyenv#readme
  19. #
  20. set -e
  21. [ -n "$PYENV_DEBUG" ] && set -x
  22. # Provide pyenv completions
  23. if [ "$1" = "--complete" ]; then
  24. exec python-build --definitions
  25. fi
  26. if [ -z "$PYENV_ROOT" ]; then
  27. PYENV_ROOT="${HOME}/.pyenv"
  28. fi
  29. # Load shared library functions
  30. eval "$(python-build --lib)"
  31. usage() {
  32. # We can remove the sed fallback once pyenv 0.4.0 is widely available.
  33. pyenv-help install 2>/dev/null || sed -ne '/^#/!q;s/.//;s/.//;1,4d;p' < "$0"
  34. [ -z "$1" ] || exit "$1"
  35. }
  36. definitions() {
  37. local query="$1"
  38. python-build --definitions | grep -F "$query" || true
  39. }
  40. indent() {
  41. sed 's/^/ /'
  42. }
  43. unset FORCE
  44. unset KEEP
  45. unset VERBOSE
  46. unset DEBUG
  47. parse_options "$@"
  48. for option in "${OPTIONS[@]}"; do
  49. case "$option" in
  50. "h" | "help" )
  51. usage 0
  52. ;;
  53. "l" | "list" )
  54. echo "Available versions:"
  55. definitions | indent
  56. exit
  57. ;;
  58. "f" | "force" )
  59. FORCE=true
  60. ;;
  61. "k" | "keep" )
  62. [ -n "${PYENV_BUILD_ROOT}" ] || PYENV_BUILD_ROOT="${PYENV_ROOT}/sources"
  63. ;;
  64. "v" | "verbose" )
  65. VERBOSE="-v"
  66. ;;
  67. "g" | "debug" )
  68. DEBUG="-g"
  69. ;;
  70. "version" )
  71. exec python-build --version
  72. ;;
  73. * )
  74. usage 1
  75. ;;
  76. esac
  77. done
  78. unset VERSION_NAME
  79. # The first argument contains the definition to install. If the
  80. # argument is missing, try to install whatever local app-specific
  81. # version is specified by pyenv. Show usage instructions if a local
  82. # version is not specified.
  83. DEFINITION="${ARGUMENTS[0]}"
  84. [ -n "$DEFINITION" ] || DEFINITION="$(pyenv local 2>/dev/null || true)"
  85. [ -n "$DEFINITION" ] || usage 1
  86. # Define `before_install` and `after_install` functions that allow
  87. # plugin hooks to register a string of code for execution before or
  88. # after the installation process.
  89. declare -a before_hooks after_hooks
  90. before_install() {
  91. local hook="$1"
  92. before_hooks["${#before_hooks[@]}"]="$hook"
  93. }
  94. after_install() {
  95. local hook="$1"
  96. after_hooks["${#after_hooks[@]}"]="$hook"
  97. }
  98. # Load plugin hooks.
  99. for script in $(pyenv-hooks install); do
  100. source "$script"
  101. done
  102. # Set VERSION_NAME from $DEFINITION, if it is not already set. Then
  103. # compute the installation prefix.
  104. [ -n "$VERSION_NAME" ] || VERSION_NAME="${DEFINITION##*/}"
  105. [ -n "$DEBUG" ] && VERSION_NAME="${VERSION_NAME}-debug"
  106. PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
  107. [ -d "${PREFIX}" ] && PREFIX_EXISTS=1
  108. # If the installation prefix exists, prompt for confirmation unless
  109. # the --force option was specified.
  110. if [ -z "$FORCE" ] && [ -d "${PREFIX}/bin" ]; then
  111. echo "pyenv: $PREFIX already exists" >&2
  112. read -p "continue with installation? (y/N) "
  113. case "$REPLY" in
  114. y* | Y* ) ;;
  115. * ) exit 1 ;;
  116. esac
  117. fi
  118. # If PYENV_BUILD_ROOT is set, always pass keep options to python-build.
  119. if [ -n "${PYENV_BUILD_ROOT}" ]; then
  120. export PYTHON_BUILD_BUILD_PATH="${PYENV_BUILD_ROOT}/${VERSION_NAME}"
  121. KEEP="-k"
  122. fi
  123. # Set PYTHON_BUILD_CACHE_PATH to $PYENV_ROOT/cache, if the directory
  124. # exists and the variable is not already set.
  125. if [ -z "${PYTHON_BUILD_CACHE_PATH}" ] && [ -d "${PYENV_ROOT}/cache" ]; then
  126. export PYTHON_BUILD_CACHE_PATH="${PYENV_ROOT}/cache"
  127. fi
  128. # Default PYENV_VERSION to the globally-specified Python version. (The
  129. # CPython installer requires an existing Python installation to run. An
  130. # unsatisfied local .python-version file can cause the installer to
  131. # fail.)
  132. #export PYENV_VERSION="$(pyenv global 2>/dev/null || true)"
  133. # Execute `before_install` hooks.
  134. for hook in "${before_hooks[@]}"; do eval "$hook"; done
  135. # Plan cleanup on unsuccessful installation.
  136. cleanup() {
  137. [ -z "${PREFIX_EXISTS}" ] && rm -rf "$PREFIX"
  138. }
  139. trap cleanup SIGINT
  140. # Invoke `python-build` and record the exit status in $STATUS.
  141. STATUS=0
  142. python-build $KEEP $VERBOSE $DEBUG "$DEFINITION" "$PREFIX" || STATUS="$?"
  143. # Display a more helpful message if the definition wasn't found.
  144. if [ "$STATUS" == "2" ]; then
  145. { candidates="$(definitions "$DEFINITION")"
  146. if [ -n "$candidates" ]; then
  147. echo
  148. echo "The following versions contain \`$DEFINITION' in the name:"
  149. echo "$candidates" | indent
  150. fi
  151. echo
  152. echo "You can list all available versions with \`pyenv install --list'."
  153. echo
  154. echo "If the version you're looking for is not present, first try upgrading"
  155. echo "pyenv. If it's still missing, open a request on the pyenv"
  156. echo "issue tracker: https://github.com/yyuu/pyenv/issues"
  157. } >&2
  158. fi
  159. # Execute `after_install` hooks.
  160. for hook in "${after_hooks[@]}"; do eval "$hook"; done
  161. # Run `pyenv-rehash` after a successful installation.
  162. if [ "$STATUS" == "0" ]; then
  163. pyenv rehash
  164. else
  165. cleanup
  166. fi
  167. exit "$STATUS"