mirror of
https://github.com/pyenv/pyenv.git
synced 2026-09-10 07:36:16 -04:00
Compare commits
No commits in common. "master" and "v2.8.3" have entirely different histories.
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -3,6 +3,9 @@ Make sure you have checked all steps below.
|
|||
### Prerequisite
|
||||
* [ ] Please consider implementing the feature as a hook script or plugin as a first step.
|
||||
* pyenv has some powerful support for plugins and hook scripts. Please refer to [Authoring plugins](https://github.com/pyenv/pyenv/wiki/Authoring-plugins) for details and try to implement it as a plugin if possible.
|
||||
* [ ] Please consider contributing the patch upstream to [rbenv](https://github.com/rbenv/rbenv), since we have borrowed most of the code from that project.
|
||||
* We occasionally import the changes from rbenv. In general, you can expect changes made in rbenv will be imported to pyenv too, eventually.
|
||||
* Generally speaking, we prefer not to make changes in the core in order to keep compatibility with rbenv.
|
||||
* [ ] My PR addresses the following pyenv issue (if any)
|
||||
- Closes https://github.com/pyenv/pyenv/issues/XXXX
|
||||
|
||||
|
|
|
|||
44
.github/actions/build-python/action.yml
vendored
44
.github/actions/build-python/action.yml
vendored
|
|
@ -1,44 +0,0 @@
|
|||
name: Build a Python version
|
||||
description: >
|
||||
Install python-build's system dependencies for the current runner's OS, build
|
||||
and check the requested version.
|
||||
inputs:
|
||||
python-version:
|
||||
description: A version as accepted by `pyenv install`.
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
#envvars
|
||||
export PYENV_ROOT="$GITHUB_WORKSPACE"
|
||||
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
# The two OSes differ only in this step.
|
||||
- if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
#prerequisites
|
||||
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd
|
||||
- if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
#prerequisites
|
||||
pyenv install-prerequisites
|
||||
- shell: bash
|
||||
run: |
|
||||
#build
|
||||
pyenv --debug install ${{ inputs.python-version }} && rc=$? || rc=$?
|
||||
if [[ $rc -ne 0 ]]; then echo config.log:; cat "${TMPDIR:-/tmp}"/python-build*/*/config.log; false; fi
|
||||
pyenv global ${{ inputs.python-version }}
|
||||
pyenv rehash
|
||||
- shell: bash
|
||||
run: |
|
||||
#print version
|
||||
python --version
|
||||
python -m pip --version
|
||||
- shell: python # Prove that actual Python == expected Python
|
||||
env:
|
||||
EXPECTED_PYTHON: ${{ inputs.python-version }}
|
||||
run: import os, sys ; assert sys.version.startswith(os.getenv("EXPECTED_PYTHON"))
|
||||
62
.github/workflows/build.yml
vendored
62
.github/workflows/build.yml
vendored
|
|
@ -1,62 +0,0 @@
|
|||
name: build
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
discover_build_logic_change:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-slim
|
||||
env:
|
||||
FULL_OS_MATRIX: '[
|
||||
"macos-14",
|
||||
"macos-15",
|
||||
"macos-15-intel",
|
||||
"macos-26",
|
||||
"macos-26-intel",
|
||||
"ubuntu-22.04",
|
||||
"ubuntu-22.04-arm",
|
||||
"ubuntu-24.04",
|
||||
"ubuntu-24.04-arm"
|
||||
]'
|
||||
outputs:
|
||||
os: ${{ steps.detect.outputs.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: git fetch origin "$GITHUB_BASE_REF"
|
||||
- id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -n $(git diff --name-only "origin/$GITHUB_BASE_REF" -- \
|
||||
plugins/python-build/bin/python-build \
|
||||
.github/actions/build-python/action.yml \
|
||||
.github/workflows/build.yml) ]]
|
||||
then
|
||||
printf "%s\n" "os<<!" "$FULL_OS_MATRIX" "!" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: discover_build_logic_change
|
||||
# Run when the detection job succeeded *or was skipped* -- but not failed
|
||||
if: ${{ !cancelled() && !failure() }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ${{ fromJson(needs.discover_build_logic_change.outputs.os || '["macos-latest","ubuntu-latest"]') }}
|
||||
python-version:
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
- "3.14"
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: ./.github/actions/build-python
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
43
.github/workflows/macos_build.yml
vendored
Normal file
43
.github/workflows/macos_build.yml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: macos_build
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
macos_build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
- "3.14"
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: |
|
||||
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd
|
||||
- run: |
|
||||
#envvars
|
||||
export PYENV_ROOT="$GITHUB_WORKSPACE"
|
||||
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
- run: |
|
||||
#build
|
||||
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$?
|
||||
if [[ $rc -ne 0 ]]; then echo config.log:; cat $TMPDIR/python-build*/*/config.log; false; fi
|
||||
pyenv global ${{ matrix.python-version }}
|
||||
- run: |
|
||||
#print version
|
||||
python --version
|
||||
python -m pip --version
|
||||
- shell: python # Prove that actual Python == expected Python
|
||||
env:
|
||||
EXPECTED_PYTHON: ${{ matrix.python-version }}
|
||||
run: import os, sys ; assert sys.version.startswith(os.getenv("EXPECTED_PYTHON"))
|
||||
63
.github/workflows/modified_scripts_build.yml
vendored
63
.github/workflows/modified_scripts_build.yml
vendored
|
|
@ -2,7 +2,7 @@ name: modified_scripts
|
|||
on: [pull_request]
|
||||
jobs:
|
||||
discover_modified_scripts:
|
||||
runs-on: ubuntu-slim
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
versions: ${{steps.modified-versions.outputs.versions}}
|
||||
versions_cpython_only: ${{steps.modified-versions.outputs.versions_cpython_only}}
|
||||
|
|
@ -43,32 +43,28 @@ jobs:
|
|||
import packaging.version
|
||||
|
||||
result=[]
|
||||
def exclude_macos_intel(result, python_version):
|
||||
result.append({'os':'macos-15-intel','python-version':python_version})
|
||||
result.append({'os':'macos-26-intel','python-version':python_version})
|
||||
|
||||
|
||||
for line in os.environ['versions'].splitlines():
|
||||
if m:=re.match(r'miniconda3-\d+\.\d+-(\d+\.\d+\.\d+)', line):
|
||||
version = packaging.version.Version(m.group(1))
|
||||
if m:=re.match(r'([^-]+)-(\d+\.\d+)-(\d+\.\d+.\d+)', line):
|
||||
name, version = m.group(1), packaging.version.Version(m.group(3))
|
||||
|
||||
# Miniconda dropped MacOS x64 support
|
||||
if version >= packaging.version.Version('25.9.1'):
|
||||
exclude_macos_intel(result, line)
|
||||
if (name == 'miniconda3' and version >= packaging.version.Version('25.9.1')):
|
||||
result.append({'os':'macos-15-intel','python-version':line})
|
||||
|
||||
if m:=re.match(r'anaconda3-(\d+\.\d+)', line):
|
||||
version = packaging.version.Version(m.group(1))
|
||||
if m:=re.match(r'([^-]+)-(\d+\.\d+)', line):
|
||||
name, version = m.group(1), packaging.version.Version(m.group(2))
|
||||
|
||||
# Anaconda dropped MacOS x64 support
|
||||
if version >= packaging.version.Version('2025.12'):
|
||||
exclude_macos_intel(result, line)
|
||||
if name == 'anaconda3' and version >= packaging.version.Version('2025.12'):
|
||||
result.append({'os':'macos-15-intel','python-version':line})
|
||||
|
||||
if m:=re.match(r'graalpy[^-]*-(community-)?(\d+\.\d+\.\d+)', line):
|
||||
if m:=re.match(r'graalpy[^-]*-(community-)?(\d+\.\d+.\d+)', line):
|
||||
version = packaging.version.Version(m.group(2))
|
||||
|
||||
# GraalPy dropped MacOS x64 support
|
||||
if version >= packaging.version.Version('25.0.2'):
|
||||
exclude_macos_intel(result, line)
|
||||
result.append({'os':'macos-15-intel','python-version':line})
|
||||
|
||||
|
||||
EOF = str(random.getrandbits(15*8))
|
||||
|
|
@ -95,7 +91,6 @@ jobs:
|
|||
- macos-15
|
||||
- macos-15-intel
|
||||
- macos-26
|
||||
- macos-26-intel
|
||||
exclude: ${{fromJson(needs.discover_modified_scripts.outputs.versions_macos_build_exclude)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
|
@ -158,12 +153,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions_cpython_only)}}
|
||||
os:
|
||||
- macos-14
|
||||
- macos-15
|
||||
- macos-15-intel
|
||||
- macos-26
|
||||
- macos-26-intel
|
||||
os: ["macos-14", "macos-15", "macos-15-intel"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
|
@ -175,7 +165,12 @@ jobs:
|
|||
- run: |
|
||||
#prerequisites
|
||||
brew install sqlite3 xz tcl-tk@8 libb2 zstd
|
||||
"$GITHUB_WORKSPACE/.github/workflows/scripts/brew-uninstall-cascade.sh" $(brew list | grep -E '^openssl(@|$)') readline
|
||||
"$GITHUB_WORKSPACE/.github/workflows/scripts/brew-uninstall-cascade.sh" openssl@3 openssl@1.1 readline
|
||||
if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then
|
||||
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
|
||||
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
|
||||
pyenv install $PYENV_BOOTSTRAP_VERSION
|
||||
fi
|
||||
- run: |
|
||||
#build
|
||||
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$?
|
||||
|
|
@ -207,9 +202,7 @@ jobs:
|
|||
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
|
||||
os:
|
||||
- ubuntu-22.04
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-24.04
|
||||
- ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
|
@ -220,7 +213,10 @@ jobs:
|
|||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
- run: |
|
||||
#prerequisites
|
||||
pyenv install-prerequisites
|
||||
sudo apt-get update -q; sudo apt-get install -yq make build-essential \
|
||||
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
|
||||
curl llvm libncurses5-dev libncursesw5-dev \
|
||||
xz-utils tk-dev libffi-dev liblzma-dev
|
||||
if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then
|
||||
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
|
||||
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
|
||||
|
|
@ -269,7 +265,8 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions_cpython_only)}}
|
||||
runs-on: ubuntu-latest
|
||||
os: ["ubuntu-latest"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: |
|
||||
|
|
@ -277,10 +274,18 @@ jobs:
|
|||
export PYENV_ROOT="$GITHUB_WORKSPACE"
|
||||
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
echo "_PYTHON_BUILD_FORCE_SKIP_XZ=1" >> $GITHUB_ENV
|
||||
echo "_PYTHON_BUILD_FORCE_SKIP_XZ=1" >> $GITHUB_PATH
|
||||
- run: |
|
||||
#prerequisites
|
||||
pyenv install-prerequisites
|
||||
sudo apt-get update -q; sudo apt-get install -yq make build-essential \
|
||||
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
|
||||
curl llvm libncurses5-dev libncursesw5-dev \
|
||||
xz-utils tk-dev libffi-dev liblzma-dev
|
||||
if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then
|
||||
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
|
||||
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
|
||||
pyenv install $PYENV_BOOTSTRAP_VERSION
|
||||
fi
|
||||
- run: |
|
||||
#build
|
||||
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$?
|
||||
|
|
|
|||
23
.github/workflows/pyenv_tests.yml
vendored
23
.github/workflows/pyenv_tests.yml
vendored
|
|
@ -14,9 +14,7 @@ jobs:
|
|||
matrix:
|
||||
os:
|
||||
- ubuntu-22.04
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-24.04
|
||||
- ubuntu-24.04-arm
|
||||
- macos-14
|
||||
- macos-15
|
||||
- macos-15-intel
|
||||
|
|
@ -24,22 +22,25 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install prerequisites
|
||||
run: |
|
||||
- run: |
|
||||
if test "$RUNNER_OS" == "macOS"; then
|
||||
brew install coreutils fish
|
||||
fi
|
||||
- name: Run tests
|
||||
- run: pwd
|
||||
- env:
|
||||
PYENV_ROOT: /home/runner/work/pyenv/pyenv
|
||||
run: |
|
||||
echo $PYENV_ROOT
|
||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
- name: Run test on the host
|
||||
run: |
|
||||
make test
|
||||
- name: Run test with docker
|
||||
if: ${{ ! contains(matrix.os, 'macos') }}
|
||||
run: |
|
||||
make test-docker
|
||||
- env:
|
||||
PYENV_NATIVE_EXT: 1
|
||||
run: |
|
||||
(cd src; ./configure; make)
|
||||
bats/bin/bats test/{pyenv,hooks,versions}.bats
|
||||
pyenv_tests_docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: |
|
||||
make test-docker
|
||||
|
|
|
|||
43
.github/workflows/ubuntu_build.yml
vendored
Normal file
43
.github/workflows/ubuntu_build.yml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: ubuntu_build
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
ubuntu_build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
- "3.14"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- run: |
|
||||
sudo apt-get update -q; sudo apt install -yq make build-essential libssl-dev zlib1g-dev \
|
||||
libbz2-dev libreadline-dev libsqlite3-dev curl \
|
||||
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
|
||||
# https://github.com/pyenv/pyenv#installation
|
||||
- run: pwd
|
||||
- env:
|
||||
PYENV_ROOT: /home/runner/work/pyenv/pyenv
|
||||
run: |
|
||||
echo $PYENV_ROOT
|
||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||
bin/pyenv --debug install ${{ matrix.python-version }}
|
||||
bin/pyenv global ${{ matrix.python-version }}
|
||||
bin/pyenv rehash
|
||||
- run: python --version
|
||||
- run: python -m pip --version
|
||||
- shell: python # Prove that actual Python == expected Python
|
||||
env:
|
||||
EXPECTED_PYTHON: ${{ matrix.python-version }}
|
||||
run: import os, sys ; assert sys.version.startswith(os.getenv("EXPECTED_PYTHON"))
|
||||
19
CHANGELOG.md
19
CHANGELOG.md
|
|
@ -1,23 +1,5 @@
|
|||
# Version History
|
||||
|
||||
## Release v2.8.5
|
||||
* pyenv-binary: record direct system dependencies in Linux/FreeBSD by @macayu17 in https://github.com/pyenv/pyenv/pull/3520
|
||||
* tests: Fix "cd: null directory" in OpenSUSE by @native-api in https://github.com/pyenv/pyenv/pull/3524
|
||||
* Test improvements by @native-api in https://github.com/pyenv/pyenv/pull/3525
|
||||
* CI: test on all runners when the build logic changes by @sujeito-operator in https://github.com/pyenv/pyenv/pull/3522
|
||||
* Add GraalPy 25.3.4.1 by @msimacek in https://github.com/pyenv/pyenv/pull/3529
|
||||
* Add CPython 3.15.0rc2 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3530
|
||||
* pyenv-binary: support relocating macOS archives by @macayu17 in https://github.com/pyenv/pyenv/pull/3528
|
||||
|
||||
## Release v2.8.4
|
||||
* CI: Add macos_26_intel by @native-api in https://github.com/pyenv/pyenv/pull/3514
|
||||
* pyenv-binary: check FreeBSD system libraries by @macayu17 in https://github.com/pyenv/pyenv/pull/3511
|
||||
* version-file: Fix infinite loop for a relative path argument by @fudianchn in https://github.com/pyenv/pyenv/pull/3515
|
||||
* pyenv-binary: check patchelf early and add --verbose by @macayu17 in https://github.com/pyenv/pyenv/pull/3516
|
||||
* CI: add ubuntu ARM images by @native-api in https://github.com/pyenv/pyenv/pull/3517
|
||||
* Add CPython 3.10.21, 3.11.16, 3.12.14 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3518
|
||||
* Add anaconda3-2026.07-1, miniconda3 26.5.3-2 by @native-api in https://github.com/pyenv/pyenv/pull/3519
|
||||
|
||||
## Release v2.8.3
|
||||
* Add CPython 3.13.15, 3.14.7 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3512
|
||||
|
||||
|
|
@ -34,7 +16,6 @@
|
|||
* Add CPython 3.15.0b4 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3495
|
||||
|
||||
## Release v2.8.0
|
||||
* CVE-2026-68939: Fix handling of glob characters in .python-version
|
||||
* CI: add_version enhancements by @native-api in https://github.com/pyenv/pyenv/pull/3480
|
||||
* Add miniforge3-26.3.2-2, 26.3.2-3 by @native-api in https://github.com/pyenv/pyenv/pull/3481
|
||||
* rehash: fix race condition in landlock writability check by @Sheile in https://github.com/pyenv/pyenv/pull/3483
|
||||
|
|
|
|||
48
Makefile
48
Makefile
|
|
@ -10,14 +10,11 @@ TEST_PYTHON_BUILD_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuf
|
|||
TEST_BINARY_DOCKER_PREFIX = test-binary-docker
|
||||
TEST_BINARY_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BINARY_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BINARY_DOCKER_PREFIX)))
|
||||
|
||||
TEST_LINK_DOCKER_PREFIX = test-link-docker
|
||||
TEST_LINK_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_LINK_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_LINK_DOCKER_PREFIX)))
|
||||
|
||||
TEST_BATS_IMAGE_PREFIX = test-pyenv-docker-image
|
||||
TEST_BATS_IMAGE_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BATS_IMAGE_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BATS_IMAGE_PREFIX)))
|
||||
|
||||
.PHONY: test-docker
|
||||
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX) $(TEST_LINK_DOCKER_PREFIX)
|
||||
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX)
|
||||
|
||||
.PHONY: $(TEST_UNIT_DOCKER_PREFIX)
|
||||
$(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS)
|
||||
|
|
@ -65,8 +62,7 @@ $(TEST_PYTHON_BUILD_DOCKER_TARGETS): $(TEST_PYTHON_BUILD_DOCKER_PREFIX)-% : $(TE
|
|||
$${CI+-e CI="$${CI}"} \
|
||||
$(INTERACTIVE) \
|
||||
$(DOCKER_IMAGE):$(DOCKER_TAG) \
|
||||
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/python-build/test/$${BATS_FILE_FILTER}
|
||||
bats $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/python-build/test/$${BATS_FILE_FILTER}
|
||||
|
||||
.PHONY: $(TEST_BINARY_DOCKER_PREFIX)
|
||||
$(TEST_BINARY_DOCKER_PREFIX): $(TEST_BINARY_DOCKER_TARGETS)
|
||||
|
|
@ -88,31 +84,7 @@ $(TEST_BINARY_DOCKER_TARGETS): $(TEST_BINARY_DOCKER_PREFIX)-% : $(TEST_BATS_IMAG
|
|||
$${CI+-e CI="$${CI}"} \
|
||||
$(INTERACTIVE) \
|
||||
$(DOCKER_IMAGE):$(DOCKER_TAG) \
|
||||
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER}
|
||||
|
||||
.PHONY: $(TEST_LINK_DOCKER_PREFIX)
|
||||
$(TEST_LINK_DOCKER_PREFIX): $(TEST_LINK_DOCKER_TARGETS)
|
||||
|
||||
.PHONY: $(TEST_LINK_DOCKER_TARGETS)
|
||||
$(TEST_LINK_DOCKER_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
|
||||
$(TEST_LINK_DOCKER_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
|
||||
$(TEST_LINK_DOCKER_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
|
||||
$(TEST_LINK_DOCKER_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
|
||||
$(TEST_LINK_DOCKER_TARGETS): INTERACTIVE = $(if $(findstring true,$(CI)),,-ti)
|
||||
$(TEST_LINK_DOCKER_TARGETS): $(TEST_LINK_DOCKER_PREFIX)-% : $(TEST_BATS_IMAGE_PREFIX)-%
|
||||
$(info Running test with docker image '$(DOCKER_IMAGE):$(DOCKER_TAG)')
|
||||
docker run \
|
||||
--init \
|
||||
-v $(PWD):/code:ro \
|
||||
-v /etc/passwd:/etc/passwd:ro \
|
||||
-v /etc/group:/etc/group:ro \
|
||||
-u "$$(id -u $$(whoami)):$$(id -g $$(whoami))" \
|
||||
$${CI+-e CI="$${CI}"} \
|
||||
$(INTERACTIVE) \
|
||||
$(DOCKER_IMAGE):$(DOCKER_TAG) \
|
||||
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-link/test/$${BATS_FILE_FILTER}
|
||||
bats $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER}
|
||||
|
||||
# Build all images needed for bats under docker
|
||||
.PHONY: $(TEST_BATS_IMAGE_PREFIX)
|
||||
|
|
@ -136,28 +108,22 @@ $(TEST_BATS_IMAGE_TARGETS):
|
|||
./ ; \
|
||||
fi
|
||||
|
||||
.PHONY: test test-unit test-python-build test-binary test-link
|
||||
.PHONY: test test-unit test-python-build test-binary
|
||||
|
||||
# Do not pass in user flags to build tests.
|
||||
unexport PYTHON_CFLAGS
|
||||
unexport PYTHON_CONFIGURE_OPTS
|
||||
|
||||
test: test-unit test-python-build test-binary test-link
|
||||
test: test-unit test-python-build test-binary
|
||||
|
||||
test-unit: bats
|
||||
PATH="./bats/bin:$$PATH" test/run
|
||||
|
||||
test-python-build: bats
|
||||
cd plugins/python-build && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||
cd plugins/python-build && $(PWD)/bats/bin/bats $${CI:+--tap} $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||
|
||||
test-binary: bats
|
||||
cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||
|
||||
test-link: bats
|
||||
cd plugins/pyenv-link && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||
cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+--tap} $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||
|
||||
.SECONDARY: bats-$(TEST_BATS_VERSION)
|
||||
bats-$(TEST_BATS_VERSION):
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
|
|||
|
||||
* Lets you **change the global Python version** on a per-user basis.
|
||||
* Provides support for **per-project Python versions**.
|
||||
* Supports **multiple Python distributions**: CPython, PyPy, Stackless Python, Jython, and more.
|
||||
See the [full list of available versions](https://github.com/pyenv/pyenv/tree/master/plugins/python-build/share/python-build).
|
||||
* Allows you to **override the Python version** with an environment
|
||||
variable.
|
||||
* Searches for commands from **multiple versions of Python at a time**.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
version="2.8.5"
|
||||
version="2.8.3"
|
||||
git_revision=""
|
||||
|
||||
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then
|
||||
|
|
|
|||
|
|
@ -473,12 +473,12 @@ function pyenv {
|
|||
}
|
||||
|
||||
if ( ("${commands[*]}" -split ' ') -contains \$command ) {
|
||||
\$shell_cmds = (& (get-command -commandtype application pyenv -totalcount 1) sh-\$command \$args)
|
||||
\$shell_cmds = (& (get-command -commandtype application pyenv) sh-\$command \$args)
|
||||
if ( \$shell_cmds.Count -gt 0 ) {
|
||||
iex (\$shell_cmds -join "\`n")
|
||||
}
|
||||
} else {
|
||||
& (get-command -commandtype application pyenv -totalcount 1) \$command \$args
|
||||
& (get-command -commandtype application pyenv) \$command \$args
|
||||
}
|
||||
}
|
||||
EOS
|
||||
|
|
|
|||
|
|
@ -8,28 +8,12 @@ target_dir="$1"
|
|||
|
||||
find_local_version_file() {
|
||||
local root="$1"
|
||||
# Nonexistent paths are UB as of this writing.
|
||||
# Relative ones cause a failure but absolute ones don't
|
||||
[[ $root != /* ]] && root=$(CDPATH= cd -- "$root" && pwd)
|
||||
# Original Rbenv code supports UNC notation for Cygwin/MinGW
|
||||
# (https://github.com/rbenv/rbenv/pull/529)
|
||||
# POSIX.1-2024 still allows to treat //<name> in implementation-specific manner
|
||||
# (https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap04.html#tag_04_16)
|
||||
# even though few UNIX variants do that
|
||||
local unc; [[ $root =~ ^//[^/] && ! / -ef // ]] && unc=1
|
||||
root="${root%/}"
|
||||
# when testing root, $root is ""
|
||||
while true; do
|
||||
# don't test //.python-version if // is special
|
||||
# as it's pointless and possibly very slow
|
||||
# if it e.g. leads to a network search
|
||||
[[ $unc && $root == / ]] && break
|
||||
|
||||
if [[ -f $root/.python-version ]]; then
|
||||
echo "$root/.python-version"
|
||||
while ! [[ "$root" =~ ^//[^/]*$ ]]; do
|
||||
if [ -f "${root}/.python-version" ]; then
|
||||
echo "${root}/.python-version"
|
||||
return 0
|
||||
fi
|
||||
[[ -n $root ]] || break
|
||||
[ -n "$root" ] || break
|
||||
root="${root%/*}"
|
||||
done
|
||||
return 1
|
||||
|
|
@ -38,9 +22,7 @@ find_local_version_file() {
|
|||
if [ -n "$target_dir" ]; then
|
||||
find_local_version_file "$target_dir"
|
||||
else
|
||||
# In tests, PYENV_DIR is not set, ultimately leading to "cd: null directory" in OpenSUSE
|
||||
# While most `cd` implementations treat an empty argument the same as missing, that's still wrong
|
||||
find_local_version_file "${PYENV_DIR:=$PWD}" || {
|
||||
find_local_version_file "$PYENV_DIR" || {
|
||||
[ "$PYENV_DIR" != "$PWD" ] && find_local_version_file "$PWD"
|
||||
} || echo "${PYENV_ROOT}/version"
|
||||
fi
|
||||
|
|
|
|||
1
plugins/.gitignore
vendored
1
plugins/.gitignore
vendored
|
|
@ -3,5 +3,4 @@
|
|||
!/version-ext-compat
|
||||
!/python-build
|
||||
!/pyenv-binary
|
||||
!/pyenv-link
|
||||
/python-build/test/build
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ and dependency metadata exist to catch that.
|
|||
|
||||
## Commands
|
||||
|
||||
### `pyenv binary package [-v|--verbose] <version>[:<entry>] --archive-base-url <url>`
|
||||
### `pyenv binary package <version>[:<entry>] --archive-base-url <url>`
|
||||
|
||||
Installs `<version>` from source under a separate name, packages that install
|
||||
with `save`, then emits a python-build definition for it with
|
||||
|
|
@ -24,8 +24,6 @@ with `save`, then emits a python-build definition for it with
|
|||
current platform, platform version and architecture. An explicit entry keeps
|
||||
the existing custom-build workflow.
|
||||
|
||||
Pass `-v` to show build progress from `pyenv install`.
|
||||
|
||||
```sh
|
||||
pyenv binary package 3.12.7 \
|
||||
--archive-base-url https://example.com/binaries
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
# into the definition; `pyenv binary save' writes the two together.
|
||||
#
|
||||
# <metadata-file> A .meta file written by `pyenv binary save'.
|
||||
# The corresponding binary package written by `pyenv binary save'
|
||||
# The corresponsing binary package written by `pyenv binary save'
|
||||
# needs to be present alongside it.
|
||||
# --archive-url <url> The URL for the resulting installation script to download
|
||||
# the package from.
|
||||
|
|
@ -55,7 +55,7 @@ if [ -z "$metadata" ] || [ -z "$archive_url" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
version="" os="" arch="" distro="" libc="" build_prefix="" archive=""
|
||||
version="" os="" arch="" distro="" libc="" archive=""
|
||||
deps=""
|
||||
while IFS='=' read -r key value; do
|
||||
case "$key" in
|
||||
|
|
@ -64,7 +64,6 @@ while IFS='=' read -r key value; do
|
|||
arch ) arch="$value" ;;
|
||||
distro ) distro="$value" ;;
|
||||
libc ) libc="$value" ;;
|
||||
build_prefix ) build_prefix="$value" ;;
|
||||
archive ) archive="$value" ;;
|
||||
dep ) deps="${deps:+$deps }$value" ;;
|
||||
esac
|
||||
|
|
@ -79,9 +78,10 @@ for field in version os arch archive; do
|
|||
fi
|
||||
done
|
||||
|
||||
# Mach-O load commands contain the prefix where Python was built.
|
||||
if [ "$os" = "Darwin" ] && [ -z "$build_prefix" ]; then
|
||||
echo "pyenv-binary: metadata is missing \`build_prefix'" >&2
|
||||
# macOS relocation needs install_name_tool and a different rpath scheme, so it is
|
||||
# not supported yet. Other systems relocate with patchelf.
|
||||
if [ "$os" = "Darwin" ]; then
|
||||
echo "pyenv-binary: macOS archives are not supported yet" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
@ -122,7 +122,6 @@ emit() {
|
|||
printf 'EXPECT_OS=%q\n' "$os"
|
||||
printf 'EXPECT_ARCH=%q\n' "$arch"
|
||||
printf 'EXPECT_LIBC=%q\n' "$libc"
|
||||
printf 'BUILD_PREFIX=%q\n' "$build_prefix"
|
||||
printf 'VERSION=%q\n' "$version"
|
||||
printf 'ARCHIVE_URL=%q\n' "$archive_url"
|
||||
printf 'SHA256=%q\n' "$sha256"
|
||||
|
|
@ -156,23 +155,10 @@ case "$EXPECT_LIBC" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# Required system libraries must already be present on the target. Linux lists
|
||||
# the soname first; FreeBSD lists it in the resolved path, so normalize that
|
||||
# path before matching exact names.
|
||||
cache=""
|
||||
if command -v ldconfig &>/dev/null; then
|
||||
case "$os" in
|
||||
FreeBSD )
|
||||
cache="$(ldconfig -r 2>/dev/null)" &&
|
||||
cache="$(printf '%s\n' "$cache" | awk -F ' *=> *' '{ sub(/^.*\//, "", $2); print $2 }')" \
|
||||
|| cache=""
|
||||
;;
|
||||
* )
|
||||
cache="$(ldconfig -p 2>/dev/null)" || cache=""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ -n "$cache" ]; then
|
||||
# Required system libraries must already be present on the target. ldconfig -p
|
||||
# lists each library as "<soname> (...) => <path>"; match the soname column
|
||||
# exactly so a longer name like libc.so.6.1 does not satisfy libc.so.6.
|
||||
if command -v ldconfig &>/dev/null && cache="$(ldconfig -p)"; then
|
||||
missing=""
|
||||
for dep in $DEPS; do
|
||||
printf '%s\n' "$cache" | awk -v d="$dep" '$1 == d { found = 1 } END { exit !found }' \
|
||||
|
|
@ -183,32 +169,11 @@ if [ -n "$cache" ]; then
|
|||
exit 1
|
||||
fi
|
||||
elif [ -n "$DEPS" ]; then
|
||||
echo "pyenv-binary: cannot check required system libraries (ldconfig cache unavailable)" >&2
|
||||
echo "pyenv-binary: cannot check required system libraries (ldconfig with -p not found)" >&2
|
||||
fi
|
||||
|
||||
case "$os" in
|
||||
Darwin )
|
||||
for tool in otool install_name_tool; do
|
||||
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||
echo "pyenv-binary: need ${tool} to relocate the binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
;;
|
||||
* )
|
||||
if ! command -v patchelf >/dev/null 2>&1; then
|
||||
echo "pyenv-binary: need patchelf to relocate the binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
build_package_relocate() {
|
||||
if [ "$os" = "Darwin" ]; then
|
||||
pyenv binary relocate "$PREFIX_PATH" "$BUILD_PREFIX"
|
||||
else
|
||||
pyenv binary relocate "$PREFIX_PATH"
|
||||
fi
|
||||
pyenv binary relocate "$PREFIX_PATH"
|
||||
}
|
||||
|
||||
install_package "Python-${VERSION}-binary" "${ARCHIVE_URL}#${SHA256}" copy relocate
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# Summary: Create an installable binary package from a Python version
|
||||
#
|
||||
# Usage: pyenv binary package [-v|--verbose] <version>[:<entry>] --archive-base-url <url>
|
||||
# Usage: pyenv binary package <version>[:<entry>] --archive-base-url <url>
|
||||
#
|
||||
# Installs <version> from source under a separate entry name, saves it as a
|
||||
# binary package, then emits a python-build definition for that package.
|
||||
|
|
@ -13,7 +13,6 @@
|
|||
# <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.
|
||||
# -v,--verbose Show build progress from `pyenv install'.
|
||||
# --archive-base-url <url>
|
||||
# Where the archive will be hosted; the definition
|
||||
# downloads it from <url>/<entry>.tar.gz.
|
||||
|
|
@ -24,29 +23,23 @@ set -e
|
|||
# Provide pyenv completions
|
||||
if [ "$1" = "--complete" ]; then
|
||||
echo --archive-base-url
|
||||
echo --verbose
|
||||
exec pyenv-install --list --bare
|
||||
fi
|
||||
|
||||
spec=""
|
||||
archive_base_url=""
|
||||
verbose=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--archive-base-url )
|
||||
[ $# -lt 2 ] && { echo "pyenv-binary: --archive-base-url needs a value" >&2; exit 1; }
|
||||
archive_base_url="$2"; shift ;;
|
||||
-v|--verbose)
|
||||
verbose=1 ;;
|
||||
[ $# -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"
|
||||
;;
|
||||
spec="$1"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -z "$spec" ] || [ -z "$archive_base_url" ]; then
|
||||
|
|
@ -75,8 +68,17 @@ latest )
|
|||
;;
|
||||
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 `<version>:<alias>' build under versions/<alias>.
|
||||
pyenv-install ${verbose:+--verbose} "$spec"
|
||||
pyenv-install "$spec"
|
||||
pyenv-binary-save "$entry" "$PWD" --name "$entry"
|
||||
|
||||
pyenv-binary-generate-installer "${entry}.meta" \
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ case "$version" in
|
|||
;;
|
||||
esac
|
||||
|
||||
version="$(pyenv-latest -f -k "$version")"
|
||||
|
||||
os="$(uname -s)"
|
||||
arch="$(uname -m)"
|
||||
distro=""
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Rewrite an unpacked Python's library paths so it runs from its prefix
|
||||
# Summary: Rewrite an unpacked Python's rpaths so it runs from its prefix
|
||||
#
|
||||
# Usage: pyenv binary relocate <prefix> [<build-prefix>]
|
||||
# Usage: pyenv binary relocate <prefix>
|
||||
#
|
||||
# Rewrites the library paths of a Python tree that was unpacked into <prefix>
|
||||
# so the interpreter and its extension modules load the bundled libraries from
|
||||
# their new location rather than the path it was built at. Requires patchelf on
|
||||
# Linux and FreeBSD, or otool and install_name_tool on macOS.
|
||||
# Rewrites the rpaths of a Python tree that was unpacked into <prefix> so the
|
||||
# interpreter and its extension modules load the bundled libraries from their
|
||||
# new location rather than the path it was built at. Requires patchelf.
|
||||
#
|
||||
# The definition that `pyenv binary generate-installer' produces calls this
|
||||
# after `install_package ... copy' has laid the tree down.
|
||||
|
|
@ -25,84 +24,6 @@ if [ -z "$prefix" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
build_prefix="${2%/}"
|
||||
if [ -z "$build_prefix" ]; then
|
||||
echo "pyenv-binary: need the original build prefix to relocate a macOS binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
for tool in otool install_name_tool; do
|
||||
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||
echo "pyenv-binary: need ${tool} to relocate the binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
relocate_macho() {
|
||||
local file="$1" new_rpath="$2"
|
||||
local load_commands install_ids rpaths dependency install_id rpath replacement
|
||||
|
||||
load_commands="$(otool -L "$file")"
|
||||
install_ids="$(otool -D "$file" 2>/dev/null || true)"
|
||||
rpaths="$(otool -l "$file")"
|
||||
install_id="$(printf '%s\n' "$install_ids" | sed -n '2s/^[[:space:]]*//p')"
|
||||
|
||||
while IFS= read -r dependency; do
|
||||
case "$dependency" in
|
||||
"$build_prefix"/lib/* )
|
||||
if [ "$dependency" != "$install_id" ]; then
|
||||
replacement="@rpath/${dependency#"$build_prefix"/lib/}"
|
||||
install_name_tool -change "$dependency" "$replacement" "$file"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done < <(printf '%s\n' "$load_commands" | tail -n +2 | sed -E \
|
||||
's/^[[:space:]]*//; s/[[:space:]]+\(compatibility version.*$//')
|
||||
|
||||
case "$install_id" in
|
||||
"$build_prefix"/lib/* )
|
||||
replacement="@rpath/${install_id#"$build_prefix"/lib/}"
|
||||
install_name_tool -id "$replacement" "$file"
|
||||
;;
|
||||
esac
|
||||
|
||||
while IFS= read -r rpath; do
|
||||
if [ "$rpath" = "$build_prefix/lib" ]; then
|
||||
install_name_tool -rpath "$rpath" "$new_rpath" "$file"
|
||||
fi
|
||||
done < <(printf '%s\n' "$rpaths" | awk '
|
||||
/cmd LC_RPATH/ { found = 1; next }
|
||||
found && /^[[:space:]]*path / {
|
||||
sub(/^[[:space:]]*path /, "")
|
||||
sub(/ \(offset [0-9]+\)$/, "")
|
||||
print
|
||||
found = 0
|
||||
}
|
||||
')
|
||||
}
|
||||
|
||||
found=0
|
||||
for file in "$prefix"/bin/*; do
|
||||
[[ -f $file && -x $file && ! -L $file ]] || continue
|
||||
otool -L "$file" >/dev/null 2>&1 || continue
|
||||
relocate_macho "$file" '@executable_path/../lib'
|
||||
found=1
|
||||
done
|
||||
if [ "$found" -eq 0 ]; then
|
||||
echo "pyenv-binary: found no interpreter to relocate under \`${prefix}/bin'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in "$prefix"/lib/*.dylib; do
|
||||
[[ -f $file && ! -L $file ]] || continue
|
||||
relocate_macho "$file" '@loader_path'
|
||||
done
|
||||
while IFS= read -r so; do
|
||||
relocate_macho "$so" '@loader_path/../..'
|
||||
done < <(find "$prefix" -type f -path '*/lib/python*/lib-dynload/*.so')
|
||||
exit
|
||||
fi
|
||||
|
||||
# patchelf can add an rpath and write one of any length; chrpath can only shorten
|
||||
# an existing one, which is not enough to relocate every build, so require it.
|
||||
if ! command -v patchelf >/dev/null 2>&1; then
|
||||
|
|
|
|||
|
|
@ -92,16 +92,12 @@ fi
|
|||
if [ "$os" = "Linux" ]; then
|
||||
libc="$(getconf GNU_LIBC_VERSION 2>/dev/null || true)"
|
||||
fi
|
||||
if [ "$os" != "Darwin" ] && ! LC_ALL=C readelf --version &>/dev/null; then
|
||||
echo "pyenv-binary: need readelf to inspect shared libraries" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# List the external shared libraries the install links against: those that
|
||||
# resolve outside its own prefix, so they must already exist on the target.
|
||||
# The interpreter plus every bundled shared object are inspected.
|
||||
system_deps() {
|
||||
local f needed
|
||||
local f
|
||||
{
|
||||
for f in "${prefix}"/bin/python*; do
|
||||
[ -e "$f" ] && printf '%s\n' "$f"
|
||||
|
|
@ -115,19 +111,8 @@ system_deps() {
|
|||
otool -L "$f" 2>/dev/null | tail -n +2 | awk -v pfx="${prefix}/" \
|
||||
'$1 !~ /^@/ && substr($1, 1, length(pfx)) != pfx { print $1 }'
|
||||
else
|
||||
# GNU binutils 2.44 writes "(NEEDED) ... [name]"; FreeBSD 15.1 writes
|
||||
# "NEEDED ... [name]". readelf(1) documents -d, not its text format.
|
||||
needed="$(LC_ALL=C readelf -dW "$f" 2>/dev/null | awk \
|
||||
'$2 == "(NEEDED)" || $2 == "NEEDED" { sub(/^.*\[/, ""); sub(/\].*$/, ""); print }' | tr '\n' ' ')"
|
||||
# Linux and FreeBSD ldd write resolved libraries as
|
||||
# "name => /absolute/path (address)"; entries without "=>" are ignored.
|
||||
LC_ALL=C ldd "$f" 2>/dev/null | awk -v needed="$needed" -v pfx="${prefix}/" '
|
||||
BEGIN {
|
||||
split(needed, deps, " ")
|
||||
for (i in deps) direct[deps[i]] = 1
|
||||
}
|
||||
$1 in direct && $2 == "=>" && $3 ~ /^\// && substr($3, 1, length(pfx)) != pfx { print $1 }
|
||||
'
|
||||
ldd "$f" 2>/dev/null | awk -v pfx="${prefix}/" \
|
||||
'$2 == "=>" && $3 ~ /^\// && substr($3, 1, length(pfx)) != pfx { print $1 }'
|
||||
fi
|
||||
done | sort -u
|
||||
}
|
||||
|
|
@ -147,7 +132,6 @@ tar -C "$(dirname "$prefix")" -czf "${output_dir}/${archive}" "$(basename "$pref
|
|||
echo "platform=${platform}"
|
||||
[ -n "$distro" ] && echo "distro=${distro}"
|
||||
[ -n "$libc" ] && echo "libc=${libc}"
|
||||
echo "build_prefix=${prefix}"
|
||||
echo "archive=${archive}"
|
||||
system_deps | while IFS= read -r dep; do
|
||||
[ -n "$dep" ] && echo "dep=${dep}"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ create_meta() {
|
|||
local os="${1-Linux}"
|
||||
local arch="${2-x86_64}"
|
||||
local libc="${3-glibc 2.17}"
|
||||
local build_prefix="${4-}"
|
||||
local archive="${BATS_TEST_TMPDIR}/3.12.7.tar.gz"
|
||||
local meta="${BATS_TEST_TMPDIR}/sample.meta"
|
||||
|
||||
|
|
@ -21,7 +20,6 @@ create_meta() {
|
|||
echo "os=${os}"
|
||||
echo "arch=${arch}"
|
||||
[ -z "$libc" ] || echo "libc=${libc}"
|
||||
[ -z "$build_prefix" ] || echo "build_prefix=${build_prefix}"
|
||||
echo "archive=${archive##*/}"
|
||||
} > "$meta"
|
||||
echo "$meta"
|
||||
|
|
@ -60,20 +58,10 @@ create_meta() {
|
|||
assert_failure
|
||||
}
|
||||
|
||||
@test "fails when macOS metadata is missing the build prefix" {
|
||||
@test "refuses macOS metadata" {
|
||||
run pyenv-binary-generate-installer "$(create_meta Darwin arm64 '')" \
|
||||
--archive-url http://x/a.tar.gz
|
||||
assert_failure "pyenv-binary: metadata is missing \`build_prefix'"
|
||||
}
|
||||
|
||||
@test "quotes the macOS build prefix in the generated definition" {
|
||||
local out="${BATS_TEST_TMPDIR}/definition"
|
||||
pyenv-binary-generate-installer \
|
||||
"$(create_meta Darwin arm64 '' '/build prefix/$name')" \
|
||||
--archive-url http://example.com/a.tar.gz -o "$out"
|
||||
|
||||
run grep '^BUILD_PREFIX=' "$out"
|
||||
assert_success 'BUILD_PREFIX=/build\ prefix/\$name'
|
||||
assert_failure "pyenv-binary: macOS archives are not supported yet"
|
||||
}
|
||||
|
||||
@test "fails when required metadata is missing" {
|
||||
|
|
@ -105,82 +93,6 @@ create_meta() {
|
|||
assert_failure "pyenv-binary: archive needs glibc 99.0 or newer, but this system has 2.31"
|
||||
}
|
||||
|
||||
@test "checks required libraries in the FreeBSD ldconfig cache" {
|
||||
local out="${BATS_TEST_TMPDIR}/definition"
|
||||
local meta="$(create_meta FreeBSD amd64 '')"
|
||||
printf 'dep=libc.so.7\ndep=libmissing.so.1\n' >> "$meta"
|
||||
pyenv-binary-generate-installer "$meta" \
|
||||
--archive-url http://example.com/a.tar.gz -o "$out"
|
||||
create_stub uname 'case "$1" in -s) echo FreeBSD;; -m) echo amd64;; esac'
|
||||
create_stub ldconfig '[ "$1" = "-r" ] && echo "0:-lc.7=>/lib/libc.so.7"'
|
||||
|
||||
run bash "$out"
|
||||
assert_failure "pyenv-binary: missing required system libraries: libmissing.so.1"
|
||||
}
|
||||
|
||||
@test "checks for patchelf before installing the archive" {
|
||||
local out="${BATS_TEST_TMPDIR}/definition"
|
||||
pyenv-binary-generate-installer "$(create_meta)" \
|
||||
--archive-url http://example.com/a.tar.gz -o "$out"
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
create_stub getconf 'echo "glibc 2.31"'
|
||||
|
||||
PATH="$(path_without patchelf)" run bash "$out"
|
||||
assert_failure "pyenv-binary: need patchelf to relocate the binary"
|
||||
}
|
||||
|
||||
@test "checks for otool before installing a macOS archive" {
|
||||
local out="${BATS_TEST_TMPDIR}/definition"
|
||||
pyenv-binary-generate-installer \
|
||||
"$(create_meta Darwin arm64 '' /build/3.12.7)" \
|
||||
--archive-url http://example.com/a.tar.gz -o "$out"
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_path_executable install_name_tool true
|
||||
|
||||
PATH="$(path_without otool)" run bash "$out"
|
||||
assert_failure "pyenv-binary: need otool to relocate the binary"
|
||||
}
|
||||
|
||||
@test "checks for install_name_tool before installing a macOS archive" {
|
||||
local out="${BATS_TEST_TMPDIR}/definition"
|
||||
pyenv-binary-generate-installer \
|
||||
"$(create_meta Darwin arm64 '' /build/3.12.7)" \
|
||||
--archive-url http://example.com/a.tar.gz -o "$out"
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_path_executable otool true
|
||||
|
||||
PATH="$(path_without install_name_tool)" run bash "$out"
|
||||
assert_failure "pyenv-binary: need install_name_tool to relocate the binary"
|
||||
}
|
||||
|
||||
@test "the generated macOS definition preserves both relocation arguments" {
|
||||
local archive="${BATS_TEST_TMPDIR}/3.12.7.tar.gz"
|
||||
local cache="${BATS_TEST_TMPDIR}/cache"
|
||||
local definition="${BATS_TEST_TMPDIR}/definition"
|
||||
local prefix="${BATS_TEST_TMPDIR}/install"
|
||||
pyenv-binary-generate-installer \
|
||||
"$(create_meta Darwin arm64 '' '/build prefix/$name')" \
|
||||
--archive-url http://example.com/3.12.7.tar.gz -o "$definition"
|
||||
mkdir -p "$cache"
|
||||
cp "$archive" "${cache}/Python-3.12.7-binary.tar.gz"
|
||||
create_stub pyenv 'printf "argc=%s\narg1=%s\narg2=%s\narg3=%s\narg4=%s\n" "$#" "$1" "$2" "$3" "$4"'
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_stub sw_vers 'echo 15.5'
|
||||
create_stub ldconfig true
|
||||
create_path_executable otool true
|
||||
create_path_executable install_name_tool true
|
||||
|
||||
PYTHON_BUILD_CACHE_PATH="$cache" run \
|
||||
"${BATS_TEST_DIRNAME}/../../python-build/bin/python-build" "$definition" "$prefix"
|
||||
assert_success
|
||||
assert_line "argc=4"
|
||||
assert_line "arg1=binary"
|
||||
assert_line "arg2=relocate"
|
||||
assert_line "arg3=${prefix}"
|
||||
assert_line 'arg4=/build prefix/$name'
|
||||
assert_line "Installed Python-3.12.7-binary to ${prefix}"
|
||||
}
|
||||
|
||||
@test "fails when the archive is not beside the metadata" {
|
||||
local meta="$(create_meta)"
|
||||
rm "${BATS_TEST_TMPDIR}/3.12.7.tar.gz"
|
||||
|
|
@ -200,7 +112,6 @@ create_meta() {
|
|||
mkdir -p "$cache"
|
||||
cp "$archive" "${cache}/Python-3.12.7-binary.tar.gz"
|
||||
create_stub pyenv 'echo "pyenv $*"'
|
||||
create_path_executable patchelf "exit 0"
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
|
||||
PYTHON_BUILD_CACHE_PATH="$cache" run \
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
create_stub pyenv-latest '[ "$1" = "-f" ] && [ "$2" = "-k" ] && shift 2 && echo "$*"'
|
||||
}
|
||||
|
||||
@test "completion lists installable versions" {
|
||||
create_stub pyenv-install \
|
||||
'[ "$*" = "--list --bare" ] && echo 3.13.14'
|
||||
|
|
@ -44,13 +40,12 @@ _setup() {
|
|||
assert_success "3.13.14-macos-15.5-arm64"
|
||||
}
|
||||
|
||||
@test "resolves a version prefix when generating a package name" {
|
||||
create_stub pyenv-latest '[ "$*" = "-f -k 3" ] && echo 3.14.7'
|
||||
@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
|
||||
assert_success "3.14.7-freebsd-14.2-release-p3-amd64"
|
||||
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" {
|
||||
|
|
|
|||
|
|
@ -6,34 +6,21 @@ load test_helper
|
|||
# the platform tools report a fixed Linux target so the real `save' and
|
||||
# `generate-installer' behave the same on any test host.
|
||||
stub_build_environment() {
|
||||
create_stub pyenv-install 'echo "${0##*/} $*"; mkdir -p "${PYENV_ROOT}/versions/${1##*:}/bin"'
|
||||
create_stub pyenv-latest 'while (($#)); do case "$1" in -f|-k);; *)break;; esac; shift; done; echo "$*"'
|
||||
create_stub pyenv-install 'mkdir -p "${PYENV_ROOT}/versions/${1##*:}/bin"'
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
create_stub getconf 'echo "glibc 2.17"'
|
||||
create_stub readelf true
|
||||
}
|
||||
|
||||
@test "-v|--verbose runs pyenv install verbosely" {
|
||||
stub_build_environment
|
||||
create_stub pyenv-binary-save true
|
||||
create_stub pyenv-binary-generate-installer true
|
||||
|
||||
for opt in "" -v --verbose; do
|
||||
run pyenv-binary-package $opt 3.12.7:3.12.7-test \
|
||||
--archive-base-url http://example.com/binaries
|
||||
assert_success "pyenv-install ${opt:+--verbose }3.12.7:3.12.7-test"
|
||||
done
|
||||
}
|
||||
|
||||
@test "completions" {
|
||||
create_stub pyenv-install 'echo "${0##*/} $*"'
|
||||
@test "completion lists the option and definitions provided by another plugin" {
|
||||
mkdir -p "${PYENV_ROOT}/plugins/example/share/python-build"
|
||||
touch "${PYENV_ROOT}/plugins/example/share/python-build/3.12.7-example"
|
||||
PATH="${BATS_TEST_DIRNAME}/../../python-build/bin:${PATH}"
|
||||
|
||||
run pyenv-binary-package --complete
|
||||
assert_success <<!
|
||||
--archive-base-url
|
||||
--verbose
|
||||
pyenv-install --list --bare
|
||||
!
|
||||
assert_success
|
||||
assert_line "--archive-base-url"
|
||||
assert_line "3.12.7-example"
|
||||
refute_line "Available versions:"
|
||||
}
|
||||
|
||||
@test "fails with no arguments" {
|
||||
|
|
@ -82,19 +69,13 @@ pyenv-install --list --bare
|
|||
assert_failure "pyenv-binary: \`latest' cannot be used as an entry name"
|
||||
}
|
||||
|
||||
@test "packages on macOS" {
|
||||
@test "refuses to package on macOS before compiling anything" {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_stub pyenv-install 'echo install'
|
||||
create_stub pyenv-binary-save 'echo save'
|
||||
create_stub pyenv-binary-generate-installer 'echo generate-installer'
|
||||
|
||||
run pyenv-binary-package 3.12.7:3.12.7-test --archive-base-url http://x/b
|
||||
assert_success "install
|
||||
save
|
||||
generate-installer"
|
||||
assert_failure "pyenv-binary: macOS archives are not supported yet"
|
||||
}
|
||||
|
||||
@test "writes the archive, metadata and definition under the entry name (integration)" {
|
||||
@test "writes the archive, metadata and definition under the entry name" {
|
||||
stub_build_environment
|
||||
cd "${BATS_TEST_TMPDIR}"
|
||||
|
||||
|
|
@ -108,24 +89,13 @@ generate-installer"
|
|||
assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-test.tar.gz"
|
||||
}
|
||||
|
||||
@test "correctly joins archive base url with a trailing slash" {
|
||||
@test "strips a trailing slash from the archive base url" {
|
||||
stub_build_environment
|
||||
create_stub pyenv-binary-save true
|
||||
create_stub pyenv-binary-generate-installer <<'!'
|
||||
echo -n "${0##*/} "
|
||||
while (($#)); do
|
||||
case $1 in
|
||||
--archive-url)
|
||||
echo "$1 ${2:?}"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
!
|
||||
cd "${BATS_TEST_TMPDIR}"
|
||||
|
||||
run pyenv-binary-package 3.12.7:3.12.7-test \
|
||||
--archive-base-url http://example.com/binaries/
|
||||
assert_success
|
||||
assert_line "pyenv-binary-generate-installer --archive-url http://example.com/binaries/3.12.7-test.tar.gz"
|
||||
run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-test"
|
||||
assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-test.tar.gz"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ load test_helper
|
|||
|
||||
_setup() {
|
||||
create_stub pyenv-help "echo usage"
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
}
|
||||
|
||||
stub_patchelf() {
|
||||
|
|
@ -22,87 +21,6 @@ create_interpreter() {
|
|||
chmod +x "${BATS_TEST_TMPDIR}/prefix/bin/python2.7"
|
||||
}
|
||||
|
||||
create_macos_tree() {
|
||||
local prefix="${BATS_TEST_TMPDIR}/prefix"
|
||||
local lib="${prefix}/lib/python3.12"
|
||||
mkdir -p "${prefix}/bin" "${lib}/lib-dynload" "${lib}/site-packages/numpy"
|
||||
printf '#!/bin/sh\n' > "${prefix}/bin/python3.12"
|
||||
chmod +x "${prefix}/bin/python3.12"
|
||||
touch "${prefix}/lib/libpython3.12.dylib"
|
||||
touch "${lib}/lib-dynload/_ssl.cpython-312-darwin.so"
|
||||
touch "${lib}/site-packages/numpy/_multiarray.so"
|
||||
}
|
||||
|
||||
stub_macos_tools() {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_path_executable install_name_tool \
|
||||
'echo "$*" >> "${BATS_TEST_TMPDIR}/install-name-tool.log"'
|
||||
create_path_executable otool <<'STUB'
|
||||
file="${!#}"
|
||||
echo "$*" >> "${BATS_TEST_TMPDIR}/otool.log"
|
||||
old="/build prefix/3.12.7"
|
||||
case "$1" in
|
||||
-L )
|
||||
echo "${file}:"
|
||||
case "$file" in
|
||||
*/bin/python3.12 )
|
||||
if [ -n "$OTOOL_RELOCATED" ]; then
|
||||
echo " @rpath/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)"
|
||||
else
|
||||
echo " ${old}/lib/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)"
|
||||
fi
|
||||
echo " ${old}-other/lib/libother.dylib (compatibility version 1.0.0, current version 1.0.0)"
|
||||
echo " /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1.0.0)"
|
||||
echo " /opt/homebrew/lib/libintl.8.dylib (compatibility version 1.0.0, current version 1.0.0)"
|
||||
echo " @loader_path/liblocal.dylib (compatibility version 1.0.0, current version 1.0.0)"
|
||||
;;
|
||||
*/lib/libpython3.12.dylib )
|
||||
if [ -n "$OTOOL_RELOCATED" ]; then
|
||||
echo " @rpath/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)"
|
||||
else
|
||||
echo " ${old}/lib/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-D )
|
||||
case "$file" in
|
||||
*/lib/libpython3.12.dylib )
|
||||
echo "${file}:"
|
||||
if [ -n "$OTOOL_RELOCATED" ]; then
|
||||
echo '@rpath/libpython3.12.dylib'
|
||||
else
|
||||
echo "${old}/lib/libpython3.12.dylib"
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-l )
|
||||
if [ -n "$OTOOL_RELOCATED" ]; then
|
||||
case "$file" in
|
||||
*/bin/* ) rpath='@executable_path/../lib' ;;
|
||||
*/lib/*.dylib ) rpath='@loader_path' ;;
|
||||
* ) rpath='@loader_path/../..' ;;
|
||||
esac
|
||||
else
|
||||
rpath="${old}/lib"
|
||||
fi
|
||||
cat <<EOF
|
||||
cmd LC_RPATH
|
||||
path ${rpath} (offset 12)
|
||||
cmd LC_RPATH
|
||||
path /opt/homebrew/lib (offset 12)
|
||||
cmd LC_RPATH
|
||||
path @loader_path/vendor (offset 12)
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
STUB
|
||||
}
|
||||
|
||||
@test "completion produces nothing" {
|
||||
run pyenv-binary-relocate --complete
|
||||
assert_success ""
|
||||
|
|
@ -118,31 +36,6 @@ STUB
|
|||
assert_failure "pyenv-binary: need patchelf to relocate the binary"
|
||||
}
|
||||
|
||||
@test "fails without the original build prefix on macOS" {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
|
||||
run pyenv-binary-relocate "${BATS_TEST_TMPDIR}/prefix"
|
||||
assert_failure "pyenv-binary: need the original build prefix to relocate a macOS binary"
|
||||
}
|
||||
|
||||
@test "fails when otool is not available on macOS" {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_path_executable install_name_tool true
|
||||
|
||||
PATH="$(path_without otool)" run \
|
||||
pyenv-binary-relocate "${BATS_TEST_TMPDIR}/prefix" /build/3.12.7
|
||||
assert_failure "pyenv-binary: need otool to relocate the binary"
|
||||
}
|
||||
|
||||
@test "fails when install_name_tool is not available on macOS" {
|
||||
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
|
||||
create_path_executable otool true
|
||||
|
||||
PATH="$(path_without install_name_tool)" run \
|
||||
pyenv-binary-relocate "${BATS_TEST_TMPDIR}/prefix" /build/3.12.7
|
||||
assert_failure "pyenv-binary: need install_name_tool to relocate the binary"
|
||||
}
|
||||
|
||||
@test "fails when the prefix has no interpreter" {
|
||||
create_path_executable patchelf "exit 0"
|
||||
mkdir -p "${BATS_TEST_TMPDIR}/prefix"
|
||||
|
|
@ -177,45 +70,3 @@ STUB
|
|||
assert_line "--set-rpath ${BATS_TEST_TMPDIR}/prefix/lib ${lib}/lib-dynload/_ssl.cpython-312-x86_64-linux-gnu.so"
|
||||
refute_line "--set-rpath ${BATS_TEST_TMPDIR}/prefix/lib ${lib}/site-packages/numpy/_multiarray.so"
|
||||
}
|
||||
|
||||
@test "relocates macOS load commands without changing unrelated entries" {
|
||||
local prefix="${BATS_TEST_TMPDIR}/prefix"
|
||||
local old="/build prefix/3.12.7"
|
||||
local lib="${prefix}/lib/python3.12"
|
||||
create_macos_tree
|
||||
stub_macos_tools
|
||||
|
||||
run pyenv-binary-relocate "$prefix" "$old"
|
||||
assert_success
|
||||
run cat "${BATS_TEST_TMPDIR}/install-name-tool.log"
|
||||
assert_output <<EOF
|
||||
-change ${old}/lib/libpython3.12.dylib @rpath/libpython3.12.dylib ${prefix}/bin/python3.12
|
||||
-rpath ${old}/lib @executable_path/../lib ${prefix}/bin/python3.12
|
||||
-id @rpath/libpython3.12.dylib ${prefix}/lib/libpython3.12.dylib
|
||||
-rpath ${old}/lib @loader_path ${prefix}/lib/libpython3.12.dylib
|
||||
-rpath ${old}/lib @loader_path/../.. ${lib}/lib-dynload/_ssl.cpython-312-darwin.so
|
||||
EOF
|
||||
run grep -F "${lib}/site-packages/numpy/_multiarray.so" "${BATS_TEST_TMPDIR}/otool.log"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "skips already relocated macOS load commands" {
|
||||
local prefix="${BATS_TEST_TMPDIR}/prefix"
|
||||
create_macos_tree
|
||||
stub_macos_tools
|
||||
export OTOOL_RELOCATED=1
|
||||
|
||||
run pyenv-binary-relocate "$prefix" "/build prefix/3.12.7"
|
||||
assert_success
|
||||
assert [ ! -e "${BATS_TEST_TMPDIR}/install-name-tool.log" ]
|
||||
}
|
||||
|
||||
@test "fails when install_name_tool cannot modify a selected file" {
|
||||
local prefix="${BATS_TEST_TMPDIR}/prefix"
|
||||
create_macos_tree
|
||||
stub_macos_tools
|
||||
create_path_executable install_name_tool 'exit 1'
|
||||
|
||||
run pyenv-binary-relocate "$prefix" "/build prefix/3.12.7"
|
||||
assert_failure ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,25 +79,7 @@ platform() {
|
|||
assert_line "archive=3.12.7-$(platform).tar.gz"
|
||||
}
|
||||
|
||||
@test "records the original installation prefix" {
|
||||
create_version "3.12.7"
|
||||
local out="${BATS_TEST_TMPDIR}/dist"
|
||||
pyenv-binary-save "3.12.7" "$out" >/dev/null
|
||||
|
||||
run grep '^build_prefix=' "${out}/3.12.7-$(platform).meta"
|
||||
assert_success "build_prefix=${PYENV_ROOT}/versions/3.12.7"
|
||||
}
|
||||
|
||||
@test "fails when readelf is not available" {
|
||||
create_version "3.12.7"
|
||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||
|
||||
PATH="$(path_without readelf)" run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
|
||||
assert_failure "pyenv-binary: need readelf to inspect shared libraries"
|
||||
assert [ ! -e "${BATS_TEST_TMPDIR}/dist/3.12.7-$(platform).tar.gz" ]
|
||||
}
|
||||
|
||||
@test "records only direct libraries resolved outside the prefix" {
|
||||
@test "records only the libraries ldd resolves outside the prefix" {
|
||||
create_version "3.12.7"
|
||||
touch "${PYENV_ROOT}/versions/3.12.7/bin/python3.12"
|
||||
create_path_executable uname <<'STUB'
|
||||
|
|
@ -115,18 +97,13 @@ cat <<EOF
|
|||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a3b800000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007f4a3c200000)
|
||||
EOF
|
||||
STUB
|
||||
create_path_executable readelf <<'STUB'
|
||||
cat <<EOF
|
||||
0x0000000000000001 (NEEDED) Shared library: [libpython3.12.so.1.0]
|
||||
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
|
||||
EOF
|
||||
STUB
|
||||
|
||||
run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
|
||||
assert_success
|
||||
run grep '^dep=' "${BATS_TEST_TMPDIR}/dist/"*.meta
|
||||
assert_output "dep=libm.so.6"
|
||||
assert_output "dep=libc.so.6
|
||||
dep=libm.so.6"
|
||||
}
|
||||
|
||||
@test "records only the libraries otool resolves outside the prefix" {
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 yfprojects
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
# pyenv-link
|
||||
A [pyenv](https://github.com/pyenv/pyenv) plugin for linking Python installations and virtual environments into your pyenv root.
|
||||
|
||||
This plugin recommends the [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv/) plugin.
|
||||
|
||||
## Usage
|
||||
|
||||
Make an arbitrary virtualenv available through pyenv. This automatically guesses a fitting name from the prompt, the directory name or the location of the venv.
|
||||
|
||||
```console
|
||||
$ pyenv link version .venv
|
||||
Linked new version named myproject
|
||||
```
|
||||
|
||||
You can also specify a name to use for the venv.
|
||||
|
||||
```console
|
||||
$ pyenv link version .venv myname
|
||||
Linked new version named myname
|
||||
```
|
||||
|
||||
The same command can give a platform-specific binary installation a shorter name:
|
||||
|
||||
```console
|
||||
$ pyenv link version "$(pyenv root)/versions/3.13.14-linux-x86_64" 3.13.14
|
||||
Linked new version named 3.13.14
|
||||
```
|
||||
|
||||
Now you can make pyenv activate/use the venv automatically:
|
||||
|
||||
```console
|
||||
$ pyenv local myproject
|
||||
```
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Link a Python environment as a pyenv version
|
||||
#
|
||||
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
|
||||
#
|
||||
# Link a virtual python environment to pyenvs version directory
|
||||
# so that the venv can be used like one created with *pyenv-virtualenv*.
|
||||
#
|
||||
# <path> should be a path to a Python installation or virtual environment.
|
||||
|
||||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
# Provide pyenv completions
|
||||
case "$1" in
|
||||
--complete)
|
||||
if [ -z "$2" ]; then
|
||||
echo version
|
||||
else
|
||||
shift 2
|
||||
pyenv-link-version --complete "$@"
|
||||
fi
|
||||
;;
|
||||
version)
|
||||
shift
|
||||
pyenv-link-version "$@"
|
||||
exit $?
|
||||
;;
|
||||
*)
|
||||
pyenv-help --usage link >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Link a Python environment as a pyenv version
|
||||
#
|
||||
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
|
||||
#
|
||||
# Link a virtual python environment to pyenvs version directory
|
||||
# so that the venv can be used like one created with *pyenv-virtualenv*.
|
||||
#
|
||||
# <path> should be a path to a Python installation or virtual environment.
|
||||
# <name> should be string used as a version name it may not be present
|
||||
# in the pyenv version directory yet.
|
||||
# If not specified a matching name is guessed from pyvenv.cfg
|
||||
# or directory name of the venv.
|
||||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
# functions
|
||||
|
||||
if ! {
|
||||
enable -f "${BASH_SOURCE%/*}"/../../../libexec/pyenv-realpath.dylib realpath ||
|
||||
type realpath # realpath available?
|
||||
} >/dev/null 2>&1; then
|
||||
# realpath requires GNU coreutils to be installed. That's why its bundled with pyenv
|
||||
echo realpath not available >&2
|
||||
|
||||
# work-around when realpath is unavailable
|
||||
realpath() {
|
||||
(cd "$1" && pwd)
|
||||
}
|
||||
fi
|
||||
|
||||
guess_name() {
|
||||
local venv_dir=$1
|
||||
local name
|
||||
|
||||
# guess venv name from pyvenv.cfg
|
||||
local pyvenv_cfg_path=$venv_dir/pyvenv.cfg
|
||||
if [ -f "$pyvenv_cfg_path" ]; then
|
||||
# if `prompt` key wasn't found the var remains empty
|
||||
name=$(cut -b 1-1024 "$pyvenv_cfg_path" | sed -n '/^ *prompt *= */s///p')
|
||||
case "$name" in
|
||||
\"*\" | \'*\')
|
||||
name=${name:1:${#name}-2}
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# guess venv name from name of venv directory
|
||||
local venv_dir_name=${venv_dir##*/}
|
||||
if [ -z "$name" ]; then
|
||||
case "$venv_dir_name" in
|
||||
venv | env | .venv | .env | ENV | VENV) ;;
|
||||
*) name=$venv_dir_name ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# guess venv name from name of the parent directory of the venv directory
|
||||
local venv_dir_parent=${venv_dir%/*}
|
||||
local venv_dir_parent_name=${venv_dir_parent##*/}
|
||||
if [ -z "$name" ]; then
|
||||
name=$venv_dir_parent_name
|
||||
fi
|
||||
|
||||
echo "$name"
|
||||
}
|
||||
|
||||
# process args
|
||||
POSARGS=()
|
||||
# Provide pyenv completions
|
||||
if [ "$1" = "--complete" ]; then
|
||||
echo --dry
|
||||
echo --quiet
|
||||
exit
|
||||
fi
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--dry)
|
||||
dry=true # any value
|
||||
;;
|
||||
--quiet)
|
||||
quiet=true # any value
|
||||
;;
|
||||
-*)
|
||||
pyenv-help --usage link-version >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
POSARGS+=("$arg")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! ${#POSARGS[@]} -le 2 ] || [ ! ${#POSARGS[@]} -ge 1 ]; then
|
||||
pyenv-help --usage link-version >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
venv_dir=${POSARGS[0]%/}
|
||||
venv_name=${POSARGS[1]}
|
||||
|
||||
# Check venv exists
|
||||
if [ ! -d "$venv_dir" ]; then
|
||||
echo "The virtual env you specified doesn't exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# make venv dir absolute
|
||||
venv_dir=$(realpath "$venv_dir")
|
||||
|
||||
# determine venv name
|
||||
if [ -z "$venv_name" ]; then
|
||||
venv_name=$(guess_name "$venv_dir")
|
||||
fi
|
||||
|
||||
case "$venv_name" in
|
||||
"" | */* | . | .. | *:* | system | *[[:cntrl:]]* )
|
||||
echo "pyenv-link: invalid version name \`${venv_name}'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
versions_dir="$PYENV_ROOT/versions"
|
||||
pyenv_prefix_path="$versions_dir/$venv_name"
|
||||
|
||||
if [ -e "$pyenv_prefix_path" ] || [ -L "$pyenv_prefix_path" ]; then
|
||||
echo Version "$venv_name" already exists >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
case "$venv_dir" in
|
||||
"$versions_dir"/*)
|
||||
link_target=${venv_dir#"$versions_dir"/}
|
||||
;;
|
||||
*)
|
||||
link_target=$venv_dir
|
||||
;;
|
||||
esac
|
||||
|
||||
# link to pyenv version directory
|
||||
if [ -z "$dry" ]; then
|
||||
mkdir -p "$versions_dir"
|
||||
ln -s "$link_target" "$pyenv_prefix_path"
|
||||
fi
|
||||
|
||||
# output
|
||||
if [ -z "$quiet" ]; then
|
||||
echo "Linked new version named $venv_name"
|
||||
fi
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "link completions use the dispatcher" {
|
||||
run pyenv completions link
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
--help
|
||||
version
|
||||
OUT
|
||||
run pyenv completions link version
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
--help
|
||||
--dry
|
||||
--quiet
|
||||
OUT
|
||||
}
|
||||
|
||||
@test "link requires a version path" {
|
||||
run pyenv-link version
|
||||
assert_failure "Usage: pyenv link version [--dry] [--quiet] <path> [<name>]"
|
||||
}
|
||||
|
||||
@test "links an installed binary under its plain version name" {
|
||||
create_alt_executable_in_version "3.13.14-linux-x86_64" python 'echo linked-python'
|
||||
run pyenv-link version "$PYENV_ROOT/versions/3.13.14-linux-x86_64" 3.13.14
|
||||
assert_success "Linked new version named 3.13.14"
|
||||
assert_equal "3.13.14-linux-x86_64" "$(readlink "$PYENV_ROOT/versions/3.13.14")"
|
||||
PYENV_VERSION=3.13.14 run pyenv exec python
|
||||
assert_success "linked-python"
|
||||
}
|
||||
|
||||
@test "links external paths containing spaces into a fresh root" {
|
||||
mkdir -p "$PYENV_TEST_DIR/external env/bin"
|
||||
run pyenv-link version "$PYENV_TEST_DIR/external env" custom
|
||||
assert_success "Linked new version named custom"
|
||||
assert_equal "$PYENV_TEST_DIR/external env" "$(readlink "$PYENV_ROOT/versions/custom")"
|
||||
}
|
||||
|
||||
@test "refuses a dangling destination link" {
|
||||
mkdir -p "$PYENV_ROOT/versions" "$PYENV_TEST_DIR/source"
|
||||
ln -s missing "$PYENV_ROOT/versions/dangling"
|
||||
run pyenv-link version "$PYENV_TEST_DIR/source" dangling
|
||||
assert_failure "Version dangling already exists"
|
||||
assert_equal missing "$(readlink "$PYENV_ROOT/versions/dangling")"
|
||||
}
|
||||
|
||||
@test "rejects invalid version names" {
|
||||
mkdir -p "$PYENV_TEST_DIR/source"
|
||||
for name in ../outside . .. 'foo/bar' 'foo:bar' system; do
|
||||
run pyenv-link version "$PYENV_TEST_DIR/source" "$name"
|
||||
assert_failure "pyenv-link: invalid version name \`$name'"
|
||||
assert [ ! -e "$PYENV_ROOT/outside" ]
|
||||
done
|
||||
echo "prompt = '../outside'" > "$PYENV_TEST_DIR/source/pyvenv.cfg"
|
||||
run pyenv-link version "$PYENV_TEST_DIR/source"
|
||||
assert_failure "pyenv-link: invalid version name \`../outside'"
|
||||
assert [ ! -e "$PYENV_ROOT/outside" ]
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../test/test_helper.bash
|
||||
|
|
@ -54,11 +54,8 @@ Or, if you would like to install the latest development release:
|
|||
|
||||
## Usage
|
||||
|
||||
On Ubuntu, Debian, and Mint, install the recommended build dependencies with:
|
||||
|
||||
pyenv install-prerequisites
|
||||
|
||||
For other environments, see our [build environment recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment).
|
||||
Before you begin, you should ensure that your build environment has the proper
|
||||
system dependencies for compiling the wanted Python Version (see our [recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)).
|
||||
|
||||
### Using `pyenv install` with pyenv
|
||||
|
||||
|
|
@ -364,3 +361,4 @@ git diff --name-only master \
|
|||
- Filter out any which don't live where python-build keeps its build scripts
|
||||
- Look only at the file name (i.e. the python version name)
|
||||
- Run a new docker container for each, building that version
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Summary: Install Python build prerequisites on Debian-based systems
|
||||
#
|
||||
# Usage: pyenv install-prerequisites
|
||||
#
|
||||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
# Provide pyenv completions
|
||||
if [ "$1" = "--complete" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
usage() {
|
||||
pyenv-help install-prerequisites 2>/dev/null
|
||||
[ -z "$1" ] || exit "$1"
|
||||
}
|
||||
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||
usage 0
|
||||
fi
|
||||
|
||||
[ "$#" -eq 0 ] || usage 1 >&2
|
||||
|
||||
if ! command -v apt-get >/dev/null; then
|
||||
echo "pyenv: installing build prerequisites is not supported on this system" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
prerequisites=(
|
||||
make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev
|
||||
libsqlite3-dev curl git llvm libncurses5-dev libncursesw5-dev xz-utils
|
||||
tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev libzstd-dev
|
||||
)
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
apt_get=(apt-get)
|
||||
elif command -v sudo >/dev/null; then
|
||||
apt_get=(sudo apt-get)
|
||||
else
|
||||
echo "pyenv: sudo is required to install build prerequisites" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"${apt_get[@]}" update -q
|
||||
"${apt_get[@]}" install -yq "${prerequisites[@]}"
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
# -g/--debug Build a debug version
|
||||
#
|
||||
|
||||
PYTHON_BUILD_VERSION="2.8.5"
|
||||
PYTHON_BUILD_VERSION="2.8.3"
|
||||
|
||||
OLDIFS="$IFS"
|
||||
|
||||
|
|
|
|||
|
|
@ -219,10 +219,7 @@ class CondaVersion(NamedTuple):
|
|||
# since 4.8, Miniconda specifies versions explicitly in the file name
|
||||
raise ValueError("Miniconda 4.8+ is supposed to specify a Python version explicitly")
|
||||
if self.flavor == "anaconda":
|
||||
# Info about the bundled Python version
|
||||
# https://www.anaconda.com/docs/getting-started/anaconda/release-notes
|
||||
if v >= (2026,7):
|
||||
return PyVersion.PY314
|
||||
# https://www.anaconda.com/docs/tools/anaconda-org/release-notes
|
||||
if v >= (2025,6):
|
||||
return PyVersion.PY313
|
||||
if v >= (2024,6):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
'Adds the latest miniforge and mambaforge releases.'
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import string
|
||||
|
|
@ -9,7 +8,7 @@ import string
|
|||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'))
|
||||
|
||||
MINIFORGE_REPO = 'conda-forge/miniforge'
|
||||
DISTRIBUTIONS = ['miniforge']
|
||||
|
|
@ -22,8 +21,6 @@ SKIPPED_RELEASES = [
|
|||
'22.11.1-2', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
|
||||
'25.3.0-0', #marked as prerelease, no Linux version
|
||||
'25.11.0-0', #regression reported in constructor, re-released as 25.11.0-1 with hotfix bumping to constructor>=3.14 (was >=3.12, 3.13 implicit)
|
||||
'26.1.1-0', #prerelease, no binary assets
|
||||
'26.1.1-1', #prerelease, no binary assets
|
||||
]
|
||||
|
||||
install_script_fmt = """
|
||||
|
|
@ -139,7 +136,7 @@ def main():
|
|||
if version in SKIPPED_RELEASES:
|
||||
continue
|
||||
|
||||
logger.debug(f'Looking for {version} in {out_dir}')
|
||||
logger.info(f'Looking for {version} in {out_dir}')
|
||||
|
||||
# mambaforge is retired https://github.com/conda-forge/miniforge/releases/tag/24.11.2-0
|
||||
if version_tuple(version) >= (24, 11, 2):
|
||||
|
|
@ -152,17 +149,4 @@ def main():
|
|||
add_version(release, distributions)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"-d", "--dry-run", action="store_true",
|
||||
help="Do not write scripts, just report them to stdout",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="store_true", default=0,
|
||||
help="Increase verbosity of logging",
|
||||
)
|
||||
parsed = parser.parse_args()
|
||||
|
||||
if parsed.verbose: logging.getLogger.setLevel(logging.DEBUG)
|
||||
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
prefer_openssl3
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
||||
install_package "openssl-3.6.3" "https://github.com/openssl/openssl/releases/download/openssl-3.6.3/openssl-3.6.3.tar.gz#243a86649cf6f23eeb6a2ff2456e09e5d77dd9018a54d3d96b0c6bdd6ba6c7f1" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.10.21" "https://www.python.org/ftp/python/3.10.21/Python-3.10.21.tar.xz#a0da1e72132e950154eca0f6f47d5db828454700de20e5113667940d81e0db04" standard verify_py310 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.10.21" "https://www.python.org/ftp/python/3.10.21/Python-3.10.21.tgz#f276987f06270ae6c1fb4da620bd105edf78c31368c2f7e85e6c1d51c560b04b" standard verify_py310 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
prefer_openssl3
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
|
||||
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
||||
install_package "openssl-3.6.3" "https://github.com/openssl/openssl/releases/download/openssl-3.6.3/openssl-3.6.3.tar.gz#243a86649cf6f23eeb6a2ff2456e09e5d77dd9018a54d3d96b0c6bdd6ba6c7f1" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.11.16" "https://www.python.org/ftp/python/3.11.16/Python-3.11.16.tar.xz#91bcdebfdde239a003ae93738a7fce0f9230fee5c4bc2b86f6e6e8c6f98aabe8" standard verify_py311 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.11.16" "https://www.python.org/ftp/python/3.11.16/Python-3.11.16.tgz#6c0bd76ab0ec7d94ed400b1497f01ac6c7751c8822615ee0855a3eb2d893ea76" standard verify_py311 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
prefer_openssl3
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
|
||||
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
||||
install_package "openssl-3.6.3" "https://github.com/openssl/openssl/releases/download/openssl-3.6.3/openssl-3.6.3.tar.gz#243a86649cf6f23eeb6a2ff2456e09e5d77dd9018a54d3d96b0c6bdd6ba6c7f1" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.12.14" "https://www.python.org/ftp/python/3.12.14/Python-3.12.14.tar.xz#5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a" standard verify_py312 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.12.14" "https://www.python.org/ftp/python/3.12.14/Python-3.12.14.tgz#6c6df908d2c3fd24e6d76869e92542abd0f33aec9dfc18df8875f89660286d43" standard verify_py312 copy_python_gdb ensurepip
|
||||
fi
|
||||
11
plugins/python-build/share/python-build/3.15.0rc1
Normal file
11
plugins/python-build/share/python-build/3.15.0rc1
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
prefer_openssl3
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
|
||||
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
||||
install_package "openssl-4.0.1" "https://github.com/openssl/openssl/releases/download/openssl-4.0.1/openssl-4.0.1.tar.gz#2db3f3a0d6ea4b59e1f094ace2c8cd536dffb87cdc39084c5afa1e6f7f37dd09" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.15.0rc1" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc1.tar.xz#f84dad680ab2147417d2739355c2678f0f9acffe4ae8ef77895de1454b384b07" standard verify_py315 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.15.0rc1" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc1.tgz#32c2b9878bbd6ac3ceb138c5b6c880345ce9d33388b399378c0da6fc7cb3bfbc" standard verify_py315 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
prefer_openssl3
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
|
||||
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
||||
install_package "openssl-4.0.2" "https://github.com/openssl/openssl/releases/download/openssl-4.0.2/openssl-4.0.2.tar.gz#736b467530f916737b7031310ccb21d8218c6229e61e8e160cd1d3458cd543a8" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.15.0rc2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc2.tar.xz#8d93af5eaaaea5adfd41bd786a7ba3f03f2ad1ab57c6a65e0b963deab91d5ad7" standard verify_py315 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.15.0rc2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc2.tgz#164dbb80f5e1fdd8768387724bfa014da1000401b2015d872a2396c8b858b829" standard verify_py315 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Anaconda3-2026.07-1-Linux-aarch64" "https://repo.anaconda.com/archive/Anaconda3-2026.07-1-Linux-aarch64.sh#af2fd0025728a04408e0481d5668b92c53589cbfc66525a15119e6503742a04d" "anaconda" verify_py314
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Anaconda3-2026.07-1-Linux-x86_64" "https://repo.anaconda.com/archive/Anaconda3-2026.07-1-Linux-x86_64.sh#9f49042048e9a8220c1cddf9192054290724052d3b2a86f938f9f5edd911db8f" "anaconda" verify_py314
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Anaconda3-2026.07-1-MacOSX-arm64" "https://repo.anaconda.com/archive/Anaconda3-2026.07-1-MacOSX-arm64.sh#6a9b63c645db4dbe293ffe9f168f7e380fe7a041fc863e67ee84db027425bce2" "anaconda" verify_py314
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Anaconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is furnished to do
|
||||
# so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
VERSION='25.3.4.1'
|
||||
RELEASE_TAG='graal-25.3.4'
|
||||
|
||||
colorize 1 "GraalPy 23.1 and later installed by python-build use the faster Oracle GraalVM distribution" && echo
|
||||
colorize 1 "Oracle GraalVM uses the GFTC license, which is free for development and production use, see https://medium.com/graalvm/161527df3d76" && echo
|
||||
colorize 1 "The GraalVM Community Edition variant of GraalPy is also available, under the name graalpy3.13-community-${VERSION}" && echo
|
||||
|
||||
|
||||
graalpy_arch="$(graalpy_architecture 2>/dev/null || true)"
|
||||
|
||||
case "$graalpy_arch" in
|
||||
"linux-amd64" )
|
||||
checksum="23515b4e659d645960517b0ceedb90faa84fcb01f0f4497beca5868a1b1ae3ea"
|
||||
;;
|
||||
"linux-aarch64" )
|
||||
checksum="53b80e284e444540ae7cb67349af3dd8f6c1848fbf6abb5051742ac745f1f33d"
|
||||
;;
|
||||
"macos-aarch64" )
|
||||
checksum="8ac33b5a5d0ee872751595211508fd826f47051ff6e6614032aed1de071eebab"
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": No binary distribution of GraalPy is available for $(uname -sm)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
install_package "graalpy3.13-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is furnished to do
|
||||
# so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
VERSION='25.3.4.1'
|
||||
RELEASE_TAG='graal-25.3.4'
|
||||
|
||||
graalpy_arch="$(graalpy_architecture 2>/dev/null || true)"
|
||||
|
||||
case "$graalpy_arch" in
|
||||
"linux-amd64" )
|
||||
checksum="5e239616c8352488585f58d33991d262e8c627483741778ad43d39a4830176ad"
|
||||
;;
|
||||
"linux-aarch64" )
|
||||
checksum="13007ecfe8180e91f1060de60a2ba6ce88f38faa4a36574b34143a492e8c660e"
|
||||
;;
|
||||
"macos-aarch64" )
|
||||
checksum="e2cf7ae230478ad8d100ad868f75e3addb174d81e7f550322ea5e74cab066644"
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": No binary distribution of GraalPy is available for $(uname -sm)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
install_package "graalpy3.13-community-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-community-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Miniconda3-py310_26.5.3-2-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.5.3-2-Linux-aarch64.sh#69b30d25b1308596e39819d2eeb8d669fec8b35205254d4d38975e9a6eb525e5" "miniconda" verify_py310
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Miniconda3-py310_26.5.3-2-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.5.3-2-Linux-x86_64.sh#83e53ab0246ca320db28734bfd16f9bba895d96ae3e0ccf6f9b65e1383ab6a26" "miniconda" verify_py310
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Miniconda3-py310_26.5.3-2-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.5.3-2-MacOSX-arm64.sh#fc25d37469e162e3073093c1e02a0a21a59681af10a097f73df3f303b89b050a" "miniconda" verify_py310
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Miniconda3-py311_26.5.3-2-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.5.3-2-Linux-aarch64.sh#e50d1c902e94b6f64a19e0a3fbc35f8cadc09c5a1cf5b0fe10da14e4ce7ff24d" "miniconda" verify_py311
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Miniconda3-py311_26.5.3-2-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.5.3-2-Linux-x86_64.sh#cdca3dd8440759bb87c60b227e26946263fe2856b30b2bcfdd964c38254fb8eb" "miniconda" verify_py311
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Miniconda3-py311_26.5.3-2-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.5.3-2-MacOSX-arm64.sh#129bee9cb8e23d0eed175439a8b41c9844bac5c75f3f2aefa0be7104b403706f" "miniconda" verify_py311
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Miniconda3-py312_26.5.3-2-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.5.3-2-Linux-aarch64.sh#822923b30d789477964ef5589f86de5a72ac4c584bad3b9f72d97190e13d776f" "miniconda" verify_py312
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Miniconda3-py312_26.5.3-2-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.5.3-2-Linux-x86_64.sh#37606f9f03ced8ef60f4ffc76b21dda01728eac8a632dcab316c891cea4fe2f5" "miniconda" verify_py312
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Miniconda3-py312_26.5.3-2-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.5.3-2-MacOSX-arm64.sh#ba7e4dede827e98c468c2dfa3b9a859728844ee8bde72a28eb216869af2d6ce1" "miniconda" verify_py312
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Miniconda3-py313_26.5.3-2-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.5.3-2-Linux-aarch64.sh#549176858e194a15df5c8326b9f4e1b7ddf1464df47aec4115d0e6d14204e8bb" "miniconda" verify_py313
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Miniconda3-py313_26.5.3-2-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.5.3-2-Linux-x86_64.sh#66f7c434bbdc7a4c5687b7e56cde724f73954d1322ffb273c6e387f12fbcdc03" "miniconda" verify_py313
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Miniconda3-py313_26.5.3-2-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.5.3-2-MacOSX-arm64.sh#0d4d44f5d0740dddc68d381bbc8eb8c056d4792c832a9f0e3b5c663f7dda9d67" "miniconda" verify_py313
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
"Linux-aarch64" )
|
||||
install_script "Miniconda3-py314_26.5.3-2-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.5.3-2-Linux-aarch64.sh#999e8761f4dc74fb8d0dc9f74d5374f6708ff81eebbb0af677a4d5307d38b2e5" "miniconda" verify_py314
|
||||
;;
|
||||
"Linux-x86_64" )
|
||||
install_script "Miniconda3-py314_26.5.3-2-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.5.3-2-Linux-x86_64.sh#80bc27f13c4de90f10e387aa45e864de4f0860692c1221aef5900009a2b55302" "miniconda" verify_py314
|
||||
;;
|
||||
"MacOSX-arm64" )
|
||||
install_script "Miniconda3-py314_26.5.3-2-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.5.3-2-MacOSX-arm64.sh#e830bee5b9c6ebfb67e9df924b259a0d43c451bd17b965f7aa84523b69f7c3eb" "miniconda" verify_py314
|
||||
;;
|
||||
* )
|
||||
{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
From 3fec519d6b326918f39ceb142ef762042ce8365f Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Pozdeev <vano@mail.mipt.ru>
|
||||
Date: Fri, 26 Dec 2025 13:39:21 +0300
|
||||
Subject: [PATCH] Recognize an argument to -j in MAKEFLAGS
|
||||
|
||||
---
|
||||
setup.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/setup.py b/setup.py
|
||||
index ad8fb81b218..5666deaf67b 100644
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -307,8 +307,8 @@ def __init__(self, dist):
|
||||
self.failed_on_import = []
|
||||
self.missing = []
|
||||
self.disabled_configure = []
|
||||
- if '-j' in os.environ.get('MAKEFLAGS', ''):
|
||||
- self.parallel = True
|
||||
+ if (m:=re.search(r'(?:^|\s)(?:-j|--jobs)(?:\s+|=)?(\d*)',os.environ.get('MAKEFLAGS', ''))) is not None:
|
||||
+ self.parallel = int(m.group(1)) if m.group(1) else True
|
||||
|
||||
def add(self, ext):
|
||||
self.extensions.append(ext)
|
||||
--
|
||||
2.36.1.windows.1
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
From 3fec519d6b326918f39ceb142ef762042ce8365f Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Pozdeev <vano@mail.mipt.ru>
|
||||
Date: Fri, 26 Dec 2025 13:39:21 +0300
|
||||
Subject: [PATCH] Recognize an argument to -j in MAKEFLAGS
|
||||
|
||||
---
|
||||
setup.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/setup.py b/setup.py
|
||||
index ad8fb81b218..5666deaf67b 100644
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -307,8 +307,8 @@ def __init__(self, dist):
|
||||
self.failed_on_import = []
|
||||
self.missing = []
|
||||
self.disabled_configure = []
|
||||
- if '-j' in os.environ.get('MAKEFLAGS', ''):
|
||||
- self.parallel = True
|
||||
+ if (m:=re.search(r'(?:^|\s)(?:-j|--jobs)(?:\s+|=)?(\d*)',os.environ.get('MAKEFLAGS', ''))) is not None:
|
||||
+ self.parallel = int(m.group(1)) if m.group(1) else True
|
||||
|
||||
def add(self, ext):
|
||||
self.extensions.append(ext)
|
||||
--
|
||||
2.36.1.windows.1
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
From 3fec519d6b326918f39ceb142ef762042ce8365f Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Pozdeev <vano@mail.mipt.ru>
|
||||
Date: Fri, 26 Dec 2025 13:39:21 +0300
|
||||
Subject: [PATCH] Recognize an argument to -j in MAKEFLAGS
|
||||
|
||||
---
|
||||
setup.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/setup.py b/setup.py
|
||||
index ad8fb81b218..5666deaf67b 100644
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -307,8 +307,8 @@ def __init__(self, dist):
|
||||
self.failed_on_import = []
|
||||
self.missing = []
|
||||
self.disabled_configure = []
|
||||
- if '-j' in os.environ.get('MAKEFLAGS', ''):
|
||||
- self.parallel = True
|
||||
+ if (m:=re.search(r'(?:^|\s)(?:-j|--jobs)(?:\s+|=)?(\d*)',os.environ.get('MAKEFLAGS', ''))) is not None:
|
||||
+ self.parallel = int(m.group(1)) if m.group(1) else True
|
||||
|
||||
def add(self, ext):
|
||||
self.extensions.append(ext)
|
||||
--
|
||||
2.36.1.windows.1
|
||||
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
From cc13eabc7ce08accf49656e258ba500f74a1dae8 Mon Sep 17 00:00:00 2001
|
||||
From: Ronald Oussoren <ronaldoussoren@mac.com>
|
||||
Date: Thu, 28 Dec 2023 09:42:05 +0100
|
||||
Subject: [PATCH] gh-110459: Make sure --with-openssl-rpath works on macOS
|
||||
(#113441)
|
||||
|
||||
* gh-110459: Make sure --with-openssl-rpath works on macOS
|
||||
|
||||
On macOS the `-rpath` linker flag is spelled differently
|
||||
than on on platforms.
|
||||
---
|
||||
.../macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst | 2 ++
|
||||
configure | 7 ++++++-
|
||||
configure.ac | 7 ++++++-
|
||||
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
|
||||
|
||||
diff --git a/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst b/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
|
||||
new file mode 100644
|
||||
index 00000000000..44ffd857785
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
|
||||
@@ -0,0 +1,2 @@
|
||||
+Running ``configure ... --with-openssl-rpath=X/Y/Z`` no longer fails to detect
|
||||
+OpenSSL on macOS.
|
||||
diff --git a/configure b/configure
|
||||
index 7e50abc29d0..6d65d3abc18 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -27478,7 +27478,12 @@ then :
|
||||
|
||||
else $as_nop
|
||||
|
||||
- rpath_arg="-Wl,-rpath="
|
||||
+ if test "$ac_sys_system" = "Darwin"
|
||||
+ then
|
||||
+ rpath_arg="-Wl,-rpath,"
|
||||
+ else
|
||||
+ rpath_arg="-Wl,-rpath="
|
||||
+ fi
|
||||
|
||||
fi
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index e064848af9e..bfdabc4474e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -6808,7 +6808,12 @@ AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no])
|
||||
AS_VAR_IF([GNULD], [yes], [
|
||||
rpath_arg="-Wl,--enable-new-dtags,-rpath="
|
||||
], [
|
||||
- rpath_arg="-Wl,-rpath="
|
||||
+ if test "$ac_sys_system" = "Darwin"
|
||||
+ then
|
||||
+ rpath_arg="-Wl,-rpath,"
|
||||
+ else
|
||||
+ rpath_arg="-Wl,-rpath="
|
||||
+ fi
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for --with-openssl-rpath])
|
||||
--
|
||||
2.46.2.windows.1
|
||||
|
||||
|
|
@ -1276,7 +1276,6 @@ OUT
|
|||
mkdir -p "$INSTALL_ROOT/bin"
|
||||
touch "$INSTALL_ROOT/bin/package"
|
||||
chmod -w "$INSTALL_ROOT/bin/package"
|
||||
skip_if_nonposix_security -w "$INSTALL_ROOT/bin/package"
|
||||
|
||||
install_fixture definitions/without-checksum
|
||||
assert_success
|
||||
|
|
@ -1289,7 +1288,6 @@ OUT
|
|||
export TMPDIR="${BATS_TEST_TMPDIR}/build"
|
||||
mkdir -p "$TMPDIR"
|
||||
chmod -w "$TMPDIR"
|
||||
skip_if_nonposix_security -w "$TMPDIR"
|
||||
|
||||
touch "${BATS_TEST_TMPDIR}/build-definition"
|
||||
run python-build "${BATS_TEST_TMPDIR}/build-definition" "$INSTALL_ROOT"
|
||||
|
|
@ -1300,7 +1298,6 @@ OUT
|
|||
export TMPDIR="${BATS_TEST_TMPDIR}/build"
|
||||
mkdir -p "$TMPDIR"
|
||||
chmod -x "$TMPDIR"
|
||||
skip_if_nonposix_security -x "$TMPDIR"
|
||||
|
||||
touch "${BATS_TEST_TMPDIR}/build-definition"
|
||||
run python-build "${BATS_TEST_TMPDIR}/build-definition" "$INSTALL_ROOT"
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
_setup() {
|
||||
prerequisites="make build-essential libssl-dev zlib1g-dev libbz2-dev \
|
||||
libreadline-dev libsqlite3-dev curl git llvm libncurses5-dev \
|
||||
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev \
|
||||
liblzma-dev libzstd-dev"
|
||||
}
|
||||
|
||||
@test "completion does not install packages" {
|
||||
stub apt-get
|
||||
|
||||
PATH="${BATS_TEST_DIRNAME}/../../../libexec:$PATH" \
|
||||
run pyenv completions install-prerequisites
|
||||
|
||||
assert_success "--help"
|
||||
unstub apt-get
|
||||
}
|
||||
|
||||
@test "supports help" {
|
||||
stub pyenv-help 'install-prerequisites : echo "Usage: pyenv install-prerequisites"'
|
||||
|
||||
run pyenv-install-prerequisites --help
|
||||
|
||||
assert_success "Usage: pyenv install-prerequisites"
|
||||
unstub pyenv-help
|
||||
}
|
||||
|
||||
@test "rejects arguments" {
|
||||
stub pyenv-help 'install-prerequisites : echo "Usage: pyenv install-prerequisites"'
|
||||
|
||||
run pyenv-install-prerequisites unexpected
|
||||
|
||||
assert_failure "Usage: pyenv install-prerequisites"
|
||||
unstub pyenv-help
|
||||
}
|
||||
|
||||
@test "installs build prerequisites with apt-get as root" {
|
||||
stub id '-u : echo 0'
|
||||
stub apt-get \
|
||||
'update -q : true' \
|
||||
"install -yq ${prerequisites} : true"
|
||||
|
||||
run pyenv-install-prerequisites
|
||||
|
||||
assert_success
|
||||
unstub apt-get
|
||||
unstub id
|
||||
}
|
||||
|
||||
@test "uses sudo when not running as root" {
|
||||
stub id '-u : echo 1000'
|
||||
stub apt-get
|
||||
stub sudo \
|
||||
'apt-get update -q : true' \
|
||||
"apt-get install -yq ${prerequisites} : true"
|
||||
|
||||
run pyenv-install-prerequisites
|
||||
|
||||
assert_success
|
||||
unstub sudo
|
||||
unstub apt-get
|
||||
unstub id
|
||||
}
|
||||
|
||||
@test "fails when apt-get is unavailable" {
|
||||
PATH="$(path_without apt-get)" run pyenv-install-prerequisites
|
||||
|
||||
assert_failure "pyenv: installing build prerequisites is not supported on this system"
|
||||
}
|
||||
|
||||
@test "fails when sudo is unavailable for an unprivileged user" {
|
||||
stub id '-u : echo 1000'
|
||||
stub apt-get
|
||||
|
||||
PATH="$(path_without sudo)" run pyenv-install-prerequisites
|
||||
|
||||
assert_failure "pyenv: sudo is required to install build prerequisites"
|
||||
unstub apt-get
|
||||
unstub id
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ setup() {
|
|||
export PYTHON_BUILD_CURL_OPTS=
|
||||
export PYTHON_BUILD_HTTP_CLIENT="curl"
|
||||
|
||||
export PYENV_TEST_DIR="${BATS_TEST_TMPDIR}/pyenv"
|
||||
export FIXTURE_ROOT="${BATS_TEST_DIRNAME}/fixtures"
|
||||
export INSTALL_ROOT="${BATS_TEST_TMPDIR}/install"
|
||||
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
|
|
@ -149,7 +148,7 @@ path_without() {
|
|||
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
||||
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
||||
mkdir -p "$alt"
|
||||
for util in bash head cut readlink greadlink tr; do
|
||||
for util in bash head cut readlink greadlink; do
|
||||
if [ -x "${found}/$util" ]; then
|
||||
ln -s "${found}/$util" "${alt}/$util"
|
||||
fi
|
||||
|
|
@ -163,7 +162,3 @@ path_without() {
|
|||
echo "$path"
|
||||
}
|
||||
|
||||
skip_if_nonposix_security() {
|
||||
true "${1:?}" "${2:?}"
|
||||
test "$@" && skip "UNIX permission bits are being overridden" || true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ FROM bash:$BASH
|
|||
apk add sed coreutils findutils \
|
||||
;fi
|
||||
# Bats
|
||||
RUN apk add --update parallel ncurses git binutils \
|
||||
RUN apk add --update parallel ncurses git \
|
||||
&& mkdir -p ~/.parallel \
|
||||
&& touch ~/.parallel/will-cite
|
||||
COPY --from=bats /root/bats-core /root/bats-core
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Wraps Bats TAP formatter, adding file names to the output
|
||||
|
||||
_BATS_FORMATTER_LIB_RELPATH="lib/bats-core/formatter.bash"
|
||||
source "$BATS_ROOT/$_BATS_FORMATTER_LIB_RELPATH"
|
||||
|
||||
|
||||
# `bats-format-tap` calls this fn at the end
|
||||
# We must stub it to be able to source and alter it
|
||||
# https://stackoverflow.com/questions/1203583/how-do-i-rename-a-bash-function
|
||||
eval orig_"$(declare -f bats_parse_internal_extended_tap)"
|
||||
bats_parse_internal_extended_tap() { true; }
|
||||
|
||||
|
||||
# stub sourcing lib from `bats-format-tap`
|
||||
# as that would've reset the stubbed fn
|
||||
FAKE_BATS_ROOT=
|
||||
_trap_rm_fakeroot() { rm -rf "$FAKE_BATS_ROOT"; }
|
||||
REAL_BATS_ROOT="$BATS_ROOT"
|
||||
FAKE_BATS_ROOT=$(mktemp -d)
|
||||
trap _trap_rm_fakeroot ERR EXIT
|
||||
mkdir -p "$(dirname "$FAKE_BATS_ROOT/$_BATS_FORMATTER_LIB_RELPATH")"
|
||||
touch "$FAKE_BATS_ROOT/$_BATS_FORMATTER_LIB_RELPATH"
|
||||
BATS_ROOT="$FAKE_BATS_ROOT"
|
||||
|
||||
source "$REAL_BATS_ROOT/libexec/bats-core/bats-format-tap"
|
||||
|
||||
_trap_rm_fakeroot
|
||||
trap - ERR EXIT
|
||||
BATS_ROOT="$REAL_BATS_ROOT"
|
||||
unset FAKE_BATS_ROOT REAL_BATS_ROOT _trap_rm_fakeroot
|
||||
|
||||
|
||||
# Finally, alter `bats-format-tap`'s logic and invoke it
|
||||
|
||||
# print as "Anything" line
|
||||
bats_tap_stream_suite() { # <file name>
|
||||
# bats only passes --base-name to specific built-in formatters
|
||||
# so we don't have info where the test root is
|
||||
printf '%s\n' "${1##*/}"
|
||||
}
|
||||
|
||||
orig_bats_parse_internal_extended_tap
|
||||
|
|
@ -13,8 +13,6 @@ load test_helper
|
|||
@test "non-writable shims directory" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
chmod -w "${PYENV_ROOT}/shims"
|
||||
skip_if_nonposix_security -w "${PYENV_ROOT}/shims"
|
||||
|
||||
run pyenv-rehash
|
||||
assert_failure "pyenv: cannot rehash: ${PYENV_ROOT}/shims isn't writable"
|
||||
}
|
||||
|
|
@ -25,8 +23,7 @@ load test_helper
|
|||
touch "${PYENV_ROOT}/shims/.pyenv-shim"
|
||||
#avoid failure due to a localized error message
|
||||
LANG=C run pyenv-rehash
|
||||
assert_failure
|
||||
assert_output_glob <<!
|
||||
assert_failure <<!
|
||||
pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for 1 seconds. Last error message:
|
||||
*/pyenv-rehash: line *: ${PYENV_ROOT}/shims/.pyenv-shim: cannot overwrite existing file
|
||||
!
|
||||
|
|
|
|||
2
test/run
2
test/run
|
|
@ -6,4 +6,4 @@ if [ -n "$PYENV_NATIVE_EXT" ]; then
|
|||
make -C src
|
||||
fi
|
||||
|
||||
exec bats ${CI:+-F "$PWD/test/libexec/bats-format-tap-suite"} ${BATS_TEST_FILTER:+--filter "${BATS_TEST_FILTER}"} test/${BATS_FILE_FILTER}
|
||||
exec bats ${CI:+--tap} ${BATS_TEST_FILTER:+--filter "${BATS_TEST_FILTER}"} test/${BATS_FILE_FILTER}
|
||||
|
|
|
|||
39
test/shims-linked-from-elsewhere.bats
Normal file
39
test/shims-linked-from-elsewhere.bats
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "shims linked from elsewhere are chained, other programs at the same paths are unaffected (integration)" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
progname=shimmed_program
|
||||
called_progname=another_program
|
||||
create_alt_executable_in_version "custom" "$progname" <<!
|
||||
echo "called from \$0"
|
||||
pyenv-exec "$called_progname"
|
||||
!
|
||||
pyenv-rehash
|
||||
PATH="$(path_without "$progname" "$called_progname")"
|
||||
for disguised_shim_path in "$BATS_TEST_TMPDIR/"{weird-location,even/weirder/location}; do
|
||||
mkdir -p "$disguised_shim_path"
|
||||
ln -s "${PYENV_ROOT}/shims/$progname" "$disguised_shim_path/$progname"
|
||||
PATH="$PATH:$disguised_shim_path"
|
||||
done
|
||||
create_executable "$disguised_shim_path" "$called_progname" <<!
|
||||
echo "convoluted call success!"
|
||||
!
|
||||
real_path="$BATS_TEST_TMPDIR/real-location"
|
||||
mkdir -p "$real_path"
|
||||
ln -s "${PYENV_ROOT}/versions/custom/bin/$progname" "$real_path/$progname"
|
||||
PATH="$PATH:$real_path"
|
||||
|
||||
run "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
called from $real_path/$progname
|
||||
convoluted call success!
|
||||
!
|
||||
|
||||
rm "$real_path/$progname"
|
||||
run -127 "$progname"
|
||||
assert_failure
|
||||
assert_line 0 "pyenv: shimmed_program: command not found"
|
||||
}
|
||||
|
|
@ -27,39 +27,3 @@ load test_helper
|
|||
assert_line "irb"
|
||||
assert_line "python"
|
||||
}
|
||||
|
||||
@test "shims linked from elsewhere are chained, other programs at the same paths are unaffected (integration)" {
|
||||
bats_require_minimum_version 1.5.0
|
||||
progname=shimmed_program
|
||||
called_progname=another_program
|
||||
create_alt_executable_in_version "custom" "$progname" <<!
|
||||
echo "called from \$0"
|
||||
pyenv-exec "$called_progname"
|
||||
!
|
||||
pyenv-rehash
|
||||
PATH="$(path_without "$progname" "$called_progname")"
|
||||
for disguised_shim_path in "$BATS_TEST_TMPDIR/"{weird-location,even/weirder/location}; do
|
||||
mkdir -p "$disguised_shim_path"
|
||||
ln -s "${PYENV_ROOT}/shims/$progname" "$disguised_shim_path/$progname"
|
||||
PATH="$PATH:$disguised_shim_path"
|
||||
done
|
||||
create_executable "$disguised_shim_path" "$called_progname" <<!
|
||||
echo "convoluted call success!"
|
||||
!
|
||||
real_path="$BATS_TEST_TMPDIR/real-location"
|
||||
mkdir -p "$real_path"
|
||||
ln -s "${PYENV_ROOT}/versions/custom/bin/$progname" "$real_path/$progname"
|
||||
PATH="$PATH:$real_path"
|
||||
|
||||
run "$progname"
|
||||
assert_success
|
||||
assert_output <<!
|
||||
called from $real_path/$progname
|
||||
convoluted call success!
|
||||
!
|
||||
|
||||
rm "$real_path/$progname"
|
||||
run -127 "$progname"
|
||||
assert_failure
|
||||
assert_line 0 "pyenv: shimmed_program: command not found"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,8 @@ unset PYENV_VERSION
|
|||
unset PYENV_DIR
|
||||
|
||||
setup() {
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
|
||||
export _PYENV_INSTALL_PREFIX="${BATS_TEST_DIRNAME%/*}"
|
||||
local PLUGIN_PREFIX
|
||||
if [[ $_PYENV_INSTALL_PREFIX =~ /plugins/[^/]+$ ]]; then
|
||||
PLUGIN_PREFIX="$_PYENV_INSTALL_PREFIX"
|
||||
_PYENV_INSTALL_PREFIX="${_PYENV_INSTALL_PREFIX::${#_PYENV_INSTALL_PREFIX}-${#BASH_REMATCH[0]}}"
|
||||
fi
|
||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||
if ! enable -f "${_PYENV_INSTALL_PREFIX}"/libexec/pyenv-realpath.dylib realpath 2>/dev/null; then
|
||||
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
||||
echo "pyenv: failed to load \`realpath' builtin" >&2
|
||||
|
|
@ -33,9 +27,6 @@ setup() {
|
|||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
|
||||
PATH="${PYENV_TEST_DIR}/bin:$PATH"
|
||||
PATH="${_PYENV_INSTALL_PREFIX}/libexec:$PATH"
|
||||
if [[ -n $PLUGIN_PREFIX ]]; then
|
||||
PATH="${PLUGIN_PREFIX}/libexec:${PLUGIN_PREFIX}/bin:$PATH"
|
||||
fi
|
||||
PATH="${BATS_TEST_DIRNAME}/libexec:$PATH"
|
||||
PATH="${PYENV_ROOT}/shims:$PATH"
|
||||
PATH="${BATS_TEST_TMPDIR}/stubs:$PATH"
|
||||
|
|
@ -49,7 +40,6 @@ setup() {
|
|||
# even if its output is redirected, breaking the comparison logic
|
||||
export NO_COLOR=1
|
||||
|
||||
|
||||
# If test specific setup exist, run it
|
||||
if [[ $(type -t _setup) == function ]];then
|
||||
_setup
|
||||
|
|
@ -68,64 +58,34 @@ assert_success() {
|
|||
if [ "$status" -ne 0 ]; then
|
||||
flunk "command failed with exit status $status" $'\n'\
|
||||
"output: $output"
|
||||
elif [ "$#" -gt 0 ]; then
|
||||
assert_output "$1"
|
||||
fi
|
||||
_assert_output_if_provided "$@"
|
||||
}
|
||||
|
||||
assert_failure() {
|
||||
if [ "$status" -eq 0 ]; then
|
||||
flunk "expected failed exit status" $'\n'\
|
||||
"output: $output"
|
||||
elif [ "$#" -gt 0 ]; then
|
||||
assert_output "$1"
|
||||
fi
|
||||
_assert_output_if_provided "$@"
|
||||
}
|
||||
|
||||
assert_equal() {
|
||||
_assert_equal_as text "$@"
|
||||
}
|
||||
|
||||
_assert_equal_as() {
|
||||
if case "$1" in
|
||||
text)
|
||||
[[ "$2" != "$3" ]];;
|
||||
glob)
|
||||
[[ "$3" != $2 ]];;
|
||||
*)
|
||||
echo "invalid comparison type: \`$1'" >&2; return 1;;
|
||||
esac
|
||||
then
|
||||
{ diff -u --label expected --label actual <(echo "$2") <(echo "$3") | cat -te
|
||||
if [ "$1" != "$2" ]; then
|
||||
{ echo "expected: \`$1'"
|
||||
echo "actual: \`$2'"
|
||||
} | flunk
|
||||
fi
|
||||
}
|
||||
|
||||
_assert_output_if_provided() {
|
||||
if [ "$#" -gt 0 ]; then
|
||||
assert_output "$1"
|
||||
elif [ ! -t 0 ]; then
|
||||
local expected=$(cat -)
|
||||
if [[ -n $expected ]]; then
|
||||
assert_output "$expected"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
assert_output() {
|
||||
_assert_output_as text "$@"
|
||||
}
|
||||
|
||||
assert_output_glob() {
|
||||
_assert_output_as glob "$@"
|
||||
}
|
||||
|
||||
_assert_output_as() {
|
||||
local kind="${1:?}"; shift
|
||||
local expected
|
||||
if [ $# -eq 0 ]
|
||||
then expected="$(cat -)"
|
||||
else expected="$1"
|
||||
if [ $# -eq 0 ]; then expected="$(cat -)"
|
||||
else expected="$1"
|
||||
fi
|
||||
_assert_equal_as "$kind" "$expected" "$output"
|
||||
assert_equal "$expected" "$output"
|
||||
}
|
||||
|
||||
assert_line() {
|
||||
|
|
@ -175,7 +135,7 @@ path_without() {
|
|||
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
||||
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
||||
mkdir -p "$alt"
|
||||
for util in basename bash cut dirname find greadlink gzip head mkdir readlink sed sort tar tr xargs; do
|
||||
for util in bash head cut readlink greadlink tr sed xargs basename sort; do
|
||||
if [ -x "${found}/$util" ]; then
|
||||
ln -s "${found}/$util" "${alt}/$util"
|
||||
fi
|
||||
|
|
@ -233,8 +193,3 @@ create_hook() {
|
|||
cat > "${PYENV_HOOK_PATH}/$1/$2"
|
||||
fi
|
||||
}
|
||||
|
||||
skip_if_nonposix_security() {
|
||||
true "${1:?}" "${2:?}"
|
||||
test "$@" && skip "UNIX permission bits are being overridden" || true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ IN
|
|||
}
|
||||
|
||||
@test "skips glob path traversal" {
|
||||
cat > my-version <<'IN'
|
||||
cat > my-version <<IN
|
||||
../*
|
||||
3.9.3
|
||||
IN
|
||||
run pyenv-version-file-read my-version
|
||||
assert_success <<'OUT'
|
||||
pyenv: invalid version `../*' ignored in `my-version'
|
||||
assert_success <<OUT
|
||||
pyenv: invalid version \`../\*' ignored in \`my-version'
|
||||
3.9.3
|
||||
OUT
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,15 +73,3 @@ create_file() {
|
|||
run pyenv-version-file "$PWD"
|
||||
assert_failure ""
|
||||
}
|
||||
|
||||
@test "walks up beyond cwd for a relative path" {
|
||||
create_file ".python-version"
|
||||
mkdir -p project/subdir
|
||||
cd project
|
||||
# Run with CPU-time limit because this used to loop forever
|
||||
run bash -c 'ulimit -t 5; pyenv-version-file .'
|
||||
assert_success "${PYENV_TEST_DIR}/.python-version"
|
||||
|
||||
run pyenv-version-file ./subdir
|
||||
assert_success "${PYENV_TEST_DIR}/.python-version"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ OUT
|
|||
create_version "3.4.0/envs/bar"
|
||||
create_version "3.5.2"
|
||||
run pyenv-versions
|
||||
assert_success <<OUT
|
||||
assert_success
|
||||
assert_output <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
2.7.6
|
||||
3.4.0
|
||||
|
|
@ -94,7 +95,6 @@ OUT
|
|||
}
|
||||
|
||||
@test "skips envs with --skip-envs" {
|
||||
stub_system_python
|
||||
create_version "3.3.3"
|
||||
create_version "3.4.0"
|
||||
create_version "3.4.0/envs/foo"
|
||||
|
|
@ -102,7 +102,7 @@ OUT
|
|||
create_version "3.5.0"
|
||||
|
||||
run pyenv-versions --skip-envs
|
||||
assert_success <<OUT
|
||||
assert_success <<OUT
|
||||
* system (set by ${PYENV_ROOT}/version)
|
||||
3.3.3
|
||||
3.4.0
|
||||
|
|
@ -188,7 +188,9 @@ OUT
|
|||
create_external_version "moo"
|
||||
|
||||
run pyenv-versions --bare --skip-aliases
|
||||
assert_success <<OUT
|
||||
assert_success
|
||||
|
||||
assert_output <<OUT
|
||||
1.8.7
|
||||
moo
|
||||
OUT
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ load test_helper
|
|||
assert_failure <<OUT
|
||||
pyenv: version \`3.3' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: py.test: command not found
|
||||
|
||||
|
||||
The \`py.test' command exists in these Python versions:
|
||||
3.4
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ OUT
|
|||
pyenv: version \`2.7' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: version \`3.3' is not installed (set by PYENV_VERSION environment variable)
|
||||
pyenv: py.test: command not found
|
||||
|
||||
|
||||
The \`py.test' command exists in these Python versions:
|
||||
3.4
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue