diff --git a/plugins/python-build/README.md b/plugins/python-build/README.md index 93e66120..3b60c1dd 100644 --- a/plugins/python-build/README.md +++ b/plugins/python-build/README.md @@ -67,6 +67,13 @@ exact name of the version you want to install. For example, Python versions will be installed into a directory of the same name under `~/.pyenv/versions`. +To install a version under a different name -- for instance, to keep several +builds of the same version side by side -- append `:` to the version: + + pyenv install 3.12.0:3.12-custom + +This installs into `~/.pyenv/versions/3.12-custom`. + To see a list of all available Python versions, run `pyenv install --list`. You may also tab-complete available Python versions if your pyenv installation is properly configured. diff --git a/plugins/python-build/bin/pyenv-install b/plugins/python-build/bin/pyenv-install index 508e8a24..6e5fcb60 100755 --- a/plugins/python-build/bin/pyenv-install +++ b/plugins/python-build/bin/pyenv-install @@ -20,6 +20,13 @@ # --version Show version of python-build # -g/--debug Build a debug version # +# Append `:' to a version to install it under a custom name, so that +# several builds of the same version can coexist: +# +# pyenv install 3.12.0:my-3.12 +# +# This installs into $PYENV_ROOT/versions/my-3.12. +# # For detailed information on installing Python versions with # python-build, including a list of environment variables for adjusting # compilation, see: https://github.com/pyenv/pyenv#readme @@ -123,6 +130,20 @@ DEFINITIONS=("${ARGUMENTS[@]}") [[ "${#DEFINITIONS[*]}" -eq 0 ]] && DEFINITIONS=($(pyenv-local 2>/dev/null || true)) [[ "${#DEFINITIONS[*]}" -eq 0 ]] && usage 1 >&2 +# A `:` argument installs under the custom name +# , so that several builds of the same version can coexist. The `latest` +# suffix is reserved for latest-version resolution (see the `install` hook), so +# it is left untouched here. +declare -a ALIASES +for i in "${!DEFINITIONS[@]}"; do + definition="${DEFINITIONS[$i]}" + alias="${definition##*:}" + if [[ "$definition" == *:* ]] && [ "$alias" != "latest" ]; then + DEFINITIONS[$i]="${definition%:*}" + ALIASES[$i]="$alias" + fi +done + # Define `before_install` and `after_install` functions that allow # plugin hooks to register a string of code for execution before or # after the installation process. @@ -152,7 +173,9 @@ IFS="$OLDIFS" for script in "${scripts[@]}"; do source "$script"; done COMBINED_STATUS=0 -for DEFINITION in "${DEFINITIONS[@]}"; do +for i in "${!DEFINITIONS[@]}"; do + DEFINITION="${DEFINITIONS[$i]}" + VERSION_ALIAS="${ALIASES[$i]}" STATUS=0 # Try to resolve a prefix if user indeed gave a prefix. @@ -161,9 +184,12 @@ for DEFINITION in "${DEFINITIONS[@]}"; do DEFINITION="$(pyenv-latest -f -k "$DEFINITION")" # Set VERSION_NAME from $DEFINITION. Then compute the installation prefix. + # With a `:` argument, install under the alias instead; + # VERSION_NAME still reflects the real version so version-specific build logic + # (e.g. the bootstrap version detection below) keeps working. VERSION_NAME="${DEFINITION##*/}" [ -n "$DEBUG" ] && VERSION_NAME="${VERSION_NAME}-debug" - PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}" + PREFIX="${PYENV_ROOT}/versions/${VERSION_ALIAS:-$VERSION_NAME}" [ -d "${PREFIX}" ] && PREFIX_EXISTS=1 @@ -188,7 +214,7 @@ for DEFINITION in "${DEFINITIONS[@]}"; do # If PYENV_BUILD_ROOT is set, always pass keep options to python-build. if [ -n "${PYENV_BUILD_ROOT}" ]; then - export PYTHON_BUILD_BUILD_PATH="${PYENV_BUILD_ROOT}/${VERSION_NAME}" + export PYTHON_BUILD_BUILD_PATH="${PYENV_BUILD_ROOT}/${VERSION_ALIAS:-$VERSION_NAME}" KEEP="-k" fi diff --git a/plugins/python-build/test/pyenv.bats b/plugins/python-build/test/pyenv.bats index 9b514d78..8d4ec144 100644 --- a/plugins/python-build/test/pyenv.bats +++ b/plugins/python-build/test/pyenv.bats @@ -31,6 +31,32 @@ stub_python_build() { unstub python-build } +@test "install a single version under an alias" { + stub_python_build_lib + stub_python_build + + run pyenv-install 3.4.2:3.4.2-custom + assert_success "python-build 3.4.2 ${PYENV_ROOT}/versions/3.4.2-custom" + + unstub python-build +} + +@test "install multiple versions, each under its own alias" { + stub_python_build_lib + stub_python_build + stub_python_build + + run pyenv-install 3.4.1:custom1 3.4.2:custom2 + assert_success + assert_output <