mirror of
https://github.com/pyenv/pyenv.git
synced 2026-08-05 12:00:34 +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
|
## 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
|
Installs `<version>` from source under a separate name, packages that install
|
||||||
that install with `save`, then emits a python-build definition for it with
|
with `save`, then emits a python-build definition for it with
|
||||||
`generate-installer`. The archive, metadata and definition land in the current
|
`generate-installer`. With no explicit entry, the name is generated from the
|
||||||
directory, named after the entry; host the archive under `<url>` and drop the
|
current platform, platform version and architecture. An explicit entry keeps
|
||||||
definition into python-build's definition directory. Keeping the entry name
|
the existing custom-build workflow.
|
||||||
distinct from the version lets the binary sit alongside a normal source
|
|
||||||
install of the same version.
|
|
||||||
|
|
||||||
```sh
|
```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
|
--archive-base-url https://example.com/binaries
|
||||||
# writes 3.12.7-debian-12.tar.gz, its .meta file and
|
# On Debian 12 x86_64, writes 3.12.7-debian-12-x86_64.tar.gz,
|
||||||
# a `3.12.7-debian-12' definition
|
# 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>]`
|
### `pyenv binary save <version> [<output-dir>] [--name <name>]`
|
||||||
|
|||||||
@ -2,18 +2,17 @@
|
|||||||
#
|
#
|
||||||
# Summary: Create an installable binary package from a Python version
|
# 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
|
# Installs <version> from source under a separate entry name, saves it as a
|
||||||
# a binary package, then emits a python-build definition for that package.
|
# binary package, then emits a python-build definition for that package.
|
||||||
# The archive, metadata and definition are written to the current directory
|
# The archive, metadata and definition are written to the current directory
|
||||||
# as <entry>.tar.gz, <entry>.meta and <entry>.
|
# as <entry>.tar.gz, <entry>.meta and <entry>.
|
||||||
#
|
#
|
||||||
# <version> A version `pyenv install' knows how to build.
|
# <version> A version `pyenv install' knows how to build.
|
||||||
# <entry> The name to build under and to install the binary
|
# <entry> The optional name to build under and install the
|
||||||
# as, e.g. `3.13.14-debian-12'. Keeping it distinct
|
# binary as. If omitted, a name is generated from the
|
||||||
# from <version> lets the binary sit alongside a
|
# current platform, platform version and architecture.
|
||||||
# normal source install of the same version.
|
|
||||||
# --archive-base-url <url>
|
# --archive-base-url <url>
|
||||||
# Where the archive will be hosted; the definition
|
# Where the archive will be hosted; the definition
|
||||||
# downloads it from <url>/<entry>.tar.gz.
|
# downloads it from <url>/<entry>.tar.gz.
|
||||||
@ -49,13 +48,9 @@ if [ -z "$spec" ] || [ -z "$archive_base_url" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
case "$spec" in
|
case "$spec" in
|
||||||
*?:?* ) ;;
|
*?:?* ) entry="${spec##*:}" ;;
|
||||||
* )
|
* ) entry="$(pyenv-binary-package-name "$spec")"; spec="${spec}:${entry}" ;;
|
||||||
echo "pyenv-binary: expected <version>:<entry>, e.g. \`3.13.14:3.13.14-debian-12'" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
entry="${spec##*:}"
|
|
||||||
|
|
||||||
case "$entry" in
|
case "$entry" in
|
||||||
# `pyenv install' reads a trailing `:latest' as part of the version rather than
|
# `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'"
|
assert_failure "pyenv-binary: unexpected argument \`extra'"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "rejects a bare version without an entry name" {
|
@test "generates an entry name for a bare version" {
|
||||||
run pyenv-binary-package 3.12.7 --archive-base-url http://x/b
|
stub_build_environment
|
||||||
assert_failure "pyenv-binary: expected <version>:<entry>, e.g. \`3.13.14:3.13.14-debian-12'"
|
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" {
|
@test "rejects an entry name containing a slash" {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user