mirror of
https://github.com/pyenv/pyenv.git
synced 2026-08-05 20:10:35 +09:00
pyenv-binary: generate platform-specific package names (#3504)
This commit is contained in:
parent
3088203e33
commit
b9e165271e
@ -16,21 +16,38 @@ and dependency metadata exist to catch that.
|
||||
|
||||
## Commands
|
||||
|
||||
### `pyenv binary package <version>:<entry> --archive-base-url <url>`
|
||||
### `pyenv binary package <version>[:<entry>] --archive-base-url <url>`
|
||||
|
||||
Installs `<version>` from source under the separate name `<entry>`, packages
|
||||
that install with `save`, then emits a python-build definition for it with
|
||||
`generate-installer`. The archive, metadata and definition land in the current
|
||||
directory, named after the entry; host the archive under `<url>` and drop the
|
||||
definition into python-build's definition directory. Keeping the entry name
|
||||
distinct from the version lets the binary sit alongside a normal source
|
||||
install of the same version.
|
||||
Installs `<version>` from source under a separate name, packages that install
|
||||
with `save`, then emits a python-build definition for it with
|
||||
`generate-installer`. With no explicit entry, the name is generated from the
|
||||
current platform, platform version and architecture. An explicit entry keeps
|
||||
the existing custom-build workflow.
|
||||
|
||||
```sh
|
||||
pyenv binary package 3.12.7:3.12.7-debian-12 \
|
||||
pyenv binary package 3.12.7 \
|
||||
--archive-base-url https://example.com/binaries
|
||||
# writes 3.12.7-debian-12.tar.gz, its .meta file and
|
||||
# a `3.12.7-debian-12' definition
|
||||
# On Debian 12 x86_64, writes 3.12.7-debian-12-x86_64.tar.gz,
|
||||
# its .meta file and a `3.12.7-debian-12-x86_64' definition.
|
||||
|
||||
pyenv binary package 3.12.7:company-python \
|
||||
--archive-base-url https://example.com/binaries
|
||||
```
|
||||
|
||||
The archive, metadata and definition land in the current directory, named after
|
||||
the entry. Host the archive under `<url>` and drop the definition into
|
||||
python-build's definition directory.
|
||||
|
||||
### `pyenv binary package-name <version>`
|
||||
|
||||
Prints the automatically generated entry name without building anything. Linux
|
||||
uses the distribution name and version, macOS uses the macOS version, and other
|
||||
systems use the name and release reported by `uname`. All names include the
|
||||
architecture.
|
||||
|
||||
```sh
|
||||
pyenv binary package-name 3.12.7
|
||||
# 3.12.7-debian-12-x86_64
|
||||
```
|
||||
|
||||
### `pyenv binary save <version> [<output-dir>] [--name <name>]`
|
||||
|
||||
@ -2,18 +2,17 @@
|
||||
#
|
||||
# Summary: Create an installable binary package from a Python version
|
||||
#
|
||||
# Usage: pyenv binary package <version>:<entry> --archive-base-url <url>
|
||||
# Usage: pyenv binary package <version>[:<entry>] --archive-base-url <url>
|
||||
#
|
||||
# Installs <version> from source under the separate name <entry>, saves it as
|
||||
# a binary package, then emits a python-build definition for that package.
|
||||
# Installs <version> from source under a separate entry 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 <entry>.tar.gz, <entry>.meta and <entry>.
|
||||
#
|
||||
# <version> A version `pyenv install' knows how to build.
|
||||
# <entry> The name to build under and to install the binary
|
||||
# as, e.g. `3.13.14-debian-12'. Keeping it distinct
|
||||
# from <version> lets the binary sit alongside a
|
||||
# normal source install of the same version.
|
||||
# <entry> The optional name to build under and install the
|
||||
# binary as. If omitted, a name is generated from the
|
||||
# current platform, platform version and architecture.
|
||||
# --archive-base-url <url>
|
||||
# Where the archive will be hosted; the definition
|
||||
# downloads it from <url>/<entry>.tar.gz.
|
||||
@ -49,13 +48,9 @@ if [ -z "$spec" ] || [ -z "$archive_base_url" ]; then
|
||||
fi
|
||||
|
||||
case "$spec" in
|
||||
*?:?* ) ;;
|
||||
* )
|
||||
echo "pyenv-binary: expected <version>:<entry>, e.g. \`3.13.14:3.13.14-debian-12'" >&2
|
||||
exit 1
|
||||
;;
|
||||
*?:?* ) entry="${spec##*:}" ;;
|
||||
* ) entry="$(pyenv-binary-package-name "$spec")"; spec="${spec}:${entry}" ;;
|
||||
esac
|
||||
entry="${spec##*:}"
|
||||
|
||||
case "$entry" in
|
||||
# `pyenv install' reads a trailing `:latest' as part of the version rather than
|
||||
|
||||
71
plugins/pyenv-binary/libexec/pyenv-binary-package-name
Executable file
71
plugins/pyenv-binary/libexec/pyenv-binary-package-name
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Generate a binary package name for the current platform
|
||||
#
|
||||
# Usage: pyenv binary package-name <version>
|
||||
#
|
||||
# Prints a package name containing the Python version, platform name,
|
||||
# platform version and architecture.
|
||||
#
|
||||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
if [ "$1" = "--complete" ]; then
|
||||
exec pyenv-install --list --bare
|
||||
fi
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
pyenv-help --usage binary-package-name >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version="$1"
|
||||
|
||||
case "$version" in
|
||||
*/* | .. | . | *[[:cntrl:]]* )
|
||||
echo "pyenv-binary: invalid version name \`${version}'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
os="$(uname -s)"
|
||||
arch="$(uname -m)"
|
||||
distro=""
|
||||
distro_version=""
|
||||
|
||||
case "$os" in
|
||||
Linux )
|
||||
if type -p lsb_release >/dev/null; then
|
||||
distro="$(lsb_release -si)"
|
||||
distro_version="$(lsb_release -sr)"
|
||||
elif [ -r /etc/os-release ]; then
|
||||
distro="$(. /etc/os-release && printf '%s' "${ID:-}")"
|
||||
distro_version="$(. /etc/os-release && printf '%s' "${VERSION_ID:-}")"
|
||||
fi
|
||||
;;
|
||||
Darwin )
|
||||
distro="macos"
|
||||
distro_version="$(sw_vers -productVersion)"
|
||||
;;
|
||||
* )
|
||||
distro="$os"
|
||||
distro_version="$(uname -r)"
|
||||
;;
|
||||
esac
|
||||
|
||||
slug() {
|
||||
printf '%s' "$1" |
|
||||
tr '[:upper:] ' '[:lower:]-' |
|
||||
tr -cd 'a-z0-9._-'
|
||||
}
|
||||
|
||||
distro="$(slug "$distro")"
|
||||
distro_version="$(slug "$distro_version")"
|
||||
arch="$(slug "$arch")"
|
||||
|
||||
if [ -z "$distro" ] || [ -z "$distro_version" ] || [ -z "$arch" ]; then
|
||||
echo "pyenv-binary: could not determine the package platform" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s-%s-%s-%s\n' "$version" "$distro" "$distro_version" "$arch"
|
||||
54
plugins/pyenv-binary/test/package-name.bats
Normal file
54
plugins/pyenv-binary/test/package-name.bats
Normal file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "completion lists installable versions" {
|
||||
create_stub pyenv-install \
|
||||
'[ "$*" = "--list --bare" ] && echo 3.13.14'
|
||||
|
||||
run pyenv-binary-package-name --complete
|
||||
assert_success "3.13.14"
|
||||
}
|
||||
|
||||
@test "fails without a version" {
|
||||
create_stub pyenv-help 'echo usage'
|
||||
|
||||
run pyenv-binary-package-name
|
||||
assert_failure "usage"
|
||||
}
|
||||
|
||||
@test "rejects a second argument" {
|
||||
create_stub pyenv-help 'echo usage'
|
||||
|
||||
run pyenv-binary-package-name 3.13.14 extra
|
||||
assert_failure "usage"
|
||||
}
|
||||
|
||||
@test "generates a package name for Linux" {
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
create_stub lsb_release 'case "$1" in -si) echo Debian;; -sr) echo 12;; esac'
|
||||
|
||||
run pyenv-binary-package-name 3.13.14
|
||||
assert_success "3.13.14-debian-12-x86_64"
|
||||
}
|
||||
|
||||
@test "generates a package name for macOS" {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_stub sw_vers 'echo 15.5'
|
||||
|
||||
run pyenv-binary-package-name 3.13.14
|
||||
assert_success "3.13.14-macos-15.5-arm64"
|
||||
}
|
||||
|
||||
@test "generates a package name for FreeBSD" {
|
||||
create_stub uname \
|
||||
'case "$1" in -s) echo FreeBSD;; -m) echo amd64;; -r) echo 14.2-RELEASE-p3;; esac'
|
||||
|
||||
run pyenv-binary-package-name 3.13.14
|
||||
assert_success "3.13.14-freebsd-14.2-release-p3-amd64"
|
||||
}
|
||||
|
||||
@test "rejects an invalid version name" {
|
||||
run pyenv-binary-package-name ../3.13.14
|
||||
assert_failure "pyenv-binary: invalid version name \`../3.13.14'"
|
||||
}
|
||||
@ -45,9 +45,18 @@ stub_build_environment() {
|
||||
assert_failure "pyenv-binary: unexpected argument \`extra'"
|
||||
}
|
||||
|
||||
@test "rejects a bare version without an entry name" {
|
||||
run pyenv-binary-package 3.12.7 --archive-base-url http://x/b
|
||||
assert_failure "pyenv-binary: expected <version>:<entry>, e.g. \`3.13.14:3.13.14-debian-12'"
|
||||
@test "generates an entry name for a bare version" {
|
||||
stub_build_environment
|
||||
create_stub lsb_release 'case "$1" in -si) echo Debian;; -sr) echo 12;; esac'
|
||||
cd "${BATS_TEST_TMPDIR}"
|
||||
|
||||
run pyenv-binary-package 3.12.7 --archive-base-url http://example.com/binaries
|
||||
assert_success
|
||||
assert [ -d "${PYENV_ROOT}/versions/3.12.7-debian-12-x86_64" ]
|
||||
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.tar.gz" ]
|
||||
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.meta" ]
|
||||
run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64"
|
||||
assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-debian-12-x86_64.tar.gz"
|
||||
}
|
||||
|
||||
@test "rejects an entry name containing a slash" {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user