#!/usr/bin/env bash # # Summary: Create an installable binary package from a Python version # # Usage: pyenv binary package : --archive-base-url # # Installs from source under the separate name , saves it as # a binary package, then emits a python-build definition for that package. # The archive, metadata and definition are written to the current directory # as .tar.gz, .meta and . # # A version `pyenv install' knows how to build. # The name to build under and to install the binary # as, e.g. `3.13.14-debian-12'. Keeping it distinct # from lets the binary sit alongside a # normal source install of the same version. # --archive-base-url # Where the archive will be hosted; the definition # downloads it from /.tar.gz. # set -e [ -n "$PYENV_DEBUG" ] && set -x # Provide pyenv completions if [ "$1" = "--complete" ]; then echo --archive-base-url exec pyenv-install --list --bare fi spec="" archive_base_url="" while [ $# -gt 0 ]; do case "$1" in --archive-base-url ) [ $# -ge 2 ] || { echo "pyenv-binary: --archive-base-url needs a value" >&2; exit 1; } archive_base_url="$2"; shift 2 ;; -* ) echo "pyenv-binary: unknown option \`$1'" >&2; exit 1 ;; * ) [ -z "$spec" ] || { echo "pyenv-binary: unexpected argument \`$1'" >&2; exit 1; } spec="$1"; shift ;; esac done if [ -z "$spec" ] || [ -z "$archive_base_url" ]; then pyenv-help --usage binary-package >&2 exit 1 fi case "$spec" in *?:?* ) ;; * ) echo "pyenv-binary: expected :, e.g. \`3.13.14:3.13.14-debian-12'" >&2 exit 1 ;; esac entry="${spec##*:}" case "$entry" in # `pyenv install' reads a trailing `:latest' as part of the version rather than # as an alias, so nothing would end up installed under that name. latest ) echo "pyenv-binary: \`latest' cannot be used as an entry name" >&2 exit 1 ;; # The entry becomes a directory name under versions/. `pyenv install' does not # validate the alias, and `save' only checks once the build is done, so refuse # a name that could point elsewhere before compiling anything. */* | .. | . ) echo "pyenv-binary: invalid entry name \`${entry}'" >&2 exit 1 ;; esac os="$(uname -s)" # `generate-installer' refuses a macOS archive, so the last step here cannot # succeed on one. Give up before compiling rather than after it. if [ "$os" = "Darwin" ]; then echo "pyenv-binary: macOS archives are not supported yet" >&2 exit 1 fi # `pyenv install' puts a `:' build under versions/. pyenv-install "$spec" pyenv-binary-save "$entry" "$PWD" --name "$entry" pyenv-binary-generate-installer "${entry}.meta" \ --archive-url "${archive_base_url%/}/${entry}.tar.gz" -o "$entry"