Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

265 rader
7.3 KiB

10 år sedan
10 år sedan
  1. #!/usr/bin/env bash
  2. #
  3. # Summary: Install a Python version using python-build
  4. #
  5. # Usage: pyenv install [-f] [-kvp] <version>
  6. # pyenv install [-f] [-kvp] <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. # -s/--skip-existing Skip if the version appears to be installed already
  12. #
  13. # python-build options:
  14. #
  15. # -k/--keep Keep source tree in $PYENV_BUILD_ROOT after installation
  16. # (defaults to $PYENV_ROOT/sources)
  17. # -v/--verbose Verbose mode: print compilation status to stdout
  18. # -p/--patch Apply a patch from stdin before building
  19. # -g/--debug Build a debug version
  20. #
  21. # For detailed information on installing Python versions with
  22. # python-build, including a list of environment variables for adjusting
  23. # compilation, see: https://github.com/yyuu/pyenv#readme
  24. #
  25. set -e
  26. [ -n "$PYENV_DEBUG" ] && set -x
  27. if [ -z "$PYENV_ROOT" ]; then
  28. PYENV_ROOT="${HOME}/.pyenv"
  29. fi
  30. # Add `share/python-build/` directory from each pyenv plugin to the list of
  31. # paths where build definitions are looked up.
  32. shopt -s nullglob
  33. for plugin_path in "$PYENV_ROOT"/plugins/*/share/python-build; do
  34. PYTHON_BUILD_DEFINITIONS="${PYTHON_BUILD_DEFINITIONS}:${plugin_path}"
  35. done
  36. export PYTHON_BUILD_DEFINITIONS
  37. shopt -u nullglob
  38. # Provide pyenv completions
  39. if [ "$1" = "--complete" ]; then
  40. exec python-build --definitions
  41. fi
  42. # Load shared library functions
  43. eval "$(python-build --lib)"
  44. usage() {
  45. pyenv-help install 2>/dev/null
  46. [ -z "$1" ] || exit "$1"
  47. }
  48. definitions() {
  49. local query="$1"
  50. python-build --definitions | $(type -p ggrep grep | head -1) -F "$query" || true
  51. }
  52. indent() {
  53. sed 's/^/ /'
  54. }
  55. unset FORCE
  56. unset SKIP_EXISTING
  57. unset KEEP
  58. unset VERBOSE
  59. unset HAS_PATCH
  60. unset DEBUG
  61. parse_options "$@"
  62. for option in "${OPTIONS[@]}"; do
  63. case "$option" in
  64. "h" | "help" )
  65. usage 0
  66. ;;
  67. "l" | "list" )
  68. echo "Available versions:"
  69. definitions | indent
  70. exit
  71. ;;
  72. "f" | "force" )
  73. FORCE=true
  74. ;;
  75. "s" | "skip-existing" )
  76. SKIP_EXISTING=true
  77. ;;
  78. "k" | "keep" )
  79. [ -n "${PYENV_BUILD_ROOT}" ] || PYENV_BUILD_ROOT="${PYENV_ROOT}/sources"
  80. ;;
  81. "v" | "verbose" )
  82. VERBOSE="-v"
  83. ;;
  84. "p" | "patch" )
  85. HAS_PATCH="-p"
  86. ;;
  87. "g" | "debug" )
  88. DEBUG="-g"
  89. ;;
  90. "version" )
  91. exec python-build --version
  92. ;;
  93. * )
  94. usage 1 >&2
  95. ;;
  96. esac
  97. done
  98. [ "${#ARGUMENTS[@]}" -le 1 ] || usage 1 >&2
  99. unset VERSION_NAME
  100. # The first argument contains the definition to install. If the
  101. # argument is missing, try to install whatever local app-specific
  102. # version is specified by pyenv. Show usage instructions if a local
  103. # version is not specified.
  104. DEFINITION="${ARGUMENTS[0]}"
  105. [ -n "$DEFINITION" ] || DEFINITION="$(pyenv-local 2>/dev/null || true)"
  106. [ -n "$DEFINITION" ] || usage 1 >&2
  107. # Define `before_install` and `after_install` functions that allow
  108. # plugin hooks to register a string of code for execution before or
  109. # after the installation process.
  110. declare -a before_hooks after_hooks
  111. before_install() {
  112. local hook="$1"
  113. before_hooks["${#before_hooks[@]}"]="$hook"
  114. }
  115. after_install() {
  116. local hook="$1"
  117. after_hooks["${#after_hooks[@]}"]="$hook"
  118. }
  119. OLDIFS="$IFS"
  120. IFS=$'\n' scripts=(`pyenv-hooks install`)
  121. IFS="$OLDIFS"
  122. for script in "${scripts[@]}"; do source "$script"; done
  123. # Set VERSION_NAME from $DEFINITION, if it is not already set. Then
  124. # compute the installation prefix.
  125. [ -n "$VERSION_NAME" ] || VERSION_NAME="${DEFINITION##*/}"
  126. [ -n "$DEBUG" ] && VERSION_NAME="${VERSION_NAME}-debug"
  127. PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
  128. [ -d "${PREFIX}" ] && PREFIX_EXISTS=1
  129. # If the installation prefix exists, prompt for confirmation unless
  130. # the --force option was specified.
  131. if [ -d "${PREFIX}/bin" ]; then
  132. if [ -z "$FORCE" ] && [ -z "$SKIP_EXISTING" ]; then
  133. echo "pyenv: $PREFIX already exists" >&2
  134. read -p "continue with installation? (y/N) "
  135. case "$REPLY" in
  136. y* | Y* ) ;;
  137. * ) exit 1 ;;
  138. esac
  139. elif [ -n "$SKIP_EXISTING" ]; then
  140. # Since we know the python version is already installed, and are opting to
  141. # not force installation of existing versions, we just `exit 0` here to
  142. # leave things happy
  143. exit 0
  144. fi
  145. fi
  146. # If PYENV_BUILD_ROOT is set, always pass keep options to python-build.
  147. if [ -n "${PYENV_BUILD_ROOT}" ]; then
  148. export PYTHON_BUILD_BUILD_PATH="${PYENV_BUILD_ROOT}/${VERSION_NAME}"
  149. KEEP="-k"
  150. fi
  151. # Set PYTHON_BUILD_CACHE_PATH to $PYENV_ROOT/cache, if the directory
  152. # exists and the variable is not already set.
  153. if [ -z "${PYTHON_BUILD_CACHE_PATH}" ] && [ -d "${PYENV_ROOT}/cache" ]; then
  154. export PYTHON_BUILD_CACHE_PATH="${PYENV_ROOT}/cache"
  155. fi
  156. # Default PYENV_VERSION to the friendly Python version. (The
  157. # CPython installer requires an existing Python installation to run. An
  158. # unsatisfied local .python-version file can cause the installer to
  159. # fail.)
  160. if [[ "${VERSION_NAME}" == [23]"."* ]]; then
  161. for version in "${VERSION_NAME%-dev}" "${VERSION_NAME%.*}" "${VERSION_NAME%%.*}"; do
  162. PYENV_VERSION="$(pyenv-whence "python${version}" 2>/dev/null | tail -n 1 || true)"
  163. if [ -n "${PYENV_VERSION}" ]; then
  164. export PYENV_VERSION
  165. break
  166. fi
  167. done
  168. fi
  169. # PyPy/PyPy3 requires existing Python 2.7 to build
  170. if [[ "${VERSION_NAME}" == "pypy-"*"-src" ]] || [[ "${VERSION_NAME}" == "pypy3-"*"-src" ]]; then
  171. if [ -z "$PYENV_RPYTHON_VERSION" ]; then
  172. for version in $(pyenv-versions --bare | sort -r); do
  173. if [[ "$version" == "2.7"* ]]; then
  174. PYENV_RPYTHON_VERSION="$version"
  175. fi
  176. done
  177. fi
  178. if [ -n "$PYENV_RPYTHON_VERSION" ]; then
  179. if PYENV_VERSION="$PYENV_RPYTHON_VERSION" pyenv-exec python -c 'import curses' 1>/dev/null 2>&1; then
  180. export PYENV_VERSION="$PYENV_RPYTHON_VERSION"
  181. else
  182. echo "pyenv-install: $VERSION_NAME: PyPy requires \`curses' in $PYENV_RPYTHON_VERSION to build from source." >&2
  183. exit 1
  184. fi
  185. else
  186. echo "pyenv-install: $VERSION_NAME: PyPy requires Python 2.5, 2.6 or 2.7 to build from source." >&2
  187. exit 1
  188. fi
  189. fi
  190. # Execute `before_install` hooks.
  191. for hook in "${before_hooks[@]}"; do eval "$hook"; done
  192. # Plan cleanup on unsuccessful installation.
  193. cleanup() {
  194. [ -z "${PREFIX_EXISTS}" ] && rm -rf "$PREFIX"
  195. }
  196. trap cleanup SIGINT
  197. # Invoke `python-build` and record the exit status in $STATUS.
  198. STATUS=0
  199. python-build $KEEP $VERBOSE $HAS_PATCH $DEBUG "$DEFINITION" "$PREFIX" || STATUS="$?"
  200. # Display a more helpful message if the definition wasn't found.
  201. if [ "$STATUS" == "2" ]; then
  202. { candidates="$(definitions "$DEFINITION")"
  203. here="$(dirname "${0%/*}")/../.."
  204. if [ -n "$candidates" ]; then
  205. echo
  206. echo "The following versions contain \`$DEFINITION' in the name:"
  207. echo "$candidates" | indent
  208. fi
  209. echo
  210. echo "See all available versions with \`pyenv install --list'."
  211. echo
  212. echo -n "If the version you need is missing, try upgrading pyenv"
  213. if [ "$here" != "${here#$(brew --prefix 2>/dev/null)}" ]; then
  214. printf ":\n\n"
  215. echo " brew update && brew upgrade pyenv"
  216. elif [ -d "${here}/.git" ]; then
  217. printf ":\n\n"
  218. echo " cd ${here} && git pull && cd -"
  219. else
  220. printf ".\n"
  221. fi
  222. } >&2
  223. fi
  224. # Execute `after_install` hooks.
  225. for hook in "${after_hooks[@]}"; do eval "$hook"; done
  226. # Run `pyenv-rehash` after a successful installation.
  227. if [ "$STATUS" == "0" ]; then
  228. pyenv-rehash
  229. else
  230. cleanup
  231. fi
  232. exit "$STATUS"