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.

80 lines
2.4 KiB

  1. #!/usr/bin/env bash
  2. # Summary: Print the latest installed or known version with the given prefix
  3. # Usage: pyenv latest [-k|--known] [-q|--quiet] <prefix>
  4. #
  5. # -k/--known Select from all known versions instead of installed
  6. # -q/--quiet Do not print an error message on resolution failure
  7. set -e
  8. [ -n "$PYENV_DEBUG" ] && set -x
  9. while [[ $# -gt 0 ]]
  10. do
  11. case "$1" in
  12. -k|--known)
  13. FROM_KNOWN=1
  14. shift
  15. ;;
  16. -q|--quiet)
  17. QUIET=1
  18. shift
  19. ;;
  20. *)
  21. break
  22. ;;
  23. esac
  24. done
  25. prefix=$1
  26. exitcode=0
  27. IFS=$'\n'
  28. if [[ -z $FROM_KNOWN ]]; then
  29. DEFINITION_CANDIDATES=( $(pyenv-versions --bare) )
  30. else
  31. DEFINITION_CANDIDATES=( $(python-build --definitions ) )
  32. fi
  33. if printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | grep -qxFe "$prefix"; then
  34. echo "$prefix"
  35. exit $exitcode;
  36. fi
  37. # https://stackoverflow.com/questions/11856054/is-there-an-easy-way-to-pass-a-raw-string-to-grep/63483807#63483807
  38. prefix_re="$(sed 's/[^\^]/[&]/g;s/[\^]/\\&/g' <<< "$prefix")"
  39. # FIXME: more reliable and readable would probably be to loop over them and transform in pure Bash
  40. DEFINITION_CANDIDATES=(\
  41. $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
  42. grep -Ee "^$prefix_re[-.]" || true))
  43. DEFINITION_CANDIDATES=(\
  44. $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
  45. sed -E -e '/-dev$/d' -e '/-src$/d' -e '/-latest$/d' -e '/(b|rc)[0-9]+$/d'));
  46. # Compose a sorting key, followed by | and original value
  47. DEFINITION_CANDIDATES=(\
  48. $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
  49. awk \
  50. '{ if (match($0,"^[[:alnum:]]+-"))
  51. { print substr($0,0,RLENGTH-1) "." substr($0,RLENGTH+1) "..|" $0; }
  52. else
  53. { print $0 "...|" $0; }
  54. }'))
  55. DEFINITION_CANDIDATES=(\
  56. $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" \
  57. | sort -t. -k1,1r -k 2,2nr -k 3,3nr -k4,4nr \
  58. | cut -f2 -d $'|' \
  59. || true))
  60. DEFINITION="${DEFINITION_CANDIDATES[0]}"
  61. if [[ -n "$DEFINITION" ]]; then
  62. echo "$DEFINITION"
  63. else
  64. if [[ -z $QUIET ]]; then
  65. echo "pyenv: no $([[ -z $FROM_KNOWN ]] && echo installed || echo known) versions match the prefix \`$prefix'" >&2
  66. fi
  67. exitcode=1
  68. fi
  69. exit $exitcode