diff --git a/plugins/.gitignore b/plugins/.gitignore index acd0fcce..2a5caf55 100644 --- a/plugins/.gitignore +++ b/plugins/.gitignore @@ -2,4 +2,5 @@ !/.gitignore !/version-ext-compat !/python-build +!/pyenv-binary /python-build/test/build diff --git a/plugins/pyenv-binary/README.md b/plugins/pyenv-binary/README.md new file mode 100644 index 00000000..4caa6252 --- /dev/null +++ b/plugins/pyenv-binary/README.md @@ -0,0 +1,15 @@ +# pyenv-binary (experimental) + +Package an installed Python version into a relocatable archive that can be +installed on another machine. + +This is experimental and intentionally decoupled: it does not change +`pyenv install` or any other command. You drive it explicitly through +`pyenv binary`. Run `pyenv binary --help` for details on a command. + +## Portability + +An archive is portable across machines that share its build platform (OS, +architecture and a compatible libc) and have the recorded system libraries. It +is not portable across, say, glibc and musl, or to an older glibc; the platform +and dependency metadata exist to catch that. diff --git a/plugins/pyenv-binary/bin/pyenv-binary b/plugins/pyenv-binary/bin/pyenv-binary new file mode 100755 index 00000000..9cd29950 --- /dev/null +++ b/plugins/pyenv-binary/bin/pyenv-binary @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Summary: Package an installed Python version as a relocatable binary (experimental) +# +# Usage: pyenv binary [] +# +# `pyenv binary` packages an already-installed Python version into a relocatable +# archive that can be installed on another machine. It is experimental and does +# not touch `pyenv install' or any other command. +# +# Run `pyenv binary' to list its commands, or `pyenv binary --help' +# for command-specific help. +# +set -e +[ -n "$PYENV_DEBUG" ] && set -x + +libexec="${BASH_SOURCE%/*}/../libexec" + +list_commands() { + local path + for path in "$libexec"/pyenv-binary-*; do + [ -e "$path" ] && echo "${path##*/pyenv-binary-}" + done +} + +# Provide pyenv completions +if [ "$1" = "--complete" ]; then + shift + if [ -z "$1" ]; then + list_commands + else + command_path="${libexec}/pyenv-binary-$1" + shift + [ -x "$command_path" ] && exec "$command_path" --complete "$@" + fi + exit +fi + +subcommand="$1" +if [ -z "$subcommand" ]; then + { pyenv-help binary + echo + echo "Commands:" + list_commands | sed 's/^/ /' + } >&2 + exit 1 +fi +shift + +command_path="${libexec}/pyenv-binary-${subcommand}" +if [ ! -x "$command_path" ]; then + echo "pyenv-binary: no such command \`${subcommand}'" >&2 + exit 1 +fi + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + # `pyenv help' looks the command up on PATH; the subcommands live in libexec. + PATH="${libexec}:${PATH}" exec pyenv-help "binary-${subcommand}" +fi + +exec "$command_path" "$@"