mirror of
https://github.com/pyenv/pyenv.git
synced 2026-06-17 14:08:15 +09:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f122a9d764 | ||
|
|
3323ba3ed9 | ||
|
|
b43c9e5d42 | ||
|
|
532b659ca2 | ||
|
|
7565df6eab | ||
|
|
e55613a267 | ||
|
|
6c0c5cfa96 | ||
|
|
cf6f3c3200 | ||
|
|
45180928d3 |
5
.github/workflows/macos_build.yml
vendored
5
.github/workflows/macos_build.yml
vendored
@ -1,5 +1,8 @@
|
||||
name: macos_build
|
||||
on: [pull_request, push]
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
5
.github/workflows/pyenv_tests.yml
vendored
5
.github/workflows/pyenv_tests.yml
vendored
@ -1,5 +1,8 @@
|
||||
name: pyenv_tests
|
||||
on: [pull_request, push]
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
5
.github/workflows/ubuntu_build.yml
vendored
5
.github/workflows/ubuntu_build.yml
vendored
@ -1,5 +1,8 @@
|
||||
name: ubuntu_build
|
||||
on: [pull_request, push]
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request: {}
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,5 +1,18 @@
|
||||
# Version History
|
||||
|
||||
## Release v2.7.2
|
||||
* fix(rehash): prevent terminal hang caused by stale or sandbox-blocked lock file by @anupddas in https://github.com/pyenv/pyenv/pull/3469
|
||||
* 3.6.x: Fix verify_* calls by @native-api in https://github.com/pyenv/pyenv/commit/6c0c5cfa9619e4a7a90102d8bee6c771c4739836
|
||||
* Add CPython 3.14.6 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3472
|
||||
* Add CPython 3.13.14 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3473
|
||||
|
||||
## Release v2.7.1
|
||||
* Support 3.9 EOL Pip URL, consolidate tests by @native-api in https://github.com/pyenv/pyenv/pull/3465
|
||||
* Update URLs for PyPy nightly; Remove pypy3.5 and pypy3.7 nightly by @native-api in https://github.com/pyenv/pyenv/pull/3466
|
||||
* Add CPython 3.15.0b2 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3467
|
||||
* init: add --install for shell setup by @macayu17 in https://github.com/pyenv/pyenv/pull/3454
|
||||
* realpath.c: fix obsolete syntax warning by @native-api in https://github.com/pyenv/pyenv/pull/3468
|
||||
|
||||
## Release v2.6.32
|
||||
* Add miniconda3 26.3.2-2, miniforge3 26.3.2-0, 26.3.2-1 by @native-api in https://github.com/pyenv/pyenv/pull/3445
|
||||
* miniforge3 26.1, 26.3, add_miniforge: exclude .pkg installers by @native-api in https://github.com/pyenv/pyenv/pull/3446
|
||||
|
||||
253
README.md
253
README.md
@ -69,6 +69,7 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
|
||||
* [Using Pyenv without shims](#using-pyenv-without-shims)
|
||||
* [Running nested shells from Python-based programs](#running-nested-shells-from-python-based-programs)
|
||||
* [Environment variables](#environment-variables)
|
||||
* [Manual shell setup](#manual-shell-setup)
|
||||
* **[Development](#development)**
|
||||
* [Contributing](#contributing)
|
||||
* [Version History](#version-history)
|
||||
@ -177,134 +178,29 @@ which does install native Windows Python versions.
|
||||
----
|
||||
|
||||
The below setup should work for the vast majority of users for common use cases.
|
||||
See [Advanced configuration](#advanced-configuration) for details and more configuration options.
|
||||
See [Advanced configuration](#advanced-configuration)
|
||||
and specifically [Manual shell setup](#manual-shell-setup) for details and more configuration options.
|
||||
|
||||
If `pyenv` is already on `PATH`, you can configure the relevant shell startup
|
||||
files automatically:
|
||||
To add the suggested setup code to the startup files of the running shell,
|
||||
run `<path/to/pyenv> --install`.
|
||||
Specifically:
|
||||
|
||||
* If you installed Pyenv with the installer script:
|
||||
|
||||
```sh
|
||||
~/.pyenv/bin/pyenv init --install
|
||||
```
|
||||
|
||||
* If you installed Pyenv with Homebrew:
|
||||
|
||||
```sh
|
||||
pyenv init --install
|
||||
```
|
||||
|
||||
If `pyenv` is not on `PATH` yet, run the same command through the `pyenv`
|
||||
executable in your chosen installation directory.
|
||||
|
||||
This uses the same shell detection as `pyenv init`. If a startup file already
|
||||
contains Pyenv-related configuration, the command refuses to edit it; review the
|
||||
file manually and run `pyenv init <shell>` to see the suggested setup.
|
||||
|
||||
For Bash, avoid the automatic `--install` path if your `BASH_ENV` points to
|
||||
`.bashrc`; use the manual Bash instructions below so the `eval "$(pyenv init - bash)"`
|
||||
line only goes in your login startup file.
|
||||
|
||||
#### Bash
|
||||
<details>
|
||||
|
||||
Stock Bash startup files vary widely between distributions in which of them source
|
||||
which, under what circumstances, in what order and what additional configuration they perform.
|
||||
As such, the most reliable way to get Pyenv in all environments is to append Pyenv
|
||||
configuration commands to both `.bashrc` (for interactive shells)
|
||||
and the profile file that Bash would use (for login shells).
|
||||
|
||||
1. First, add the commands to `~/.bashrc` by running the following in your terminal:
|
||||
|
||||
```bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
|
||||
```
|
||||
2. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well.
|
||||
If you have none of these, create a `~/.profile` and add the commands there.
|
||||
|
||||
* to add to `~/.profile`:
|
||||
``` bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.profile
|
||||
```
|
||||
* to add to `~/.bash_profile`:
|
||||
```bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile
|
||||
```
|
||||
|
||||
**Bash warning**: There are some systems where the `BASH_ENV` variable is configured
|
||||
to point to `.bashrc`. On such systems, you should almost certainly put the
|
||||
`eval "$(pyenv init - bash)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you
|
||||
may observe strange behaviour, such as `pyenv` getting into an infinite loop.
|
||||
See [#264](https://github.com/pyenv/pyenv/issues/264) for details.
|
||||
|
||||
</details>
|
||||
|
||||
#### Zsh
|
||||
|
||||
<details>
|
||||
Add Pyenv startup commands to `~/.zshrc` by running the following in your terminal:
|
||||
|
||||
```zsh
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
|
||||
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`.
|
||||
</details>
|
||||
|
||||
#### Fish
|
||||
|
||||
<details>
|
||||
|
||||
1. If you have Fish 3.2.0 or newer, execute this interactively:
|
||||
```fish
|
||||
set -Ux PYENV_ROOT $HOME/.pyenv
|
||||
test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin
|
||||
```
|
||||
|
||||
2. Otherwise, execute the snippet below:
|
||||
```fish
|
||||
set -Ux PYENV_ROOT $HOME/.pyenv
|
||||
test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
|
||||
```
|
||||
|
||||
3. Now, add this to `~/.config/fish/config.fish`:
|
||||
```fish
|
||||
pyenv init - fish | source
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Nushell
|
||||
|
||||
<details>
|
||||
|
||||
Add the following lines to your `config.nu` to add Pyenv and its shims to your `PATH`.
|
||||
Shell integration (completions and subcommands changing the shell's state)
|
||||
isn't currently supported.
|
||||
|
||||
~~~ nu
|
||||
$env.PYENV_ROOT = "~/.pyenv" | path expand
|
||||
if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") {
|
||||
$env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" }
|
||||
$env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
|
||||
~~~
|
||||
|
||||
</details>
|
||||
|
||||
#### Microsoft PowerShell
|
||||
|
||||
<details>
|
||||
|
||||
Add the commands to `$profile.CurrentUserAllHosts` by running the following in your terminal:
|
||||
|
||||
~~~ pwsh
|
||||
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts
|
||||
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {
|
||||
$Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts
|
||||
echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts
|
||||
~~~
|
||||
|
||||
</details>
|
||||
|
||||
### C. Restart your shell
|
||||
----
|
||||
|
||||
@ -815,6 +711,127 @@ name | default | description
|
||||
See also [_Special environment variables_ in Python-Build's README](plugins/python-build/README.md#special-environment-variables)
|
||||
for environment variables that can be used to customize the build.
|
||||
|
||||
|
||||
### Manual shell setup
|
||||
|
||||
Below is the suggested shell setup added to shell startup files by `pyenv init --install`.
|
||||
|
||||
* To automatically install Pyenv for a shell different than the running shell, run
|
||||
|
||||
```sh
|
||||
path/to/pyenv --install <shell executable name>
|
||||
```
|
||||
|
||||
e.g. `~/.pyenv --install bash`.
|
||||
|
||||
#### Bash
|
||||
<details>
|
||||
|
||||
Stock Bash startup files vary widely between distributions in which of them source
|
||||
which, under what circumstances, in what order and what additional configuration they perform.
|
||||
As such, the most reliable way to get Pyenv in all environments is to append Pyenv
|
||||
configuration commands to both `.bashrc` (for interactive shells)
|
||||
and the profile file that Bash would use (for login shells).
|
||||
|
||||
1. First, add the commands to `~/.bashrc` by running the following in your terminal:
|
||||
|
||||
```bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
|
||||
```
|
||||
2. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well.
|
||||
If you have none of these, create a `~/.profile` and add the commands there.
|
||||
|
||||
* to add to `~/.profile`:
|
||||
``` bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.profile
|
||||
```
|
||||
* to add to `~/.bash_profile`:
|
||||
```bash
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile
|
||||
```
|
||||
|
||||
**Bash warning**: There are some systems where the `BASH_ENV` variable is configured
|
||||
to point to `.bashrc`. On such systems, you should almost certainly put the
|
||||
`eval "$(pyenv init - bash)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you
|
||||
may observe strange behaviour, such as `pyenv` getting into an infinite loop.
|
||||
See [#264](https://github.com/pyenv/pyenv/issues/264) for details.
|
||||
|
||||
</details>
|
||||
|
||||
#### Zsh
|
||||
|
||||
<details>
|
||||
Add Pyenv startup commands to `~/.zshrc` by running the following in your terminal:
|
||||
|
||||
```zsh
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
|
||||
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`.
|
||||
</details>
|
||||
|
||||
#### Fish
|
||||
|
||||
<details>
|
||||
|
||||
1. If you have Fish 3.2.0 or newer, execute this interactively:
|
||||
```fish
|
||||
set -Ux PYENV_ROOT $HOME/.pyenv
|
||||
test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin
|
||||
```
|
||||
|
||||
2. Otherwise, execute the snippet below:
|
||||
```fish
|
||||
set -Ux PYENV_ROOT $HOME/.pyenv
|
||||
test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
|
||||
```
|
||||
|
||||
3. Now, add this to `~/.config/fish/config.fish`:
|
||||
```fish
|
||||
pyenv init - fish | source
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Nushell
|
||||
|
||||
<details>
|
||||
|
||||
Add the following lines to your `config.nu` to add Pyenv and its shims to your `PATH`.
|
||||
Shell integration (completions and subcommands changing the shell's state)
|
||||
isn't currently supported.
|
||||
|
||||
~~~ nu
|
||||
$env.PYENV_ROOT = "~/.pyenv" | path expand
|
||||
if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") {
|
||||
$env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" }
|
||||
$env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
|
||||
~~~
|
||||
|
||||
</details>
|
||||
|
||||
#### Microsoft PowerShell
|
||||
|
||||
<details>
|
||||
|
||||
Add the commands to `$profile.CurrentUserAllHosts` by running the following in your terminal:
|
||||
|
||||
~~~ pwsh
|
||||
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts
|
||||
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {
|
||||
$Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts
|
||||
echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts
|
||||
~~~
|
||||
|
||||
</details>
|
||||
|
||||
----
|
||||
|
||||
## Development
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
set -e
|
||||
[ -n "$PYENV_DEBUG" ] && set -x
|
||||
|
||||
version="2.6.32"
|
||||
version="2.7.2"
|
||||
git_revision=""
|
||||
|
||||
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then
|
||||
|
||||
@ -13,15 +13,29 @@ mkdir -p "$SHIM_PATH"
|
||||
declare last_acquire_error
|
||||
|
||||
acquire_lock() {
|
||||
# Ensure only one instance of pyenv-rehash is running at a time by
|
||||
# setting the shell's `noclobber` option and attempting to write to
|
||||
# the prototype shim file.
|
||||
local ret
|
||||
# An old lock file is presumed stale. We assume no healthy rehash takes this long.
|
||||
# The time is picked very small so that a killed rehash holds up new shell sessions
|
||||
# for as little as possible
|
||||
find "$PROTOTYPE_SHIM_PATH" -mmin +2 -exec rm -f {} \; 2>/dev/null || true
|
||||
set -o noclobber
|
||||
# Assuming an old lockfile is stale
|
||||
# Unknown why this happens for some users but this at least unblocks them
|
||||
last_acquire_error="$( { ( echo -n > "$PROTOTYPE_SHIM_PATH"; ) 2>&1 1>&3 3>&1-; } 3>&1)" \
|
||||
|| { find "$PROTOTYPE_SHIM_PATH" -mmin +10 -exec rm -f {} \; ; ret=1; }
|
||||
&& trap release_lock EXIT \
|
||||
|| {
|
||||
# Linux Landlock and MacOS Seatbelt sandbox subsystems return false information in access(),
|
||||
# making -w "$SHIM_PATH" not catch the fact that the shims dir is not writable in this case.
|
||||
# Bash doesn't provide access to errno to check for non-EEXIST error code in `echo >'.
|
||||
# So check for writablity by trying to write to a different file,
|
||||
# in a way that taxes the usual use case as little as possible.
|
||||
if [[ -z $tested_for_other_write_errors ]]; then
|
||||
( t="$(TMPDIR="$SHIM_PATH" mktemp)" && rm "$t" ) \
|
||||
&& tested_for_other_write_errors=1 \
|
||||
|| { echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2
|
||||
set +o noclobber
|
||||
exit 1; }
|
||||
fi
|
||||
ret=1
|
||||
}
|
||||
set +o noclobber
|
||||
[[ -z "${ret}" ]]
|
||||
}
|
||||
@ -32,6 +46,7 @@ remove_prototype_shim() {
|
||||
|
||||
release_lock() {
|
||||
remove_prototype_shim
|
||||
trap - EXIT
|
||||
}
|
||||
|
||||
if [ ! -w "$SHIM_PATH" ]; then
|
||||
@ -45,22 +60,8 @@ PYENV_REHASH_TIMEOUT=${PYENV_REHASH_TIMEOUT:-60}
|
||||
while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )); do
|
||||
if acquire_lock; then
|
||||
acquired=1
|
||||
|
||||
# If we were able to obtain a lock, register a trap to clean up the
|
||||
# prototype shim when the process exits.
|
||||
trap release_lock EXIT
|
||||
|
||||
break
|
||||
else
|
||||
#Landlock sandbox subsystem in the Linux kernel returns false information in access() as of 6.14.0,
|
||||
# making -w "$SHIM_PATH" not catch the fact that the shims dir is not writable in this case.
|
||||
#Bash doesn't provide access to errno to check for non-EEXIST error code in acquire_lock.
|
||||
#So check for writablity by trying to write to a different file,
|
||||
# in a way that taxes the usual use case as little as possible.
|
||||
if [[ -z $tested_for_other_write_errors ]]; then
|
||||
( t="$(TMPDIR="$SHIM_PATH" mktemp)" && rm "$t" ) && tested_for_other_write_errors=1 ||
|
||||
{ echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2; break; }
|
||||
fi
|
||||
# POSIX sleep(1) doesn't provide subsecond precision, but many others do
|
||||
sleep 0.1 2>/dev/null || sleep 1
|
||||
fi
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
# -g/--debug Build a debug version
|
||||
#
|
||||
|
||||
PYTHON_BUILD_VERSION="2.6.32"
|
||||
PYTHON_BUILD_VERSION="2.7.2"
|
||||
|
||||
OLDIFS="$IFS"
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import os.path
|
||||
import pathlib
|
||||
import pprint
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
@ -46,6 +47,14 @@ EXCLUDED_VERSIONS= {
|
||||
here = pathlib.Path(__file__).resolve()
|
||||
OUT_DIR: pathlib.Path = here.parent.parent / "share" / "python-build"
|
||||
|
||||
AUTO_ADD_VERSION_REF_RE = re.compile(
|
||||
r"^(?P<object_id>[0-9a-f]{40,64})\t"
|
||||
r"refs/heads/auto_add_version/(?P<versions>\S+)$"
|
||||
)
|
||||
OPENSSL_RELEASE_TAG_RE = re.compile(
|
||||
r"^openssl-(?P<major>\d+)\.\d+(?:\.\d+)*(?:[a-z]+\d*)?$"
|
||||
)
|
||||
|
||||
T_THUNK=\
|
||||
'''export PYTHON_BUILD_FREE_THREADING=1
|
||||
source "${BASH_SOURCE[0]%t}"
|
||||
@ -83,10 +92,13 @@ def adapt_script(version: packaging.version.Version,
|
||||
url=new_package_url+'#'+new_package_hash,
|
||||
verify_py_suffix=verify_py_suffix)
|
||||
|
||||
elif m:=re.match(r'\s*install_package\s+"(?P<package>openssl-\S+)"\s+'
|
||||
r'"(?P<url>\S+)"\s.*$',
|
||||
elif m:=re.match(r'\s*install_package\s+'
|
||||
r'"(?P<package>openssl-(?P<openssl_major>\d+)\.\S+)"\s+'
|
||||
r'"(?P<url>\S+)"\s.*$',
|
||||
line):
|
||||
item = VersionDirectory.openssl.get_store_latest_release()
|
||||
item = VersionDirectory.openssl.get_store_latest_release(
|
||||
int(m.group('openssl_major'))
|
||||
)
|
||||
|
||||
line = Re.sub_groups(m,
|
||||
package=item.package_name,
|
||||
@ -129,6 +141,8 @@ def add_version(version: packaging.version.Version):
|
||||
return False
|
||||
VersionDirectory.existing.append(_CPythonExistingScriptInfo(version,str(new_path)))
|
||||
|
||||
handle_version_patches(version, previous_version, is_prerelease_upgrade)
|
||||
|
||||
cleanup_prerelease_upgrade(is_prerelease_upgrade, previous_version, version)
|
||||
|
||||
handle_t_thunks(version, previous_version, is_prerelease_upgrade)
|
||||
@ -137,6 +151,51 @@ def add_version(version: packaging.version.Version):
|
||||
return True
|
||||
|
||||
|
||||
def handle_version_patches(
|
||||
version: packaging.version.Version,
|
||||
previous_version: packaging.version.Version,
|
||||
is_prerelease_upgrade: bool)\
|
||||
-> None:
|
||||
if (previous_version.major, previous_version.minor) != (version.major, version.minor):
|
||||
return
|
||||
|
||||
patches_dir = OUT_DIR / "patches"
|
||||
previous_patches = patches_dir / str(previous_version)
|
||||
if not previous_patches.exists():
|
||||
return
|
||||
|
||||
new_patches = patches_dir / str(version)
|
||||
if is_prerelease_upgrade:
|
||||
logger.info(f"Git moving patches from {previous_version} to {version}")
|
||||
subprocess.check_call((
|
||||
"git", "-C", OUT_DIR, "mv",
|
||||
f"patches/{previous_version}",
|
||||
f"patches/{version}",
|
||||
))
|
||||
else:
|
||||
logger.info(f"Copying patches from {previous_version} to {version}")
|
||||
shutil.copytree(previous_patches, new_patches)
|
||||
|
||||
previous_package_patches = new_patches / f"Python-{previous_version}"
|
||||
new_package_patches = new_patches / f"Python-{version}"
|
||||
if is_prerelease_upgrade:
|
||||
subprocess.check_call((
|
||||
"git", "-C", OUT_DIR, "mv",
|
||||
f"patches/{version}/Python-{previous_version}",
|
||||
f"patches/{version}/Python-{version}",
|
||||
))
|
||||
else:
|
||||
previous_package_patches.rename(new_package_patches)
|
||||
|
||||
previous_t_patches = patches_dir / f"{previous_version}t"
|
||||
if previous_t_patches.exists() or previous_t_patches.is_symlink():
|
||||
if is_prerelease_upgrade:
|
||||
previous_t_patches.unlink()
|
||||
(patches_dir / f"{version}t").symlink_to(
|
||||
str(version), target_is_directory=True
|
||||
)
|
||||
|
||||
|
||||
def cleanup_prerelease_upgrade(
|
||||
is_prerelease_upgrade: bool,
|
||||
previous_version: packaging.version.Version,
|
||||
@ -211,7 +270,11 @@ def main():
|
||||
VersionDirectory.available.get_store_available_source_downloads(release, True)
|
||||
del release
|
||||
|
||||
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys())
|
||||
versions_to_add = sorted(
|
||||
VersionDirectory.available.keys()
|
||||
- VersionDirectory.existing.keys()
|
||||
- get_pending_versions()
|
||||
)
|
||||
|
||||
logger.info("Versions to add:\n"+pprint.pformat(versions_to_add))
|
||||
result = False
|
||||
@ -219,6 +282,27 @@ def main():
|
||||
result = add_version(version_to_add) or result
|
||||
return int(not result)
|
||||
|
||||
|
||||
def get_pending_versions() -> typing.Set[packaging.version.Version]:
|
||||
ls_remote = subprocess.check_output(
|
||||
("git", "-C", OUT_DIR, "ls-remote", "origin",
|
||||
"refs/heads/auto_add_version/*"),
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
pending_versions = set()
|
||||
for line in ls_remote.splitlines():
|
||||
match = AUTO_ADD_VERSION_REF_RE.fullmatch(line)
|
||||
if not match:
|
||||
raise ValueError(f"Unexpected git ls-remote output: {line!r}")
|
||||
pending_versions.update(
|
||||
packaging.version.Version(version)
|
||||
for version in match.group("versions").split("_")
|
||||
)
|
||||
return pending_versions
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
@ -440,18 +524,41 @@ class _OpenSSLVersionInfo(typing.NamedTuple):
|
||||
class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.Version]):
|
||||
key_field = "version"
|
||||
|
||||
def get_store_latest_release(self) \
|
||||
def get_store_latest_release(self, major: int) \
|
||||
-> _OpenSSLVersionInfo:
|
||||
if self:
|
||||
#already retrieved
|
||||
return self[max(self.keys())]
|
||||
matching = [
|
||||
release for release in self
|
||||
if release.version.major == major
|
||||
]
|
||||
if matching:
|
||||
return max(matching, key=lambda release: release.version)
|
||||
|
||||
url = "https://api.github.com/repos/openssl/openssl/releases?per_page=100"
|
||||
while url:
|
||||
response = requests.get(url, timeout=30)
|
||||
response.raise_for_status()
|
||||
matching = [
|
||||
release
|
||||
for release in response.json()
|
||||
if not release['draft']
|
||||
and not release['prerelease']
|
||||
and (match := OPENSSL_RELEASE_TAG_RE.fullmatch(
|
||||
release['tag_name']
|
||||
))
|
||||
and int(match.group('major')) == major
|
||||
]
|
||||
if matching:
|
||||
j_release = matching[0]
|
||||
break
|
||||
url = response.links.get('next', {}).get('url')
|
||||
else:
|
||||
raise ValueError(f"No OpenSSL {major}.x release found")
|
||||
|
||||
j = requests.get("https://api.github.com/repos/openssl/openssl/releases/latest", timeout=30).json()
|
||||
# noinspection PyTypeChecker
|
||||
# urlparse can parse str as well as bytes
|
||||
shasum_url = more_itertools.one(
|
||||
asset['browser_download_url']
|
||||
for asset in j['assets']
|
||||
for asset in j_release['assets']
|
||||
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1].endswith('.sha256')
|
||||
)
|
||||
shasum_text = requests.get(shasum_url, timeout=30).text
|
||||
@ -467,7 +574,7 @@ class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.
|
||||
|
||||
package_url = more_itertools.one(
|
||||
asset['browser_download_url']
|
||||
for asset in j['assets']
|
||||
for asset in j_release['assets']
|
||||
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1] == package_filename
|
||||
)
|
||||
|
||||
|
||||
11
plugins/python-build/share/python-build/3.13.14
Normal file
11
plugins/python-build/share/python-build/3.13.14
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-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.13.14" "https://www.python.org/ftp/python/3.13.14/Python-3.13.14.tar.xz#639e43243c620a308f968213df9e00f2f8f62332f7adbaa7a7eeb9783057c690" standard verify_py313 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.13.14" "https://www.python.org/ftp/python/3.13.14/Python-3.13.14.tgz#5ae535a36af0ebca6fca176ecb8197f5db9c1cb8c8f0cd12cdf1787046db1f41" standard verify_py313 copy_python_gdb ensurepip
|
||||
fi
|
||||
2
plugins/python-build/share/python-build/3.13.14t
Normal file
2
plugins/python-build/share/python-build/3.13.14t
Normal file
@ -0,0 +1,2 @@
|
||||
export PYTHON_BUILD_FREE_THREADING=1
|
||||
source "${BASH_SOURCE[0]%t}"
|
||||
11
plugins/python-build/share/python-build/3.14.6
Normal file
11
plugins/python-build/share/python-build/3.14.6
Normal file
@ -0,0 +1,11 @@
|
||||
prefer_openssl3_to_4
|
||||
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.14.6" "https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tar.xz#143b1dddefaec3bd2e21e3b839b34a2b7fb9842272883c576420d605e9f30c63" standard verify_py314 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.14.6" "https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz#74d0d71d0600e477651a077101d6e62d1e2e69b8e992ba18c993dd643b7ba222" standard verify_py314 copy_python_gdb ensurepip
|
||||
fi
|
||||
2
plugins/python-build/share/python-build/3.14.6t
Normal file
2
plugins/python-build/share/python-build/3.14.6t
Normal file
@ -0,0 +1,2 @@
|
||||
export PYTHON_BUILD_FREE_THREADING=1
|
||||
source "${BASH_SOURCE[0]%t}"
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tar.xz#0a833c398ac8cd7c5538f7232d8531afef943c60495c504484f308dac3af40de" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tar.xz#0a833c398ac8cd7c5538f7232d8531afef943c60495c504484f308dac3af40de" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tgz#7034dd7cba98d4f94c74f9edd7345bac71c8814c41672c64d9044fa2f96f334d" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tgz#7034dd7cba98d4f94c74f9edd7345bac71c8814c41672c64d9044fa2f96f334d" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tar.xz#741ebdcbc4e3937a5ff23517dd455ebf7d543ea9fef6f5cf6f46e575d6c4fda4" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tar.xz#741ebdcbc4e3937a5ff23517dd455ebf7d543ea9fef6f5cf6f46e575d6c4fda4" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tgz#96621902f89746fffc22f39749c07da7c2917b232e72352e6837d41850f7b90c" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tgz#96621902f89746fffc22f39749c07da7c2917b232e72352e6837d41850f7b90c" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tar.xz#70953a9b5d6891d92e65d184c3512126a15814bee15e1eff2ddcce04334e9a99" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tar.xz#70953a9b5d6891d92e65d184c3512126a15814bee15e1eff2ddcce04334e9a99" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tgz#12dddbe52385a0f702fb8071e12dcc6b3cb2dde07cd8db3ed60e90d90ab78693" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tgz#12dddbe52385a0f702fb8071e12dcc6b3cb2dde07cd8db3ed60e90d90ab78693" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tar.xz#a47a43a53abb42286a2c11965343ff56711b9e64e8d11bf2c6701a4fb8ce1a0f" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tar.xz#a47a43a53abb42286a2c11965343ff56711b9e64e8d11bf2c6701a4fb8ce1a0f" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tgz#614950d3d54f6e78dac651b49c64cfe2ceefea5af3aff3371a9e4b27a53b2669" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tgz#614950d3d54f6e78dac651b49c64cfe2ceefea5af3aff3371a9e4b27a53b2669" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz#81fd1401a9d66533b0a3e9e3f4ea1c7c6702d57d5b90d659f971e6f1b745f77d" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz#81fd1401a9d66533b0a3e9e3f4ea1c7c6702d57d5b90d659f971e6f1b745f77d" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgz#b7c36f7ed8f7143b2c46153b7332db2227669f583ea0cce753facf549d1a4239" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgz#b7c36f7ed8f7143b2c46153b7332db2227669f583ea0cce753facf549d1a4239" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz#35446241e995773b1bed7d196f4b624dadcadc8429f26282e756b2fb8a351193" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz#35446241e995773b1bed7d196f4b624dadcadc8429f26282e756b2fb8a351193" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz#7f5b1f08b3b0a595387ef6c64c85b1b13b38abef0dd871835ee923262e4f32f0" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz#7f5b1f08b3b0a595387ef6c64c85b1b13b38abef0dd871835ee923262e4f32f0" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
@ -2,7 +2,7 @@ prefer_openssl11
|
||||
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
|
||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||
if has_tar_xz_support; then
|
||||
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz#5e2f5f554e3f8f7f0296f7e73d8600c4e9acbaee6b2555b83206edf5153870da" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz#5e2f5f554e3f8f7f0296f7e73d8600c4e9acbaee6b2555b83206edf5153870da" standard verify_py36 copy_python_gdb ensurepip
|
||||
else
|
||||
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz#47fc92a1dcb946b9ed0abc311d3767b7215c54e655b17fd1d3f9b538195525aa" standard verify_py37 copy_python_gdb ensurepip
|
||||
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz#47fc92a1dcb946b9ed0abc311d3767b7215c54e655b17fd1d3f9b538195525aa" standard verify_py36 copy_python_gdb ensurepip
|
||||
fi
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
plugins/python-build/share/python-build/patches/3.14.6t
Symbolic link
1
plugins/python-build/share/python-build/patches/3.14.6t
Symbolic link
@ -0,0 +1 @@
|
||||
3.14.6
|
||||
@ -38,18 +38,17 @@ pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "stale lockfile is removed" {
|
||||
@test "removes stale lockfile" {
|
||||
mkdir -p "${PYENV_ROOT}/shims"
|
||||
#GNU and BSD `date` support generating relative dates via different syntax
|
||||
# but BusyBox `date` used in Bash Docker images doesn't
|
||||
# A portable code to set mtime to "N minutes ago" is long and unwieldy,
|
||||
# see https://unix.stackexchange.com/questions/806015/portably-set-a-files-time-to-n-minutes-ago
|
||||
# Using a fixed timestamp far in the past is infinitely simpler and good enough for the test
|
||||
touch -t 200001010000.00 "${PYENV_ROOT}/shims/.pyenv-shim"
|
||||
run pyenv-rehash
|
||||
assert_success ""
|
||||
assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ]
|
||||
}
|
||||
|
||||
|
||||
|
||||
@test "creates shims" {
|
||||
create_alt_executable_in_version "2.7" "python"
|
||||
create_alt_executable_in_version "2.7" "fab"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user