You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
2.8 KiB

  1. #!/usr/bin/env bash
  2. # Summary: List all Python versions available to pyenv
  3. # Usage: pyenv versions [--bare] [--skip-aliases]
  4. #
  5. # Lists all Python versions found in `$PYENV_ROOT/versions/*'.
  6. set -e
  7. [ -n "$PYENV_DEBUG" ] && set -x
  8. unset bare
  9. unset skip_aliases
  10. # Provide pyenv completions
  11. for arg; do
  12. case "$arg" in
  13. --complete )
  14. echo --bare
  15. echo --skip-aliases
  16. exit ;;
  17. --bare ) bare=1 ;;
  18. --skip-aliases ) skip_aliases=1 ;;
  19. * )
  20. pyenv-help --usage versions >&2
  21. exit 1
  22. ;;
  23. esac
  24. done
  25. versions_dir="${PYENV_ROOT}/versions"
  26. if ! enable -f "${BASH_SOURCE%/*}"/pyenv-realpath.dylib realpath 2>/dev/null; then
  27. if [ -n "$PYENV_NATIVE_EXT" ]; then
  28. echo "pyenv: failed to load \`realpath' builtin" >&2
  29. exit 1
  30. fi
  31. READLINK=$(type -p greadlink readlink | head -1)
  32. if [ -z "$READLINK" ]; then
  33. echo "pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
  34. exit 1
  35. fi
  36. resolve_link() {
  37. $READLINK "$1"
  38. }
  39. realpath() {
  40. local cwd="$PWD"
  41. local path="$1"
  42. local name
  43. while [ -n "$path" ]; do
  44. name="${path##*/}"
  45. [ "$name" = "$path" ] || cd "${path%/*}"
  46. path="$(resolve_link "$name" || true)"
  47. done
  48. echo "${PWD}/$name"
  49. cd "$cwd"
  50. }
  51. fi
  52. if [ -d "$versions_dir" ]; then
  53. versions_dir="$(realpath "$versions_dir")"
  54. fi
  55. if [ -n "$bare" ]; then
  56. hit_prefix=""
  57. miss_prefix=""
  58. current_versions=()
  59. include_system=""
  60. else
  61. hit_prefix="* "
  62. miss_prefix=" "
  63. OLDIFS="$IFS"
  64. IFS=: current_versions=($(pyenv-version-name || true))
  65. IFS="$OLDIFS"
  66. include_system="1"
  67. fi
  68. num_versions=0
  69. exists() {
  70. local car="$1"
  71. local cdar
  72. shift
  73. for cdar in "$@"; do
  74. if [ "${car}" == "${cdar}" ]; then
  75. return 0
  76. fi
  77. done
  78. return 1
  79. }
  80. print_version() {
  81. if exists "$1" "${current_versions[@]}"; then
  82. echo "${hit_prefix}$1 (set by $(pyenv-version-origin))"
  83. else
  84. echo "${miss_prefix}$1"
  85. fi
  86. num_versions=$((num_versions + 1))
  87. }
  88. # Include "system" in the non-bare output, if it exists
  89. if [ -n "$include_system" ] && PYENV_VERSION=system pyenv-which python >/dev/null 2>&1; then
  90. print_version system
  91. fi
  92. shopt -s nullglob
  93. for path in "$versions_dir"/*; do
  94. if [ -d "$path" ]; then
  95. if [ -n "$skip_aliases" ] && [ -L "$path" ]; then
  96. target="$(realpath "$path")"
  97. [ "${target%/*}" != "$versions_dir" ] || continue
  98. [ "${target%/*/envs/*}" != "$versions_dir" ] || continue
  99. fi
  100. print_version "${path##*/}"
  101. # virtual environments created by anaconda/miniconda
  102. for env_path in "${path}/envs/"*; do
  103. if [ -d "${env_path}" ]; then
  104. print_version "${env_path#${PYENV_ROOT}/versions/}"
  105. fi
  106. done
  107. fi
  108. done
  109. shopt -u nullglob
  110. if [ "$num_versions" -eq 0 ] && [ -n "$include_system" ]; then
  111. echo "Warning: no Python detected on the system" >&2
  112. exit 1
  113. fi