mirror of
https://github.com/pyenv/pyenv-virtualenv.git
synced 2026-09-10 15:26:23 -04:00
Compare commits
27 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eda64556af | ||
|
|
37ab83f1b0 | ||
|
|
99d35f201c | ||
|
|
6a832cacbb | ||
|
|
90dfbcad93 | ||
|
|
f046752219 | ||
|
|
72cb35b2b4 | ||
|
|
38f3333f3a | ||
|
|
10c8ace3c3 | ||
|
|
7d9840478c | ||
|
|
bf7d3b0584 | ||
|
|
dd2ad3ee65 | ||
|
|
4785e89a3b | ||
|
|
b83e2c3c83 | ||
|
|
b5c88a7a15 | ||
|
|
64233612fb | ||
|
|
4d37a6e477 | ||
|
|
f5b2602597 | ||
|
|
387f627464 | ||
|
|
4b3f5f8468 | ||
|
|
3057e1549b | ||
|
|
aa9b8e9a5a | ||
|
|
e8c8fd9b84 | ||
|
|
db299cada3 | ||
|
|
c6bb0694bf | ||
|
|
28cd9be54e | ||
|
|
d4c9655e26 |
|
|
@ -1,17 +1,30 @@
|
||||||
Too many issues will kill our team's development velocity, drastically.
|
---
|
||||||
Make sure you have checked all steps below.
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Prerequisite
|
### Prerequisite
|
||||||
* [ ] Make sure your problem is not listed in [the common build problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems).
|
|
||||||
* [ ] Make sure no duplicated issue has already been reported in [the pyenv-virtualenv issues](https://github.com/pyenv/pyenv-virtualenv/issues). You should look in closed issues, too.
|
* [ ] Make sure no duplicated issue has already been reported in [the pyenv-virtualenv issues](https://github.com/pyenv/pyenv-virtualenv/issues). You should look in closed issues, too.
|
||||||
* [ ] Make sure you are not asking us to help solving your specific issue.
|
* [ ] Make sure you are reporting a problem in Pyenv-Virtualenv and not seeking consultation with Pyenv-Virtualenv use.
|
||||||
* GitHub issues is opened mainly for development purposes. If you want to ask someone to help solving your problem, go to some community site like [Gitter](https://gitter.im/yyuu/pyenv), [StackOverflow](https://stackoverflow.com/questions/tagged/pyenv), etc.
|
* GitHub issues are intended mainly for Pyenv-Virtualenv development purposes. If you are seeking help with Pyenv-Virtualenv use, check [Pyenv-Virtualenv documentation](https://github.com/pyenv/pyenv-virtualenv?tab=readme-ov-file#usage), go to a user community site like [Gitter](https://gitter.im/yyuu/pyenv), [StackOverflow](https://stackoverflow.com/questions/tagged/pyenv), etc, or to [Discussions](https://github.com/orgs/pyenv/discussions).
|
||||||
* [ ] Make sure your problem is not derived from packaging (e.g. [Homebrew](https://brew.sh)).
|
* [ ] Make sure your problem is not derived from packaging (e.g. [Homebrew](https://brew.sh)).
|
||||||
* Please refer to the package documentation for the installation issues, etc.
|
* Please refer to the package documentation for the installation issues, etc.
|
||||||
* [ ] Make sure your problem is not derived from other plugins.
|
* [ ] Make sure your problem is not derived from other plugins.
|
||||||
* This repository is maintaining the `pyenv-virtualenv` plugin only. Please refrain from reporting issues of other plugins here.
|
* This repository is maintaining the `pyenv-virtualenv` plugin only. Please refrain from reporting issues of other plugins here.
|
||||||
|
|
||||||
### Description
|
### Describe the bug
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
Do specify what the expected behaviour is if that's not obvious from the bug's nature.
|
||||||
|
|
||||||
|
#### Reproduction steps
|
||||||
|
Listing the commands to run in a new console session and their output is usually sufficient.
|
||||||
|
Please use a Markdown code block (three backticks on a line by themselves before and after the text) to denote a console output excerpt.
|
||||||
|
|
||||||
|
#### Diagnostic details
|
||||||
- [ ] Platform information (e.g. Ubuntu Linux 20.04):
|
- [ ] Platform information (e.g. Ubuntu Linux 20.04):
|
||||||
- [ ] OS architecture (e.g. amd64):
|
- [ ] OS architecture (e.g. amd64):
|
||||||
- [ ] pyenv version:
|
- [ ] pyenv version:
|
||||||
|
|
@ -21,7 +34,7 @@ Make sure you have checked all steps below.
|
||||||
- [ ] Please attach the debug log of a faulty Pyenv invocation as a gist
|
- [ ] Please attach the debug log of a faulty Pyenv invocation as a gist
|
||||||
* If the problem happens in a Pyenv invocation, you can turn on debug logging by setting `PYENV_DEBUG=1`, e.g. `env PYENV_DEBUG=1 pyenv install -v 3.6.4`
|
* If the problem happens in a Pyenv invocation, you can turn on debug logging by setting `PYENV_DEBUG=1`, e.g. `env PYENV_DEBUG=1 pyenv install -v 3.6.4`
|
||||||
* If the problem happens outside of a Pyenv invocation, get the debug log like this:
|
* If the problem happens outside of a Pyenv invocation, get the debug log like this:
|
||||||
```
|
```bash
|
||||||
# for Bash
|
# for Bash
|
||||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||||
# for Zsh
|
# for Zsh
|
||||||
24
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the intended use case**
|
||||||
|
* What your general environment is if it's relevant to the feature request and is not a generic console with a typical Pyenv installation (CI, server with a custom setup, cloud environment, IDE)
|
||||||
|
* What you are trying to achieve
|
||||||
|
* What specifically you are doing for that regarding Pyenv
|
||||||
|
* Where you are stuck
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
[ ] In particular, did you consider [writing a plugin](https://github.com/pyenv/pyenv/blob/master/README.md#pyenv-plugins)? Note that if your plugin has general applicability, you can publish it in the 3rd-party plugin catalog on the Pyenv Wiki as per the link above.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
28
.github/workflows/tests.yml
vendored
28
.github/workflows/tests.yml
vendored
|
|
@ -7,31 +7,13 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- ubuntu-22.04
|
- ubuntu-22.04
|
||||||
- ubuntu-20.04
|
- ubuntu-24.04
|
||||||
- macos-14
|
- macos-14
|
||||||
- macos-13
|
- macos-15
|
||||||
|
- macos-15-intel
|
||||||
|
- macos-26
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# Normally, we would use the superbly maintained...
|
- run: git clone https://github.com/bats-core/bats-core.git --depth=1 -b v1.10.0 bats
|
||||||
# - uses: actions/setup-python@v2
|
|
||||||
# with:
|
|
||||||
# python-version: ${{ matrix.python-version }}
|
|
||||||
# ... but in the repo, we want to test pyenv builds on Ubuntu
|
|
||||||
# - run: |
|
|
||||||
# sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
|
|
||||||
# libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
|
|
||||||
# xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
|
|
||||||
# https://github.com/pyenv/pyenv#installation
|
|
||||||
#- env:
|
|
||||||
# PYENV_ROOT: /home/runner/work/pyenv/pyenv
|
|
||||||
# run: |
|
|
||||||
# echo $PYENV_ROOT
|
|
||||||
# echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
|
||||||
# macos-11 Github Actions env has an old `readlink` and lacks `greadlink` which causes Bats to break
|
|
||||||
- run: |
|
|
||||||
if [[ $RUNNER_OS == "macOS" ]] && [[ $(sw_vers -productVersion | awk -F. '{print $1}') -lt 12 ]]; then
|
|
||||||
brew install coreutils
|
|
||||||
fi
|
|
||||||
- run: git clone https://github.com/bats-core/bats-core.git --depth=1 -b v1.2.0 bats
|
|
||||||
- run: bats/bin/bats --tap test
|
- run: bats/bin/bats --tap test
|
||||||
|
|
|
||||||
108
CHANGELOG.md
108
CHANGELOG.md
|
|
@ -1,17 +1,41 @@
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
#### 1.2.4
|
## v1.4.0
|
||||||
|
* Fix POSIX sh (dash) compatibility in pyenv-virtualenv-init by @chrisolof in https://github.com/pyenv/pyenv-virtualenv/pull/526
|
||||||
|
* Improve performance and output of `pyenv virtualenvs` by @samdoran in https://github.com/pyenv/pyenv-virtualenv/pull/502
|
||||||
|
|
||||||
|
## v1.3.0
|
||||||
|
* CI: cleanup by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/521
|
||||||
|
* CI: tests: use Bats 1.10; support concurrent, out-of-order and multiple-times execution of stub commands; fix race condition between concurrent stubs by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/520
|
||||||
|
* Drastically speed up precommand hook by caching active version to skip redundant `activate` calls by @jakelodwick in https://github.com/pyenv/pyenv-virtualenv/pull/523
|
||||||
|
|
||||||
|
## v1.2.6
|
||||||
|
* Fix changelog and version numbers
|
||||||
|
|
||||||
|
## v1.2.5
|
||||||
|
* Add prompt customization by @jimenezj8 in https://github.com/pyenv/pyenv-virtualenv/pull/476
|
||||||
|
* README: fix and distinguish syntax highlighting in Bash vs Fish snippets by @diericx in https://github.com/pyenv/pyenv-virtualenv/pull/489
|
||||||
|
* Fix pyenv-virtualenv using a different Python version in a conda environment by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/492
|
||||||
|
* Fix confusing activate/deactivate error messages when Pyenv is not installed as a shell function by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/495
|
||||||
|
* Fix errorneously creating a symlink inside env directory if running w… by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/496
|
||||||
|
* Update LICENSE, fix copyright license year by @JasonnnW3000 in https://github.com/pyenv/pyenv-virtualenv/pull/499
|
||||||
|
* docs: add WSL note about core.autocrlf to prevent CRLF issues by @stoneHee99 in https://github.com/pyenv/pyenv-virtualenv/pull/512
|
||||||
|
* docs: fix the link to Pyenv shell setup steps by @cshen-dev in https://github.com/pyenv/pyenv-virtualenv/pull/516
|
||||||
|
* Convert issue template to new Github format by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/519
|
||||||
|
* Prevent loss of data on `virtualenv-delete -f` if the env doesn't exist and the PREFIX envvar is set elsewhere by @SabriRamadanTNG in https://github.com/pyenv/pyenv-virtualenv/pull/518
|
||||||
|
|
||||||
|
## v1.2.4
|
||||||
* Fix failing to detect `-m venv` when "python" is not provided by the distro by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/479
|
* Fix failing to detect `-m venv` when "python" is not provided by the distro by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/479
|
||||||
* README: Remove dollar signs from commands that are meant to be copied by @galonsky in https://github.com/pyenv/pyenv-virtualenv/pull/481
|
* README: Remove dollar signs from commands that are meant to be copied by @galonsky in https://github.com/pyenv/pyenv-virtualenv/pull/481
|
||||||
* Reflect pyenv-latest switch change in 2.4.8 by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/484
|
* Reflect pyenv-latest switch change in 2.4.8 by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/484
|
||||||
|
|
||||||
#### 1.2.3
|
## v1.2.3
|
||||||
* Fix: add `colorize` helper by @silverjam in https://github.com/pyenv/pyenv-virtualenv/pull/470
|
* Fix: add `colorize` helper by @silverjam in https://github.com/pyenv/pyenv-virtualenv/pull/470
|
||||||
* Bump pyenv-virtualenv reporting version to match release by @ushuz in https://github.com/pyenv/pyenv-virtualenv/pull/471
|
* Bump pyenv-virtualenv reporting version to match release by @ushuz in https://github.com/pyenv/pyenv-virtualenv/pull/471
|
||||||
* Add fish prompt changing by @romirk in https://github.com/pyenv/pyenv-virtualenv/pull/475
|
* Add fish prompt changing by @romirk in https://github.com/pyenv/pyenv-virtualenv/pull/475
|
||||||
* Don't activate if a 3rd-party venv is activated over ours by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/478
|
* Don't activate if a 3rd-party venv is activated over ours by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/478
|
||||||
|
|
||||||
#### 1.2.2
|
## v1.2.2
|
||||||
* Prompt removal was never done and is not planned anymore by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/447
|
* Prompt removal was never done and is not planned anymore by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/447
|
||||||
* Update PYENV_VIRTUALENV_VERSION by @jack-mcivor in https://github.com/pyenv/pyenv-virtualenv/pull/449
|
* Update PYENV_VIRTUALENV_VERSION by @jack-mcivor in https://github.com/pyenv/pyenv-virtualenv/pull/449
|
||||||
* Add activate/deactivate hooks by @joshfrench in https://github.com/pyenv/pyenv-virtualenv/pull/452
|
* Add activate/deactivate hooks by @joshfrench in https://github.com/pyenv/pyenv-virtualenv/pull/452
|
||||||
|
|
@ -19,10 +43,10 @@
|
||||||
* Add fish install oneliner by @ElijahLynn in https://github.com/pyenv/pyenv-virtualenv/pull/322
|
* Add fish install oneliner by @ElijahLynn in https://github.com/pyenv/pyenv-virtualenv/pull/322
|
||||||
* Link python*-config into VE by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/460
|
* Link python*-config into VE by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/460
|
||||||
|
|
||||||
#### 1.2.1
|
## v1.2.1
|
||||||
* Support prefixes resolved by pyenv-latest as base version names by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/446
|
* Support prefixes resolved by pyenv-latest as base version names by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/446
|
||||||
|
|
||||||
#### 1.2.0
|
## v1.2.0
|
||||||
* ~/.*rc should be modified instead of ~/.*profile by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/384
|
* ~/.*rc should be modified instead of ~/.*profile by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/384
|
||||||
* Fixes #394 - update pyenv virtualenvs to list virtualenvs start with dot prefixes by @Gauravtalreja1 in https://github.com/pyenv/pyenv-virtualenv/pull/395
|
* Fixes #394 - update pyenv virtualenvs to list virtualenvs start with dot prefixes by @Gauravtalreja1 in https://github.com/pyenv/pyenv-virtualenv/pull/395
|
||||||
* Fix installation steps to allow for Pyenv 2 by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/388
|
* Fix installation steps to allow for Pyenv 2 by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/388
|
||||||
|
|
@ -45,63 +69,63 @@
|
||||||
* Use realpath of scripts to determine relative locations by @andrew-christianson in https://github.com/pyenv/pyenv-virtualenv/pull/308
|
* Use realpath of scripts to determine relative locations by @andrew-christianson in https://github.com/pyenv/pyenv-virtualenv/pull/308
|
||||||
* Shell detect improvements by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/377
|
* Shell detect improvements by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/377
|
||||||
|
|
||||||
#### 1.1.5
|
## v1.1.5
|
||||||
|
|
||||||
* Fix install script (#290, #302)
|
* Fix install script (#290, #302)
|
||||||
|
|
||||||
#### 1.1.4
|
## v1.1.4
|
||||||
|
|
||||||
* Support newer conda (#290)
|
* Support newer conda (#290)
|
||||||
* Prefer `python3.x` executable if available (#206, #282, #296)
|
* Prefer `python3.x` executable if available (#206, #282, #296)
|
||||||
|
|
||||||
#### 1.1.3
|
## v1.1.3
|
||||||
|
|
||||||
* No code changes since 1.1.2
|
* No code changes since 1.1.2
|
||||||
|
|
||||||
#### 1.1.2
|
## v1.1.2
|
||||||
|
|
||||||
* Use custom get-pip URL based on the target version (#253, #254, #255)
|
* Use custom get-pip URL based on the target version (#253, #254, #255)
|
||||||
* Source conda 4.4.4 shell files (#251)
|
* Source conda 4.4.4 shell files (#251)
|
||||||
* Evaluate force flag before testing if venv exists (#232)
|
* Evaluate force flag before testing if venv exists (#232)
|
||||||
|
|
||||||
#### 1.1.1
|
## v1.1.1
|
||||||
|
|
||||||
* Set `CONDA_PREFIX` to make is useable in conda activate/deactivate scripts (#224)
|
* Set `CONDA_PREFIX` to make is useable in conda activate/deactivate scripts (#224)
|
||||||
* Generate `pydoc` executable after creating new virtualenv (#197, #230)
|
* Generate `pydoc` executable after creating new virtualenv (#197, #230)
|
||||||
|
|
||||||
#### 1.1.0
|
## v1.1.0
|
||||||
|
|
||||||
* fish: use "set -gx" instead of "setenv" (#215, #216, #217, #218)
|
* fish: use "set -gx" instead of "setenv" (#215, #216, #217, #218)
|
||||||
|
|
||||||
#### 1.0.0
|
## v1.0.0
|
||||||
|
|
||||||
* Use similar versioning scheme as pyenv; YYYYMMDD -> X.Y.Z
|
* Use similar versioning scheme as pyenv; YYYYMMDD -> X.Y.Z
|
||||||
|
|
||||||
#### 20160716
|
## v20160716
|
||||||
|
|
||||||
* Suppress activate/deactivate messages by default (#169, #170, #171)
|
* Suppress activate/deactivate messages by default (#169, #170, #171)
|
||||||
* Source conda package activate/deactivat scripts if exist (#173)
|
* Source conda package activate/deactivat scripts if exist (#173)
|
||||||
* Use `source` in favor of `.` for `fish` (#175)
|
* Use `source` in favor of `.` for `fish` (#175)
|
||||||
* Use `python -m venv` instead of `pyvenv` due to deprecation of `pyvenv` after 3.6 (#184, #185)
|
* Use `python -m venv` instead of `pyvenv` due to deprecation of `pyvenv` after 3.6 (#184, #185)
|
||||||
|
|
||||||
#### 20160315
|
## v20160315
|
||||||
|
|
||||||
* Evaluate `${PATH}` when outputted code is eval'd. (#154)
|
* Evaluate `${PATH}` when outputted code is eval'd. (#154)
|
||||||
* Set proper `CONDA_DEFAULT_ENV` for shorter name (#160)
|
* Set proper `CONDA_DEFAULT_ENV` for shorter name (#160)
|
||||||
|
|
||||||
#### 20160202
|
## v20160202
|
||||||
|
|
||||||
* Install virtualenv 13.1.2 for CPython/Stackless 3.2.x (yyuu/pyenv#531)
|
* Install virtualenv 13.1.2 for CPython/Stackless 3.2.x (yyuu/pyenv#531)
|
||||||
|
|
||||||
#### 20160112
|
## v20160112
|
||||||
|
|
||||||
* Fix problem with `virtualenv` to look up executables from source version with `--system-site-packages` (#62)
|
* Fix problem with `virtualenv` to look up executables from source version with `--system-site-packages` (#62)
|
||||||
|
|
||||||
#### 20151229
|
## v20151229
|
||||||
|
|
||||||
* Fix `deactivate` error on `fish` (#136)
|
* Fix `deactivate` error on `fish` (#136)
|
||||||
|
|
||||||
#### 20151222
|
## v20151222
|
||||||
|
|
||||||
* Improved interoperability with Anaconda/Miniconda (#103, #106, #107, #108)
|
* Improved interoperability with Anaconda/Miniconda (#103, #106, #107, #108)
|
||||||
* Create `virtualenv` inside `envs` directory of source version, like Anaconda/Miniconda (#103, #107)
|
* Create `virtualenv` inside `envs` directory of source version, like Anaconda/Miniconda (#103, #107)
|
||||||
|
|
@ -111,49 +135,49 @@
|
||||||
* Add `--skip-aliases` to `pyenv virtualenvs` (#120)
|
* Add `--skip-aliases` to `pyenv virtualenvs` (#120)
|
||||||
* Stop showing `version not installed` warning messages in precmd (#49)
|
* Stop showing `version not installed` warning messages in precmd (#49)
|
||||||
|
|
||||||
#### 20151103
|
## v20151103
|
||||||
|
|
||||||
* Passing return value from executed command. (#100)
|
* Passing return value from executed command. (#100)
|
||||||
* Add workaround for commands installed in a virtual environment created by `pyvenv` (#62)
|
* Add workaround for commands installed in a virtual environment created by `pyvenv` (#62)
|
||||||
* init: zsh: prepend hook to `precmd_functions` (#101)
|
* init: zsh: prepend hook to `precmd_functions` (#101)
|
||||||
|
|
||||||
#### 20151006
|
## v20151006
|
||||||
|
|
||||||
* Ignore user's site-packages on ensurepip/get-pip (#89)
|
* Ignore user's site-packages on ensurepip/get-pip (#89)
|
||||||
* Find `python-config` from source version if current version is a virtualenv
|
* Find `python-config` from source version if current version is a virtualenv
|
||||||
* Fix pyenv-virtualenv-init script for fish where command was in string and not being evaluated (#98)
|
* Fix pyenv-virtualenv-init script for fish where command was in string and not being evaluated (#98)
|
||||||
* Add foolproof for `-p` argument. (yyuu/pyenv#98)
|
* Add foolproof for `-p` argument. (yyuu/pyenv#98)
|
||||||
|
|
||||||
#### 20150719
|
## v20150719
|
||||||
|
|
||||||
* Add support for `conda` environments created by Anaconda/Miniconda (#91)
|
* Add support for `conda` environments created by Anaconda/Miniconda (#91)
|
||||||
* Look up commands for original version as well if the environment is created with `--system-site-packages` (#62)
|
* Look up commands for original version as well if the environment is created with `--system-site-packages` (#62)
|
||||||
* Add error message if the source version is not installed (#83)
|
* Add error message if the source version is not installed (#83)
|
||||||
|
|
||||||
#### 20150526
|
## v20150526
|
||||||
|
|
||||||
* Use `typeset -g` with `precmd_functions` (#75)
|
* Use `typeset -g` with `precmd_functions` (#75)
|
||||||
* activate: display setup instructions only with `PYENV_VIRTUALENV_INIT=0` (#78)
|
* activate: display setup instructions only with `PYENV_VIRTUALENV_INIT=0` (#78)
|
||||||
* Ignore failure of pyenv activate (#68)
|
* Ignore failure of pyenv activate (#68)
|
||||||
|
|
||||||
#### 20150119
|
## v20150119
|
||||||
|
|
||||||
* Ignore errors from `pyenv-version-name` since it might fail if there is configuration error (yyuu/pyenv#291)
|
* Ignore errors from `pyenv-version-name` since it might fail if there is configuration error (yyuu/pyenv#291)
|
||||||
* The _shell_ version set in `activate` should be unset in `deactivate` (#61)
|
* The _shell_ version set in `activate` should be unset in `deactivate` (#61)
|
||||||
* Anaconda has `activate` script nevertheless it is not a virtual environment (#65)
|
* Anaconda has `activate` script nevertheless it is not a virtual environment (#65)
|
||||||
|
|
||||||
#### 20141106
|
## v20141106
|
||||||
|
|
||||||
* Stop creating after `ensurepip` since it has done by `ensurepip` itself
|
* Stop creating after `ensurepip` since it has done by `ensurepip` itself
|
||||||
* Suppress some useless warnings from `pyenv virtualenv-init`
|
* Suppress some useless warnings from `pyenv virtualenv-init`
|
||||||
|
|
||||||
#### 20141012
|
## v20141012
|
||||||
|
|
||||||
* Fix warnings from `shellcheck` to improve support for POSIX sh (#40)
|
* Fix warnings from `shellcheck` to improve support for POSIX sh (#40)
|
||||||
* Do not allow whitespace in `VIRTUALENV_NAME` (#44)
|
* Do not allow whitespace in `VIRTUALENV_NAME` (#44)
|
||||||
* Should not persist `PYENV_DEACTIVATE` after automatic deactivation (#47, #48)
|
* Should not persist `PYENV_DEACTIVATE` after automatic deactivation (#47, #48)
|
||||||
|
|
||||||
#### 20140705
|
## v20140705
|
||||||
|
|
||||||
* Display information on auto-(de)?activation
|
* Display information on auto-(de)?activation
|
||||||
* Support manual (de)?activation with auto-activation enabled (#32, #34)
|
* Support manual (de)?activation with auto-activation enabled (#32, #34)
|
||||||
|
|
@ -161,88 +185,88 @@
|
||||||
* Use https://bootstrap.pypa.io/ to install setuptools and pip
|
* Use https://bootstrap.pypa.io/ to install setuptools and pip
|
||||||
* Create backup of original virtualenv within `$(pyenv root)/versions` when `--upgrade`
|
* Create backup of original virtualenv within `$(pyenv root)/versions` when `--upgrade`
|
||||||
|
|
||||||
#### 20140615
|
## v20140615
|
||||||
|
|
||||||
* Fix incompatibility issue of `pyenv activate` and `pyenv deactivate` (#26)
|
* Fix incompatibility issue of `pyenv activate` and `pyenv deactivate` (#26)
|
||||||
* Workaround for the issue with pyenv-which-ext (#26)
|
* Workaround for the issue with pyenv-which-ext (#26)
|
||||||
|
|
||||||
#### 20140614
|
## v20140614
|
||||||
|
|
||||||
* Add `pyenv virtualenv-init` to enable auto-activation feature (#24)
|
* Add `pyenv virtualenv-init` to enable auto-activation feature (#24)
|
||||||
* Create symlinks for executables with version suffix (yyuu/pyenv#182)
|
* Create symlinks for executables with version suffix (yyuu/pyenv#182)
|
||||||
|
|
||||||
#### 20140602
|
## v20140602
|
||||||
|
|
||||||
* Use new style GH raw url to avoid redirects (raw.github.com -> raw.githubusercontent.com)
|
* Use new style GH raw url to avoid redirects (raw.github.com -> raw.githubusercontent.com)
|
||||||
* Repaired virtualenv activation and deactivation for the fish shell (#23)
|
* Repaired virtualenv activation and deactivation for the fish shell (#23)
|
||||||
|
|
||||||
#### 20140421
|
## v20140421
|
||||||
|
|
||||||
* Display error if `pyenv activate` was invoked as a command
|
* Display error if `pyenv activate` was invoked as a command
|
||||||
* Fix completion of `pyenv activate` (#15)
|
* Fix completion of `pyenv activate` (#15)
|
||||||
* Use `virtualenv` instead of `pyvenv` if `-p` has given (yyuu/pyenv#158)
|
* Use `virtualenv` instead of `pyvenv` if `-p` has given (yyuu/pyenv#158)
|
||||||
|
|
||||||
#### 20140123
|
## v20140123
|
||||||
|
|
||||||
* Add `activate` and `deactivate` to make `pyenv-virtualenv` work with [jedi](https://github.com/davidhalter/jedi) (#9)
|
* Add `activate` and `deactivate` to make `pyenv-virtualenv` work with [jedi](https://github.com/davidhalter/jedi) (#9)
|
||||||
* Use `ensurepip` to install `pip` if it is available
|
* Use `ensurepip` to install `pip` if it is available
|
||||||
* Unset `PIP_REQUIRE_VENV` to avoid problem on the installation of `virtualenv` (#10)
|
* Unset `PIP_REQUIRE_VENV` to avoid problem on the installation of `virtualenv` (#10)
|
||||||
* Add tests
|
* Add tests
|
||||||
|
|
||||||
#### 20140110.1
|
## v20140110.1
|
||||||
|
|
||||||
* Fix install script
|
* Fix install script
|
||||||
|
|
||||||
#### 20140110
|
## v20140110
|
||||||
|
|
||||||
* Support environment variables of `EZ_SETUP` and `GET_PIP`.
|
* Support environment variables of `EZ_SETUP` and `GET_PIP`.
|
||||||
* Support a short option `-p` of `virtualenv`.
|
* Support a short option `-p` of `virtualenv`.
|
||||||
|
|
||||||
#### 20131216
|
## v20131216
|
||||||
|
|
||||||
* Use latest release of setuptools and pip if the version not given via environment variables.
|
* Use latest release of setuptools and pip if the version not given via environment variables.
|
||||||
|
|
||||||
#### 20130622
|
## v20130622
|
||||||
|
|
||||||
* Removed bundled `virtualenv.py` script. Now pyenv-virtualenv installs `virtualenv` package into source version and then use it.
|
* Removed bundled `virtualenv.py` script. Now pyenv-virtualenv installs `virtualenv` package into source version and then use it.
|
||||||
* On Python 3.3+, use `pyvenv` as virtualenv command if `virtualenv` is not available.
|
* On Python 3.3+, use `pyvenv` as virtualenv command if `virtualenv` is not available.
|
||||||
* Install setuptools and pip into environments created by `pyvenv`.
|
* Install setuptools and pip into environments created by `pyvenv`.
|
||||||
|
|
||||||
#### 20130614
|
## v20130614
|
||||||
|
|
||||||
* Add `pyenv virtualenvs` to list all virtualenv versions.
|
* Add `pyenv virtualenvs` to list all virtualenv versions.
|
||||||
* *EXPERIMENTAL*: Add `--upgrade` option to re-create virtualenv with migrating packages
|
* *EXPERIMENTAL*: Add `--upgrade` option to re-create virtualenv with migrating packages
|
||||||
|
|
||||||
#### 20130527
|
## v20130527
|
||||||
|
|
||||||
* Remove `python-virtualenv` which was no longer used.
|
* Remove `python-virtualenv` which was no longer used.
|
||||||
* Change the installation path of the `virtualenv.py` script. (`./libexec` -> `./libexec/pyenv-virtualenv/${VIRTUALENV_VERSION}`)
|
* Change the installation path of the `virtualenv.py` script. (`./libexec` -> `./libexec/pyenv-virtualenv/${VIRTUALENV_VERSION}`)
|
||||||
* Download `virtualenv.py` if desired version has not been installed.
|
* Download `virtualenv.py` if desired version has not been installed.
|
||||||
|
|
||||||
#### 20130507
|
## v20130507
|
||||||
|
|
||||||
* Display virtualenv information in `--help` and `--version`
|
* Display virtualenv information in `--help` and `--version`
|
||||||
* Update virtualenv version; 1.8.4 -> 1.9.1
|
* Update virtualenv version; 1.8.4 -> 1.9.1
|
||||||
|
|
||||||
#### 20130307
|
## v20130307
|
||||||
|
|
||||||
* Rename the project; `s/python-virtualenv/pyenv-virtualenv/g`
|
* Rename the project; `s/python-virtualenv/pyenv-virtualenv/g`
|
||||||
* The `pyenv-virtualenv` script is not depending on `python-virtualenv` now.
|
* The `pyenv-virtualenv` script is not depending on `python-virtualenv` now.
|
||||||
`python-virtualenv` will left for compatibility and will not continue for future releases.
|
`python-virtualenv` will left for compatibility and will not continue for future releases.
|
||||||
* Update virtualenv version; 1.8.2 -> 1.8.4
|
* Update virtualenv version; 1.8.2 -> 1.8.4
|
||||||
|
|
||||||
#### 20130218
|
## v20130218
|
||||||
|
|
||||||
* Add pyenv 0.2.x (rbenv 0.4.x) style help messages.
|
* Add pyenv 0.2.x (rbenv 0.4.x) style help messages.
|
||||||
|
|
||||||
#### 20121023
|
## v20121023
|
||||||
|
|
||||||
* Create virtualenv with exact name of python executables.
|
* Create virtualenv with exact name of python executables.
|
||||||
* Changed command-line options of python-virtualenv.
|
* Changed command-line options of python-virtualenv.
|
||||||
First argument should be a path to the python executable.
|
First argument should be a path to the python executable.
|
||||||
* Add install script.
|
* Add install script.
|
||||||
|
|
||||||
#### 20120927
|
## v20120927
|
||||||
|
|
||||||
* Initial public release.
|
* Initial public release.
|
||||||
|
|
||||||
|
|
|
||||||
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2015 Yamashita, Yuu
|
Copyright (c) 2025 Yamashita, Yuu
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
|
||||||
19
README.md
19
README.md
|
|
@ -28,27 +28,33 @@ From inside that directory you can:
|
||||||
- Get the latest development release by running `git pull` to download the
|
- Get the latest development release by running `git pull` to download the
|
||||||
latest changes.
|
latest changes.
|
||||||
|
|
||||||
|
💡 **WSL note:** If you're using WSL, we recommend setting Git to use Unix-style line endings to prevent script execution errors:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git config --global core.autocrlf input
|
||||||
|
```
|
||||||
|
|
||||||
1. **Check out pyenv-virtualenv into plugin directory**
|
1. **Check out pyenv-virtualenv into plugin directory**
|
||||||
|
|
||||||
```sh
|
```bash
|
||||||
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
|
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
|
||||||
```
|
```
|
||||||
|
|
||||||
For the Fish shell:
|
For the Fish shell:
|
||||||
|
|
||||||
```sh
|
```fish
|
||||||
git clone https://github.com/pyenv/pyenv-virtualenv.git (pyenv root)/plugins/pyenv-virtualenv
|
git clone https://github.com/pyenv/pyenv-virtualenv.git (pyenv root)/plugins/pyenv-virtualenv
|
||||||
```
|
```
|
||||||
|
|
||||||
2. (OPTIONAL) **Add `pyenv virtualenv-init` to your shell** to enable auto-activation of virtualenvs. This is entirely optional but pretty useful. See "Activate virtualenv" below.
|
2. (OPTIONAL) **Add `pyenv virtualenv-init` to your shell** to enable auto-activation of virtualenvs. This is entirely optional but pretty useful. See "Activate virtualenv" below.
|
||||||
|
|
||||||
```sh
|
```bash
|
||||||
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
|
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
|
||||||
```
|
```
|
||||||
|
|
||||||
**Fish shell note**: Add this to your `~/.config/fish/config.fish`
|
**Fish shell note**: Add this to your `~/.config/fish/config.fish`
|
||||||
|
|
||||||
```sh
|
```fish
|
||||||
status --is-interactive; and pyenv virtualenv-init - | source
|
status --is-interactive; and pyenv virtualenv-init - | source
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -56,7 +62,7 @@ From inside that directory you can:
|
||||||
|
|
||||||
3. **Restart your shell to enable pyenv-virtualenv**
|
3. **Restart your shell to enable pyenv-virtualenv**
|
||||||
|
|
||||||
```sh
|
```bash
|
||||||
exec "$SHELL"
|
exec "$SHELL"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -82,7 +88,7 @@ brew install --HEAD pyenv-virtualenv
|
||||||
```
|
```
|
||||||
|
|
||||||
After installation, you'll still need to do
|
After installation, you'll still need to do
|
||||||
[Pyenv shell setup steps](https://github.com/pyenv/pyenv#basic-github-checkout)
|
[Pyenv shell setup steps](https://github.com/pyenv/pyenv#b-set-up-your-shell-environment-for-pyenv)
|
||||||
then add
|
then add
|
||||||
```sh
|
```sh
|
||||||
eval "$(pyenv virtualenv-init -)"
|
eval "$(pyenv virtualenv-init -)"
|
||||||
|
|
@ -243,6 +249,7 @@ You can set certain environment variables to control pyenv-virtualenv.
|
||||||
* `PIP_VERSION`, if set and `venv` is preferred
|
* `PIP_VERSION`, if set and `venv` is preferred
|
||||||
over `virtualenv`, install the specified version of pip.
|
over `virtualenv`, install the specified version of pip.
|
||||||
* `PYENV_VIRTUALENV_VERBOSE_ACTIVATE`, if set, shows some verbose outputs on activation and deactivation
|
* `PYENV_VIRTUALENV_VERBOSE_ACTIVATE`, if set, shows some verbose outputs on activation and deactivation
|
||||||
|
* `PYENV_VIRTUALENV_PROMPT`, if set, allows users to customize how `pyenv-virtualenv` modifies their shell prompt. The default prompt ("(venv)") is overwritten with any user-specified text. Specify the location of the virtual environment name with the string `{venv}`. For example, the default prompt string would be `({venv})`.
|
||||||
|
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,8 @@ fi
|
||||||
|
|
||||||
{ printf "\x1B[31;1m"
|
{ printf "\x1B[31;1m"
|
||||||
echo
|
echo
|
||||||
echo "Failed to activate virtualenv."
|
echo "\`pyenv activate' requires Pyenv and Pyenv-Virtualenv to be loaded into your shell."
|
||||||
echo
|
echo "Check your shell configuration and Pyenv and Pyenv-Virtualenv installation instructions."
|
||||||
echo "Perhaps pyenv-virtualenv has not been loaded into your shell properly."
|
|
||||||
echo "Please restart current shell and try again."
|
|
||||||
echo
|
echo
|
||||||
printf "\x1B[0m"
|
printf "\x1B[0m"
|
||||||
} 1>&2
|
} 1>&2
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ set -e
|
||||||
|
|
||||||
{ printf "\x1B[31;1m"
|
{ printf "\x1B[31;1m"
|
||||||
echo
|
echo
|
||||||
echo "Failed to deactivate virtualenv."
|
echo "\`pyenv deactivate' requires Pyenv and Pyenv-Virtualenv to be loaded into your shell."
|
||||||
echo
|
echo "Check your shell configuration and Pyenv and Pyenv-Virtualenv installation instructions."
|
||||||
echo "Perhaps pyenv-virtualenv has not been loaded into your shell properly."
|
|
||||||
echo "Please restart current shell and try again."
|
|
||||||
echo
|
echo
|
||||||
printf "\x1B[0m"
|
printf "\x1B[0m"
|
||||||
} 1>&2
|
} 1>&2
|
||||||
|
|
|
||||||
|
|
@ -262,9 +262,14 @@ EOS
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
|
if [ -z "${PYENV_VIRTUALENV_PROMPT}" ]; then
|
||||||
|
PYENV_VIRTUALENV_PROMPT="(${venv})"
|
||||||
|
else
|
||||||
|
PYENV_VIRTUALENV_PROMPT="${PYENV_VIRTUALENV_PROMPT/\{venv\}/${venv}}"
|
||||||
|
fi
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
export _OLD_VIRTUAL_PS1="\${PS1:-}";
|
export _OLD_VIRTUAL_PS1="\${PS1:-}";
|
||||||
export PS1="(${venv}) \${PS1:-}";
|
export PS1="${PYENV_VIRTUALENV_PROMPT} \${PS1:-}";
|
||||||
EOS
|
EOS
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
# -u/--upgrade Imply --force
|
# -u/--upgrade Imply --force
|
||||||
#
|
#
|
||||||
|
|
||||||
PYENV_VIRTUALENV_VERSION="1.2.4"
|
PYENV_VIRTUALENV_VERSION="1.4.0"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
@ -24,7 +24,7 @@ fi
|
||||||
|
|
||||||
# Provide pyenv completions
|
# Provide pyenv completions
|
||||||
if [ "$1" = "--complete" ]; then
|
if [ "$1" = "--complete" ]; then
|
||||||
exec pyenv-versions --bare
|
exec pyenv-versions --bare --skip-envs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unset PIP_REQUIRE_VENV
|
unset PIP_REQUIRE_VENV
|
||||||
|
|
@ -605,7 +605,13 @@ STATUS=0
|
||||||
mkdir -p "${PYENV_VIRTUALENV_CACHE_PATH}"
|
mkdir -p "${PYENV_VIRTUALENV_CACHE_PATH}"
|
||||||
cd "${PYENV_VIRTUALENV_CACHE_PATH}"
|
cd "${PYENV_VIRTUALENV_CACHE_PATH}"
|
||||||
if [ -n "${USE_CONDA}" ]; then
|
if [ -n "${USE_CONDA}" ]; then
|
||||||
pyenv-exec conda create $QUIET $VERBOSE --name "${VIRTUALENV_PATH##*/}" --yes "${VIRTUALENV_OPTIONS[@]}" python || STATUS="$?"
|
if [ -z "$VIRTUALENV_PYTHON" ]; then
|
||||||
|
#process substitution doesn't seem to work unless it's directly inserted to the command line
|
||||||
|
#if we add it to VIRTUALENV_OPTIONS instead, "broken pipe" happens
|
||||||
|
pyenv-exec conda create $QUIET $VERBOSE --name "${VIRTUALENV_PATH##*/}" --yes "${VIRTUALENV_OPTIONS[@]}" --file <(pyenv-exec conda list python --full-name --export) || STATUS="$?"
|
||||||
|
else
|
||||||
|
pyenv-exec conda create $QUIET $VERBOSE --name "${VIRTUALENV_PATH##*/}" --yes "${VIRTUALENV_OPTIONS[@]}" || STATUS="$?"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
if [ -n "${USE_M_VENV}" ]; then
|
if [ -n "${USE_M_VENV}" ]; then
|
||||||
pyenv-exec "${M_VENV_PYTHON_BIN:-python}" -m venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?"
|
pyenv-exec "${M_VENV_PYTHON_BIN:-python}" -m venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?"
|
||||||
|
|
@ -625,7 +631,8 @@ fi
|
||||||
|
|
||||||
## Create symlink in the `versions` directory for backward compatibility
|
## Create symlink in the `versions` directory for backward compatibility
|
||||||
if [ -d "${VIRTUALENV_PATH}" ] && [ -n "${COMPAT_VIRTUALENV_PATH}" ]; then
|
if [ -d "${VIRTUALENV_PATH}" ] && [ -n "${COMPAT_VIRTUALENV_PATH}" ]; then
|
||||||
ln -fs "${VIRTUALENV_PATH}" "${COMPAT_VIRTUALENV_PATH}"
|
# Overwrite an existing link, can happen if running with -f
|
||||||
|
ln -fsn "${VIRTUALENV_PATH}" "${COMPAT_VIRTUALENV_PATH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e "${VIRTUALENV_PATH}/bin/pydoc" ]; then
|
if [ ! -e "${VIRTUALENV_PATH}/bin/pydoc" ]; then
|
||||||
|
|
|
||||||
|
|
@ -55,26 +55,28 @@ case "$DEFINITION" in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
VERSION_NAME="${DEFINITION##*/}"
|
VERSION_NAME="${DEFINITION##*/}"
|
||||||
COMPAT_PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
# Must initialize because it might be set in the environment
|
||||||
|
ENV_PREFIX=
|
||||||
|
ENV_COMPAT_PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
||||||
|
|
||||||
if [[ "${DEFINITION}" != "${DEFINITION%/envs/*}" ]]; then
|
if [[ "${DEFINITION}" != "${DEFINITION%/envs/*}" ]]; then
|
||||||
PREFIX="${PYENV_ROOT}/versions/${DEFINITION}"
|
ENV_PREFIX="${PYENV_ROOT}/versions/${DEFINITION}"
|
||||||
if [ -L "${COMPAT_PREFIX}" ]; then
|
if [ -L "${ENV_COMPAT_PREFIX}" ]; then
|
||||||
if [[ "${PREFIX}" != "$(resolve_link "${COMPAT_PREFIX}" 2>/dev/null || true)" ]]; then
|
if [[ "${ENV_PREFIX}" != "$(resolve_link "${ENV_COMPAT_PREFIX}" 2>/dev/null || true)" ]]; then
|
||||||
unset COMPAT_PREFIX
|
unset ENV_COMPAT_PREFIX
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ -L "${COMPAT_PREFIX}" ]; then
|
if [ -L "${ENV_COMPAT_PREFIX}" ]; then
|
||||||
PREFIX="$(resolve_link "${COMPAT_PREFIX}" 2>/dev/null || true)"
|
ENV_PREFIX="$(resolve_link "${ENV_COMPAT_PREFIX}" 2>/dev/null || true)"
|
||||||
if [[ "${PREFIX%/*/envs/*}" != "${PYENV_ROOT}/versions" ]]; then
|
if [[ "${ENV_PREFIX%/*/envs/*}" != "${PYENV_ROOT}/versions" ]]; then
|
||||||
echo "pyenv-virtualenv: \`${COMPAT_PREFIX}' is a symlink for unknown location." 1>&2
|
echo "pyenv-virtualenv: \`${ENV_COMPAT_PREFIX}' is a symlink for unknown location." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if pyenv-virtualenv-prefix "${VERSION_NAME}" 1>/dev/null 2>&1; then
|
if pyenv-virtualenv-prefix "${VERSION_NAME}" 1>/dev/null 2>&1; then
|
||||||
PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
ENV_PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
||||||
unset COMPAT_PREFIX
|
unset ENV_COMPAT_PREFIX
|
||||||
elif [ -z "$FORCE" ]; then
|
elif [ -z "$FORCE" ]; then
|
||||||
echo "pyenv-virtualenv: \`${DEFINITION}' is not a virtualenv." 1>&2
|
echo "pyenv-virtualenv: \`${DEFINITION}' is not a virtualenv." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -82,23 +84,25 @@ else
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$FORCE" ]; then
|
if [ ! -d "$ENV_PREFIX" ]; then
|
||||||
if [ ! -d "$PREFIX" ]; then
|
if [ -z "$FORCE" ]; then
|
||||||
echo "pyenv-virtualenv: virtualenv \`$VERSION_NAME' not installed" >&2
|
echo "pyenv-virtualenv: virtualenv \`$VERSION_NAME' not installed" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
read -p "pyenv-virtualenv: remove $PREFIX? (y/N) "
|
if [ -z "$FORCE" ]; then
|
||||||
|
read -p "pyenv-virtualenv: remove $ENV_PREFIX? (y/N) "
|
||||||
case "$REPLY" in
|
case "$REPLY" in
|
||||||
y* | Y* ) ;;
|
y* | Y* ) ;;
|
||||||
* ) exit 1 ;;
|
* ) exit 1 ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d "$PREFIX" ]; then
|
rm -rf "$ENV_PREFIX"
|
||||||
rm -rf "$PREFIX"
|
if [ -L "$ENV_COMPAT_PREFIX" ]; then
|
||||||
if [ -L "$COMPAT_PREFIX" ]; then
|
rm -rf "$ENV_COMPAT_PREFIX"
|
||||||
rm -rf "$COMPAT_PREFIX"
|
|
||||||
fi
|
|
||||||
pyenv-rehash
|
|
||||||
fi
|
fi
|
||||||
|
pyenv-rehash
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,23 @@
|
||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
||||||
|
# Detect stat format for mtime: GNU uses -c %Y, BSD uses -f %m
|
||||||
|
# -L follows symlinks: a symlinked .python-version reflects target changes
|
||||||
|
if stat -L -c %Y / >/dev/null 2>&1; then
|
||||||
|
_stat_fmt="-L -c %Y"
|
||||||
|
else
|
||||||
|
_stat_fmt="-L -f %m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for version-name hooks at init time. Hooks can alter version
|
||||||
|
# resolution in ways the mtime cache cannot track. If present, the hook
|
||||||
|
# falls back to upstream behavior (no caching). Restart shell after
|
||||||
|
# installing or removing pyenv plugins.
|
||||||
|
_has_version_hooks=""
|
||||||
|
if [ -n "$(pyenv hooks version-name 2>/dev/null)" ]; then
|
||||||
|
_has_version_hooks=1
|
||||||
|
fi
|
||||||
|
|
||||||
resolve_link() {
|
resolve_link() {
|
||||||
$(type -p greadlink readlink | head -1) "$1"
|
$(type -p greadlink readlink | head -1) "$1"
|
||||||
}
|
}
|
||||||
|
|
@ -106,57 +123,147 @@ fish )
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
function _pyenv_virtualenv_hook --on-event fish_prompt;
|
function _pyenv_virtualenv_hook --on-event fish_prompt;
|
||||||
set -l ret \$status
|
set -l ret \$status
|
||||||
|
EOS
|
||||||
|
|
||||||
|
if [ -z "$_has_version_hooks" ]; then
|
||||||
|
cat <<EOS
|
||||||
|
if test "\$PYENV_VERSION" = "\$_PYENV_VH_VERSION" \\
|
||||||
|
-a "\$VIRTUAL_ENV" = "\$_PYENV_VH_VENV"
|
||||||
|
if test -n "\$PYENV_VERSION"
|
||||||
|
return \$ret
|
||||||
|
end
|
||||||
|
if test "\$PWD" = "\$_PYENV_VH_PWD" \\
|
||||||
|
-a "(stat ${_stat_fmt} \$_PYENV_VH_PATHS 2>/dev/null)" = "\$_PYENV_VH_MTIMES"
|
||||||
|
return \$ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
EOS
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOS
|
||||||
if [ -n "\$VIRTUAL_ENV" ]
|
if [ -n "\$VIRTUAL_ENV" ]
|
||||||
pyenv activate --quiet; or pyenv deactivate --quiet; or true
|
pyenv activate --quiet; or pyenv deactivate --quiet; or true
|
||||||
else
|
else
|
||||||
pyenv activate --quiet; or true
|
pyenv activate --quiet; or true
|
||||||
end
|
end
|
||||||
|
EOS
|
||||||
|
|
||||||
|
if [ -z "$_has_version_hooks" ]; then
|
||||||
|
cat <<EOS
|
||||||
|
set -g _PYENV_VH_PWD "\$PWD"
|
||||||
|
set -g _PYENV_VH_VERSION "\$PYENV_VERSION"
|
||||||
|
set -g _PYENV_VH_VENV "\$VIRTUAL_ENV"
|
||||||
|
set -l d "\$PWD"
|
||||||
|
set -l _pvh_found_local 0
|
||||||
|
set -g _PYENV_VH_PATHS
|
||||||
|
while true
|
||||||
|
if test -f "\$d/.python-version"; or test -L "\$d/.python-version"
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$d/.python-version"
|
||||||
|
if test -f "\$d/.python-version"
|
||||||
|
set _pvh_found_local 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$d"
|
||||||
|
end
|
||||||
|
test "\$d" = "/"; and break
|
||||||
|
set d (string replace -r '/[^/]*\$' '' -- "\$d")
|
||||||
|
test -z "\$d"; and set d "/"
|
||||||
|
end
|
||||||
|
if test "\$_pvh_found_local" = "0"
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$PYENV_ROOT/version"
|
||||||
|
end
|
||||||
|
set -g _PYENV_VH_MTIMES (stat ${_stat_fmt} \$_PYENV_VH_PATHS 2>/dev/null)
|
||||||
|
EOS
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOS
|
||||||
return \$ret
|
return \$ret
|
||||||
end
|
end
|
||||||
EOS
|
|
||||||
;;
|
|
||||||
ksh )
|
|
||||||
cat <<EOS
|
|
||||||
function _pyenv_virtualenv_hook() {
|
|
||||||
EOS
|
EOS
|
||||||
;;
|
;;
|
||||||
* )
|
|
||||||
|
bash|zsh )
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
_pyenv_virtualenv_hook() {
|
_pyenv_virtualenv_hook() {
|
||||||
EOS
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ "$shell" != "fish" ]]; then
|
|
||||||
cat <<EOS
|
|
||||||
local ret=\$?
|
local ret=\$?
|
||||||
|
EOS
|
||||||
|
|
||||||
|
if [ -z "$_has_version_hooks" ]; then
|
||||||
|
cat <<EOS
|
||||||
|
if [ "\${PYENV_VERSION-}" = "\${_PYENV_VH_VERSION-}" ] \\
|
||||||
|
&& [ "\${VIRTUAL_ENV-}" = "\${_PYENV_VH_VENV-}" ]; then
|
||||||
|
if [ -n "\${PYENV_VERSION-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
if [ "\${PWD}" = "\${_PYENV_VH_PWD-}" ] \\
|
||||||
|
&& [ "\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)" = "\${_PYENV_VH_MTIMES-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
EOS
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOS
|
||||||
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
||||||
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
||||||
else
|
else
|
||||||
eval "\$(pyenv sh-activate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || true)" || true
|
||||||
fi
|
fi
|
||||||
|
EOS
|
||||||
|
|
||||||
|
if [ -z "$_has_version_hooks" ]; then
|
||||||
|
cat <<EOS
|
||||||
|
_PYENV_VH_PWD="\${PWD}"
|
||||||
|
_PYENV_VH_VERSION="\${PYENV_VERSION-}"
|
||||||
|
_PYENV_VH_VENV="\${VIRTUAL_ENV-}"
|
||||||
|
local _pvh_d="\${PWD}" _pvh_found_local=0
|
||||||
|
_PYENV_VH_PATHS=()
|
||||||
|
while :; do
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ] || [ -L "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}/.python-version")
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_pvh_found_local=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}")
|
||||||
|
fi
|
||||||
|
[ "\${_pvh_d}" = "/" ] && break
|
||||||
|
_pvh_d="\${_pvh_d%/*}"
|
||||||
|
[ -z "\${_pvh_d}" ] && _pvh_d="/"
|
||||||
|
done
|
||||||
|
if [ "\${_pvh_found_local}" = "0" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${PYENV_ROOT}/version")
|
||||||
|
fi
|
||||||
|
_PYENV_VH_MTIMES="\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)"
|
||||||
|
EOS
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOS
|
||||||
return \$ret
|
return \$ret
|
||||||
};
|
};
|
||||||
EOS
|
EOS
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case "$shell" in
|
case "$shell" in
|
||||||
bash )
|
bash )
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
if ! [[ "\${PROMPT_COMMAND-}" =~ _pyenv_virtualenv_hook ]]; then
|
if ! [[ "\${PROMPT_COMMAND-}" =~ _pyenv_virtualenv_hook ]]; then
|
||||||
PROMPT_COMMAND="_pyenv_virtualenv_hook;\${PROMPT_COMMAND-}"
|
PROMPT_COMMAND="_pyenv_virtualenv_hook;\${PROMPT_COMMAND-}"
|
||||||
fi
|
fi
|
||||||
EOS
|
EOS
|
||||||
;;
|
;;
|
||||||
zsh )
|
zsh )
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
typeset -g -a precmd_functions
|
typeset -g -a precmd_functions
|
||||||
if [[ -z \$precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then
|
if [[ -z \$precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then
|
||||||
precmd_functions=(_pyenv_virtualenv_hook \$precmd_functions);
|
precmd_functions=(_pyenv_virtualenv_hook \$precmd_functions);
|
||||||
fi
|
fi
|
||||||
EOS
|
EOS
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
# FIXME: what should i do here??
|
# No prompt command support or it's installed elsewhere
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,17 @@ if [ -z "$PYENV_ROOT" ]; then
|
||||||
PYENV_ROOT="${HOME}/.pyenv"
|
PYENV_ROOT="${HOME}/.pyenv"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
OLDIFS="$IFS"
|
||||||
|
IFS=:
|
||||||
if [ -n "$1" ]; then
|
if [ -n "$1" ]; then
|
||||||
versions=($@)
|
# $@ is not affected by IFS
|
||||||
IFS=: PYENV_VERSION="${versions[*]}"
|
versions=("$@")
|
||||||
|
PYENV_VERSION="${versions[*]}"
|
||||||
export PYENV_VERSION
|
export PYENV_VERSION
|
||||||
else
|
else
|
||||||
IFS=: versions=($(pyenv-version-name))
|
versions=($(pyenv-version-name))
|
||||||
fi
|
fi
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
|
||||||
append_virtualenv_prefix() {
|
append_virtualenv_prefix() {
|
||||||
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
|
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
|
||||||
|
|
@ -49,7 +53,18 @@ for version in "${versions[@]}"; do
|
||||||
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
|
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PYENV_PREFIX_PATH="$(pyenv-prefix "${version}")"
|
|
||||||
|
# In the vast majority of cases, there's a direct match and
|
||||||
|
# not spawning `pyenv-prefix' saves about half the invocation time
|
||||||
|
# with a signle argument which accumulates when called repeatedly
|
||||||
|
# (e.g. from `pyenv-virtualenvs').
|
||||||
|
# `pyenv-prefix' also does not have hooks to worry about.
|
||||||
|
# XXX: refactor the test into a shared module?
|
||||||
|
PYENV_PREFIX_PATH="${PYENV_ROOT}/versions/${version}"
|
||||||
|
if [[ ! -d "$PYENV_PREFIX_PATH" ]]; then
|
||||||
|
PYENV_PREFIX_PATH="$(pyenv-prefix "${version}")"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -x "${PYENV_PREFIX_PATH}/bin/python" ]; then
|
if [ -x "${PYENV_PREFIX_PATH}/bin/python" ]; then
|
||||||
if [ -f "${PYENV_PREFIX_PATH}/bin/activate" ]; then
|
if [ -f "${PYENV_PREFIX_PATH}/bin/activate" ]; then
|
||||||
if [ -f "${PYENV_PREFIX_PATH}/bin/conda" ]; then
|
if [ -f "${PYENV_PREFIX_PATH}/bin/conda" ]; then
|
||||||
|
|
@ -94,4 +109,7 @@ for version in "${versions[@]}"; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
IFS=: echo "${VIRTUALENV_PREFIX_PATHS[*]}"
|
OLDIFS="$IFS"
|
||||||
|
IFS=:
|
||||||
|
echo "${VIRTUALENV_PREFIX_PATHS[*]}"
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
|
|
||||||
|
|
@ -6,24 +6,9 @@
|
||||||
# List all virtualenvs found in `$PYENV_ROOT/versions/*' and its `$PYENV_ROOT/versions/envs/*'.
|
# List all virtualenvs found in `$PYENV_ROOT/versions/*' and its `$PYENV_ROOT/versions/envs/*'.
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[[ -n $PYENV_DEBUG ]] && set -x
|
||||||
if [ -L "${BASH_SOURCE}" ]; then
|
|
||||||
READLINK=$(type -p greadlink readlink | head -1)
|
|
||||||
if [ -z "$READLINK" ]; then
|
|
||||||
echo "pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
resolve_link() {
|
|
||||||
$READLINK -f "$1"
|
|
||||||
}
|
|
||||||
script_path=$(resolve_link ${BASH_SOURCE})
|
|
||||||
else
|
|
||||||
script_path=${BASH_SOURCE}
|
|
||||||
fi
|
|
||||||
|
|
||||||
. ${script_path%/*}/../libexec/pyenv-virtualenv-realpath
|
if [[ -z $PYENV_ROOT ]]; then
|
||||||
|
|
||||||
if [ -z "$PYENV_ROOT" ]; then
|
|
||||||
PYENV_ROOT="${HOME}/.pyenv"
|
PYENV_ROOT="${HOME}/.pyenv"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -47,28 +32,26 @@ done
|
||||||
|
|
||||||
versions_dir="${PYENV_ROOT}/versions"
|
versions_dir="${PYENV_ROOT}/versions"
|
||||||
|
|
||||||
if [ -d "$versions_dir" ]; then
|
if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then
|
||||||
versions_dir="$(realpath "$versions_dir")"
|
declare -A current_versions
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$bare" ]; then
|
|
||||||
hit_prefix=""
|
|
||||||
miss_prefix=""
|
|
||||||
current_versions=()
|
|
||||||
unset print_origin
|
|
||||||
include_system=""
|
|
||||||
else
|
else
|
||||||
|
current_versions=()
|
||||||
|
fi
|
||||||
|
if [[ -z $bare ]]; then
|
||||||
hit_prefix="* "
|
hit_prefix="* "
|
||||||
miss_prefix=" "
|
miss_prefix=" "
|
||||||
OLDIFS="$IFS"
|
OLDIFS="$IFS"
|
||||||
IFS=: current_versions=($(pyenv-version-name || true))
|
IFS=:
|
||||||
|
if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then
|
||||||
|
for i in $(pyenv-version-name || true); do
|
||||||
|
current_versions["$i"]="1"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
read -r -a current_versions <<< "$(pyenv-version-name || true)"
|
||||||
|
fi
|
||||||
IFS="$OLDIFS"
|
IFS="$OLDIFS"
|
||||||
print_origin="1"
|
|
||||||
include_system=""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
num_versions=0
|
|
||||||
|
|
||||||
exists() {
|
exists() {
|
||||||
local car="$1"
|
local car="$1"
|
||||||
local cdar
|
local cdar
|
||||||
|
|
@ -82,39 +65,67 @@ exists() {
|
||||||
}
|
}
|
||||||
|
|
||||||
print_version() {
|
print_version() {
|
||||||
if exists "$1" "${current_versions[@]}"; then
|
local version="${1:?}"
|
||||||
echo "${hit_prefix}${1}${print_origin+$2}"
|
if [[ -n $bare ]]; then
|
||||||
else
|
echo "$version"
|
||||||
echo "${miss_prefix}${1}${print_origin+$2}"
|
return
|
||||||
|
fi
|
||||||
|
local path="${2:?}"
|
||||||
|
if [[ -L "$path" ]]; then
|
||||||
|
version_repr="$version --> $(readlink "$path")"
|
||||||
|
else
|
||||||
|
version_repr="$version (created from $(pyenv-virtualenv-prefix "$version" 2>/dev/null))"
|
||||||
|
fi
|
||||||
|
if [[ ${BASH_VERSINFO[0]} -gt 3 && ${current_versions["$1"]} ]] || \
|
||||||
|
{ [[ ${BASH_VERSINFO[0]} -le 3 ]] && exists "$1" "${current_versions[@]}"; }; then
|
||||||
|
echo "${hit_prefix}${version_repr} (set by $(pyenv-version-origin))"
|
||||||
|
else
|
||||||
|
echo "${miss_prefix}${version_repr}"
|
||||||
fi
|
fi
|
||||||
num_versions=$((num_versions + 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shopt -s dotglob
|
shopt -s dotglob
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
for path in "$versions_dir"/*; do
|
version_dir_entries=("$versions_dir"/*)
|
||||||
if [ -d "$path" ]; then
|
venv_dir_entries=("$versions_dir"/*/envs/*)
|
||||||
if [ -n "$skip_aliases" ] && [ -L "$path" ]; then
|
|
||||||
target="$(realpath "$path")"
|
if sort --version-sort </dev/null >/dev/null 2>&1; then
|
||||||
[ "${target%/*/envs/*}" != "$versions_dir" ] || continue
|
# system sort supports version sorting
|
||||||
fi
|
OLDIFS="$IFS"
|
||||||
virtualenv_prefix="$(pyenv-virtualenv-prefix "${path##*/}" 2>/dev/null || true)"
|
IFS='||'
|
||||||
if [ -d "${virtualenv_prefix}" ]; then
|
|
||||||
print_version "${path##*/}" " (created from ${virtualenv_prefix})"
|
read -r -a version_dir_entries <<< "$(
|
||||||
fi
|
printf "%s||" "${version_dir_entries[@]}" |
|
||||||
for venv_path in "${path}/envs/"*; do
|
sort --version-sort
|
||||||
venv="${path##*/}/envs/${venv_path##*/}"
|
)"
|
||||||
virtualenv_prefix="$(pyenv-virtualenv-prefix "${venv}" 2>/dev/null || true)"
|
|
||||||
if [ -d "${virtualenv_prefix}" ]; then
|
read -r -a venv_dir_entries <<< "$(
|
||||||
print_version "${venv}" " (created from ${virtualenv_prefix})"
|
printf "%s||" "${venv_dir_entries[@]}" |
|
||||||
fi
|
sort --version-sort
|
||||||
done
|
)"
|
||||||
|
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for env_path in "${venv_dir_entries[@]}"; do
|
||||||
|
if [[ -d ${env_path} ]]; then
|
||||||
|
print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
for env_path in "${version_dir_entries[@]}"; do
|
||||||
|
if [[ -d ${env_path} ]]; then
|
||||||
|
if [[ -L ${env_path} ]]; then
|
||||||
|
if [[ -z $skip_aliases ]]; then
|
||||||
|
print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}"
|
||||||
|
fi
|
||||||
|
# Mimics the test from pyenv-virtualenv-prefix
|
||||||
|
# XXX: refactor itto a shared module ?
|
||||||
|
elif [[ -f "${env_path}/bin/activate" ]]; then
|
||||||
|
print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
shopt -u dotglob
|
shopt -u dotglob
|
||||||
shopt -u nullglob
|
shopt -u nullglob
|
||||||
|
|
||||||
if [ "$num_versions" -eq 0 ] && [ -n "$include_system" ]; then
|
|
||||||
echo "Warning: no Python virtualenv detected on the system" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ setup() {
|
||||||
unset PYENV_VIRTUALENV_DISABLE_PROMPT
|
unset PYENV_VIRTUALENV_DISABLE_PROMPT
|
||||||
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
|
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
|
||||||
unset VIRTUAL_ENV_DISABLE_PROMPT
|
unset VIRTUAL_ENV_DISABLE_PROMPT
|
||||||
|
unset PYENV_VIRTUALENV_PROMPT
|
||||||
unset _OLD_VIRTUAL_PS1
|
unset _OLD_VIRTUAL_PS1
|
||||||
stub pyenv-hooks "activate : echo"
|
stub pyenv-hooks "activate : echo"
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +45,31 @@ EOS
|
||||||
unstub pyenv-sh-deactivate
|
unstub pyenv-sh-deactivate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "activate virtualenv from current version with custom prompt" {
|
||||||
|
export PYENV_VIRTUALENV_INIT=1
|
||||||
|
|
||||||
|
stub pyenv-version-name "echo venv"
|
||||||
|
stub pyenv-virtualenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
|
||||||
|
stub pyenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
|
||||||
|
stub pyenv-sh-deactivate "--force --quiet : echo deactivated"
|
||||||
|
|
||||||
|
PYENV_SHELL="bash" PYENV_VERSION="venv" PYENV_VIRTUALENV_PROMPT='venv:{venv}' run pyenv-sh-activate
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<EOS
|
||||||
|
deactivated
|
||||||
|
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
|
||||||
|
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
|
||||||
|
export _OLD_VIRTUAL_PS1="\${PS1:-}";
|
||||||
|
export PS1="venv:venv \${PS1:-}";
|
||||||
|
EOS
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
unstub pyenv-virtualenv-prefix
|
||||||
|
unstub pyenv-prefix
|
||||||
|
unstub pyenv-sh-deactivate
|
||||||
|
}
|
||||||
|
|
||||||
@test "activate virtualenv from current version (quiet)" {
|
@test "activate virtualenv from current version (quiet)" {
|
||||||
export PYENV_VIRTUALENV_INIT=1
|
export PYENV_VIRTUALENV_INIT=1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ setup() {
|
||||||
unset PYENV_VIRTUALENV_DISABLE_PROMPT
|
unset PYENV_VIRTUALENV_DISABLE_PROMPT
|
||||||
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
|
unset PYENV_VIRTUAL_ENV_DISABLE_PROMPT
|
||||||
unset VIRTUAL_ENV_DISABLE_PROMPT
|
unset VIRTUAL_ENV_DISABLE_PROMPT
|
||||||
|
unset PYENV_VIRTUALENV_PROMPT
|
||||||
unset _OLD_VIRTUAL_PS1
|
unset _OLD_VIRTUAL_PS1
|
||||||
stub pyenv-hooks "activate : echo"
|
stub pyenv-hooks "activate : echo"
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +54,35 @@ EOS
|
||||||
teardown_conda "anaconda-2.3.0"
|
teardown_conda "anaconda-2.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "activate conda root from current version with custom prompt" {
|
||||||
|
export PYENV_VIRTUALENV_INIT=1
|
||||||
|
|
||||||
|
setup_conda "anaconda-2.3.0"
|
||||||
|
stub pyenv-version-name "echo anaconda-2.3.0"
|
||||||
|
stub pyenv-virtualenv-prefix "anaconda-2.3.0 : echo \"${PYENV_ROOT}/versions/anaconda-2.3.0\""
|
||||||
|
stub pyenv-prefix "anaconda-2.3.0 : echo \"${PYENV_ROOT}/versions/anaconda-2.3.0\""
|
||||||
|
stub pyenv-sh-deactivate "--force --quiet : echo deactivated"
|
||||||
|
|
||||||
|
PYENV_SHELL="bash" PYENV_VERSION="anaconda-2.3.0" PYENV_VIRTUALENV_PROMPT='venv:{venv}' run pyenv-sh-activate
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<EOS
|
||||||
|
deactivated
|
||||||
|
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0";
|
||||||
|
export VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0";
|
||||||
|
export CONDA_DEFAULT_ENV="root";
|
||||||
|
export _OLD_VIRTUAL_PS1="\${PS1:-}";
|
||||||
|
export PS1="venv:anaconda-2.3.0 \${PS1:-}";
|
||||||
|
export CONDA_PREFIX="${TMP}/pyenv/versions/anaconda-2.3.0";
|
||||||
|
EOS
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
unstub pyenv-virtualenv-prefix
|
||||||
|
unstub pyenv-prefix
|
||||||
|
unstub pyenv-sh-deactivate
|
||||||
|
teardown_conda "anaconda-2.3.0"
|
||||||
|
}
|
||||||
|
|
||||||
@test "activate conda root from current version (fish)" {
|
@test "activate conda root from current version (fish)" {
|
||||||
export PYENV_VIRTUALENV_INIT=1
|
export PYENV_VIRTUALENV_INIT=1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ setup() {
|
||||||
@test "display conda root" {
|
@test "display conda root" {
|
||||||
setup_conda "anaconda-2.3.0"
|
setup_conda "anaconda-2.3.0"
|
||||||
stub pyenv-version-name "echo anaconda-2.3.0"
|
stub pyenv-version-name "echo anaconda-2.3.0"
|
||||||
stub pyenv-prefix "anaconda-2.3.0 : echo \"${PYENV_ROOT}/versions/anaconda-2.3.0\""
|
|
||||||
|
|
||||||
PYENV_VERSION="anaconda-2.3.0" run pyenv-virtualenv-prefix
|
PYENV_VERSION="anaconda-2.3.0" run pyenv-virtualenv-prefix
|
||||||
|
|
||||||
|
|
@ -19,14 +18,12 @@ ${PYENV_ROOT}/versions/anaconda-2.3.0
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
teardown_conda "anaconda-2.3.0"
|
teardown_conda "anaconda-2.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display conda env" {
|
@test "display conda env" {
|
||||||
setup_conda "anaconda-2.3.0" "foo"
|
setup_conda "anaconda-2.3.0" "foo"
|
||||||
stub pyenv-version-name "echo anaconda-2.3.0/envs/foo"
|
stub pyenv-version-name "echo anaconda-2.3.0/envs/foo"
|
||||||
stub pyenv-prefix "anaconda-2.3.0/envs/foo : echo \"${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo\""
|
|
||||||
|
|
||||||
PYENV_VERSION="anaconda-2.3.0/envs/foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="anaconda-2.3.0/envs/foo" run pyenv-virtualenv-prefix
|
||||||
|
|
||||||
|
|
@ -36,6 +33,5 @@ ${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
teardown_conda "anaconda-2.3.0" "foo"
|
teardown_conda "anaconda-2.3.0" "foo"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,15 @@ unstub_pyenv() {
|
||||||
stub_pyenv "${PYENV_VERSION}"
|
stub_pyenv "${PYENV_VERSION}"
|
||||||
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-exec "conda * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
stub -N pyenv-exec "conda list * : true"
|
||||||
|
stub -N pyenv-exec "conda create * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
||||||
stub pyenv-exec "python -s -m ensurepip : true"
|
stub pyenv-exec "python -s -m ensurepip : true"
|
||||||
|
|
||||||
run pyenv-virtualenv venv
|
run pyenv-virtualenv venv
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output_wildcards <<OUT
|
||||||
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes python
|
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes --file /dev/fd/*
|
||||||
rehashed
|
rehashed
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
|
|
@ -49,14 +50,14 @@ OUT
|
||||||
stub_pyenv "${PYENV_VERSION}"
|
stub_pyenv "${PYENV_VERSION}"
|
||||||
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-exec "conda * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
stub pyenv-exec "conda create * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
||||||
stub pyenv-exec "python -s -m ensurepip : true"
|
stub pyenv-exec "python -s -m ensurepip : true"
|
||||||
|
|
||||||
run pyenv-virtualenv -p python3.5 venv
|
run pyenv-virtualenv -p python3.5 venv
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes python=3.5 python
|
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes python=3.5
|
||||||
rehashed
|
rehashed
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
|
|
@ -72,14 +73,14 @@ OUT
|
||||||
stub_pyenv "${PYENV_VERSION}"
|
stub_pyenv "${PYENV_VERSION}"
|
||||||
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
stub pyenv-virtualenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
|
||||||
stub pyenv-exec "conda * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
stub pyenv-exec "conda create * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
|
||||||
stub pyenv-exec "python -s -m ensurepip : true"
|
stub pyenv-exec "python -s -m ensurepip : true"
|
||||||
|
|
||||||
run pyenv-virtualenv --python=python3.5 venv
|
run pyenv-virtualenv --python=python3.5 venv
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes python=3.5 python
|
PYENV_VERSION=miniconda3-3.16.0 conda create --name venv --yes python=3.5
|
||||||
rehashed
|
rehashed
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bats
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
load test_helper
|
load test_helper
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ setup() {
|
||||||
export PYENV_ROOT="${TMP}/pyenv"
|
export PYENV_ROOT="${TMP}/pyenv"
|
||||||
export HOOK_PATH="${TMP}/i has hooks"
|
export HOOK_PATH="${TMP}/i has hooks"
|
||||||
mkdir -p "$HOOK_PATH"
|
mkdir -p "$HOOK_PATH"
|
||||||
|
unset PYENV_VIRTUALENV_PROMPT
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "pyenv-virtualenv hooks" {
|
@test "pyenv-virtualenv hooks" {
|
||||||
|
|
|
||||||
126
test/init.bats
126
test/init.bats
|
|
@ -29,22 +29,18 @@ load test_helper
|
||||||
rm -f "${TMP}/script.sh"
|
rm -f "${TMP}/script.sh"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "sh-compatible instructions" {
|
|
||||||
run pyenv-virtualenv-init bash
|
|
||||||
assert [ "$status" -eq 1 ]
|
|
||||||
assert_output_contains 'eval "$(pyenv virtualenv-init -)"'
|
|
||||||
|
|
||||||
run pyenv-virtualenv-init zsh
|
|
||||||
assert [ "$status" -eq 1 ]
|
|
||||||
assert_output_contains 'eval "$(pyenv virtualenv-init -)"'
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fish instructions" {
|
@test "fish instructions" {
|
||||||
run pyenv-virtualenv-init fish
|
run pyenv-virtualenv-init fish
|
||||||
assert [ "$status" -eq 1 ]
|
assert [ "$status" -eq 1 ]
|
||||||
assert_output_contains 'status --is-interactive; and source (pyenv virtualenv-init -|psub)'
|
assert_output_contains 'status --is-interactive; and source (pyenv virtualenv-init -|psub)'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "other shells instructions" {
|
||||||
|
run pyenv-virtualenv-init some_other_sh
|
||||||
|
assert [ "$status" -eq 1 ]
|
||||||
|
assert_output_contains 'eval "$(pyenv virtualenv-init -)"'
|
||||||
|
}
|
||||||
|
|
||||||
@test "outputs bash-specific syntax" {
|
@test "outputs bash-specific syntax" {
|
||||||
export PYENV_VIRTUALENV_ROOT="${TMP}/pyenv/plugins/pyenv-virtualenv"
|
export PYENV_VIRTUALENV_ROOT="${TMP}/pyenv/plugins/pyenv-virtualenv"
|
||||||
run pyenv-virtualenv-init - bash
|
run pyenv-virtualenv-init - bash
|
||||||
|
|
@ -54,11 +50,44 @@ export PATH="${TMP}/pyenv/plugins/pyenv-virtualenv/shims:\${PATH}";
|
||||||
export PYENV_VIRTUALENV_INIT=1;
|
export PYENV_VIRTUALENV_INIT=1;
|
||||||
_pyenv_virtualenv_hook() {
|
_pyenv_virtualenv_hook() {
|
||||||
local ret=\$?
|
local ret=\$?
|
||||||
|
if [ "\${PYENV_VERSION-}" = "\${_PYENV_VH_VERSION-}" ] \\
|
||||||
|
&& [ "\${VIRTUAL_ENV-}" = "\${_PYENV_VH_VENV-}" ]; then
|
||||||
|
if [ -n "\${PYENV_VERSION-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
if [ "\${PWD}" = "\${_PYENV_VH_PWD-}" ] \\
|
||||||
|
&& [ "\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)" = "\${_PYENV_VH_MTIMES-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
||||||
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
||||||
else
|
else
|
||||||
eval "\$(pyenv sh-activate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || true)" || true
|
||||||
fi
|
fi
|
||||||
|
_PYENV_VH_PWD="\${PWD}"
|
||||||
|
_PYENV_VH_VERSION="\${PYENV_VERSION-}"
|
||||||
|
_PYENV_VH_VENV="\${VIRTUAL_ENV-}"
|
||||||
|
local _pvh_d="\${PWD}" _pvh_found_local=0
|
||||||
|
_PYENV_VH_PATHS=()
|
||||||
|
while :; do
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ] || [ -L "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}/.python-version")
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_pvh_found_local=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}")
|
||||||
|
fi
|
||||||
|
[ "\${_pvh_d}" = "/" ] && break
|
||||||
|
_pvh_d="\${_pvh_d%/*}"
|
||||||
|
[ -z "\${_pvh_d}" ] && _pvh_d="/"
|
||||||
|
done
|
||||||
|
if [ "\${_pvh_found_local}" = "0" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${PYENV_ROOT}/version")
|
||||||
|
fi
|
||||||
|
_PYENV_VH_MTIMES="\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)"
|
||||||
return \$ret
|
return \$ret
|
||||||
};
|
};
|
||||||
if ! [[ "\${PROMPT_COMMAND-}" =~ _pyenv_virtualenv_hook ]]; then
|
if ! [[ "\${PROMPT_COMMAND-}" =~ _pyenv_virtualenv_hook ]]; then
|
||||||
|
|
@ -78,11 +107,45 @@ set -gx PATH '${TMP}/pyenv/plugins/pyenv-virtualenv/shims' \$PATH;
|
||||||
set -gx PYENV_VIRTUALENV_INIT 1;
|
set -gx PYENV_VIRTUALENV_INIT 1;
|
||||||
function _pyenv_virtualenv_hook --on-event fish_prompt;
|
function _pyenv_virtualenv_hook --on-event fish_prompt;
|
||||||
set -l ret \$status
|
set -l ret \$status
|
||||||
|
if test "\$PYENV_VERSION" = "\$_PYENV_VH_VERSION" \\
|
||||||
|
-a "\$VIRTUAL_ENV" = "\$_PYENV_VH_VENV"
|
||||||
|
if test -n "\$PYENV_VERSION"
|
||||||
|
return \$ret
|
||||||
|
end
|
||||||
|
if test "\$PWD" = "\$_PYENV_VH_PWD" \\
|
||||||
|
-a "(stat ${_stat_fmt} \$_PYENV_VH_PATHS 2>/dev/null)" = "\$_PYENV_VH_MTIMES"
|
||||||
|
return \$ret
|
||||||
|
end
|
||||||
|
end
|
||||||
if [ -n "\$VIRTUAL_ENV" ]
|
if [ -n "\$VIRTUAL_ENV" ]
|
||||||
pyenv activate --quiet; or pyenv deactivate --quiet; or true
|
pyenv activate --quiet; or pyenv deactivate --quiet; or true
|
||||||
else
|
else
|
||||||
pyenv activate --quiet; or true
|
pyenv activate --quiet; or true
|
||||||
end
|
end
|
||||||
|
set -g _PYENV_VH_PWD "\$PWD"
|
||||||
|
set -g _PYENV_VH_VERSION "\$PYENV_VERSION"
|
||||||
|
set -g _PYENV_VH_VENV "\$VIRTUAL_ENV"
|
||||||
|
set -l d "\$PWD"
|
||||||
|
set -l _pvh_found_local 0
|
||||||
|
set -g _PYENV_VH_PATHS
|
||||||
|
while true
|
||||||
|
if test -f "\$d/.python-version"; or test -L "\$d/.python-version"
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$d/.python-version"
|
||||||
|
if test -f "\$d/.python-version"
|
||||||
|
set _pvh_found_local 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$d"
|
||||||
|
end
|
||||||
|
test "\$d" = "/"; and break
|
||||||
|
set d (string replace -r '/[^/]*\$' '' -- "\$d")
|
||||||
|
test -z "\$d"; and set d "/"
|
||||||
|
end
|
||||||
|
if test "\$_pvh_found_local" = "0"
|
||||||
|
set -g _PYENV_VH_PATHS \$_PYENV_VH_PATHS "\$PYENV_ROOT/version"
|
||||||
|
end
|
||||||
|
set -g _PYENV_VH_MTIMES (stat ${_stat_fmt} \$_PYENV_VH_PATHS 2>/dev/null)
|
||||||
return \$ret
|
return \$ret
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
|
|
@ -97,11 +160,44 @@ export PATH="${TMP}/pyenv/plugins/pyenv-virtualenv/shims:\${PATH}";
|
||||||
export PYENV_VIRTUALENV_INIT=1;
|
export PYENV_VIRTUALENV_INIT=1;
|
||||||
_pyenv_virtualenv_hook() {
|
_pyenv_virtualenv_hook() {
|
||||||
local ret=\$?
|
local ret=\$?
|
||||||
|
if [ "\${PYENV_VERSION-}" = "\${_PYENV_VH_VERSION-}" ] \\
|
||||||
|
&& [ "\${VIRTUAL_ENV-}" = "\${_PYENV_VH_VENV-}" ]; then
|
||||||
|
if [ -n "\${PYENV_VERSION-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
if [ "\${PWD}" = "\${_PYENV_VH_PWD-}" ] \\
|
||||||
|
&& [ "\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)" = "\${_PYENV_VH_MTIMES-}" ]; then
|
||||||
|
return \$ret
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
if [ -n "\${VIRTUAL_ENV-}" ]; then
|
||||||
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true
|
||||||
else
|
else
|
||||||
eval "\$(pyenv sh-activate --quiet || true)" || true
|
eval "\$(pyenv sh-activate --quiet || true)" || true
|
||||||
fi
|
fi
|
||||||
|
_PYENV_VH_PWD="\${PWD}"
|
||||||
|
_PYENV_VH_VERSION="\${PYENV_VERSION-}"
|
||||||
|
_PYENV_VH_VENV="\${VIRTUAL_ENV-}"
|
||||||
|
local _pvh_d="\${PWD}" _pvh_found_local=0
|
||||||
|
_PYENV_VH_PATHS=()
|
||||||
|
while :; do
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ] || [ -L "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}/.python-version")
|
||||||
|
if [ -f "\${_pvh_d}/.python-version" ]; then
|
||||||
|
_pvh_found_local=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_PYENV_VH_PATHS+=("\${_pvh_d}")
|
||||||
|
fi
|
||||||
|
[ "\${_pvh_d}" = "/" ] && break
|
||||||
|
_pvh_d="\${_pvh_d%/*}"
|
||||||
|
[ -z "\${_pvh_d}" ] && _pvh_d="/"
|
||||||
|
done
|
||||||
|
if [ "\${_pvh_found_local}" = "0" ]; then
|
||||||
|
_PYENV_VH_PATHS+=("\${PYENV_ROOT}/version")
|
||||||
|
fi
|
||||||
|
_PYENV_VH_MTIMES="\$(stat ${_stat_fmt} "\${_PYENV_VH_PATHS[@]}" 2>/dev/null)"
|
||||||
return \$ret
|
return \$ret
|
||||||
};
|
};
|
||||||
typeset -g -a precmd_functions
|
typeset -g -a precmd_functions
|
||||||
|
|
@ -110,3 +206,13 @@ if [[ -z \$precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then
|
||||||
fi
|
fi
|
||||||
EOS
|
EOS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "outputs other shells syntax" {
|
||||||
|
export PYENV_VIRTUALENV_ROOT="${TMP}/pyenv/plugins/pyenv-virtualenv"
|
||||||
|
run pyenv-virtualenv-init - some_other_sh
|
||||||
|
assert_success
|
||||||
|
assert_output <<EOS
|
||||||
|
export PATH="${TMP}/pyenv/plugins/pyenv-virtualenv/shims:\${PATH}";
|
||||||
|
export PYENV_VIRTUALENV_INIT=1;
|
||||||
|
EOS
|
||||||
|
}
|
||||||
|
|
@ -12,10 +12,6 @@ create_version() {
|
||||||
chmod +x "${PYENV_ROOT}/versions/$1/bin/python"
|
chmod +x "${PYENV_ROOT}/versions/$1/bin/python"
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_version() {
|
|
||||||
rm -fr "${PYENV_ROOT}/versions/$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
create_virtualenv() {
|
create_virtualenv() {
|
||||||
create_version "$1"
|
create_version "$1"
|
||||||
create_version "${2:-$1}"
|
create_version "${2:-$1}"
|
||||||
|
|
@ -40,11 +36,6 @@ create_virtualenv_pypy() {
|
||||||
touch "${PYENV_ROOT}/versions/$1/bin/activate"
|
touch "${PYENV_ROOT}/versions/$1/bin/activate"
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_virtualenv() {
|
|
||||||
remove_version "$1"
|
|
||||||
remove_version "${2:-$1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
create_m_venv() {
|
create_m_venv() {
|
||||||
create_version "$1"
|
create_version "$1"
|
||||||
create_version "${2:-$1}"
|
create_version "${2:-$1}"
|
||||||
|
|
@ -52,10 +43,6 @@ create_m_venv() {
|
||||||
touch "${PYENV_ROOT}/versions/$1/bin/activate"
|
touch "${PYENV_ROOT}/versions/$1/bin/activate"
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_m_venv() {
|
|
||||||
remove_version "${2:-$1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
create_conda() {
|
create_conda() {
|
||||||
create_version "$1"
|
create_version "$1"
|
||||||
create_version "${2:-$1}"
|
create_version "${2:-$1}"
|
||||||
|
|
@ -66,13 +53,8 @@ create_conda() {
|
||||||
touch "${PYENV_ROOT}/versions/${2:-$1}/bin/activate"
|
touch "${PYENV_ROOT}/versions/${2:-$1}/bin/activate"
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_conda() {
|
|
||||||
remove_version "${2:-$1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "display prefix of virtualenv created by virtualenv" {
|
@test "display prefix of virtualenv created by virtualenv" {
|
||||||
stub pyenv-version-name "echo foo"
|
stub pyenv-version-name "echo foo"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\""
|
|
||||||
create_virtualenv "foo" "2.7.11"
|
create_virtualenv "foo" "2.7.11"
|
||||||
|
|
||||||
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -83,13 +65,10 @@ ${PYENV_ROOT}/versions/2.7.11
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_virtualenv "foo" "2.7.11"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefix of virtualenv created by virtualenv (pypy)" {
|
@test "display prefix of virtualenv created by virtualenv (pypy)" {
|
||||||
stub pyenv-version-name "echo foo"
|
stub pyenv-version-name "echo foo"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\""
|
|
||||||
create_virtualenv_pypy "foo" "pypy-4.0.1"
|
create_virtualenv_pypy "foo" "pypy-4.0.1"
|
||||||
|
|
||||||
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -100,13 +79,10 @@ ${PYENV_ROOT}/versions/pypy-4.0.1
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_virtualenv "foo" "pypy-4.0.1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefix of virtualenv created by virtualenv (jython)" {
|
@test "display prefix of virtualenv created by virtualenv (jython)" {
|
||||||
stub pyenv-version-name "echo foo"
|
stub pyenv-version-name "echo foo"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\""
|
|
||||||
create_virtualenv_jython "foo" "jython-2.7.0"
|
create_virtualenv_jython "foo" "jython-2.7.0"
|
||||||
|
|
||||||
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -117,14 +93,10 @@ ${PYENV_ROOT}/versions/jython-2.7.0
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_virtualenv "foo" "jython-2.7.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefixes of virtualenv created by virtualenv" {
|
@test "display prefixes of virtualenv created by virtualenv" {
|
||||||
stub pyenv-version-name "echo foo:bar"
|
stub pyenv-version-name "echo foo:bar"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\"" \
|
|
||||||
"bar : echo \"${PYENV_ROOT}/versions/bar\""
|
|
||||||
create_virtualenv "foo" "2.7.11"
|
create_virtualenv "foo" "2.7.11"
|
||||||
create_virtualenv "bar" "3.5.1"
|
create_virtualenv "bar" "3.5.1"
|
||||||
|
|
||||||
|
|
@ -136,14 +108,10 @@ ${PYENV_ROOT}/versions/2.7.11:${PYENV_ROOT}/versions/3.5.1
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_virtualenv "foo" "2.7.11"
|
|
||||||
remove_virtualenv "bar" "3.5.1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefix of virtualenv created by venv" {
|
@test "display prefix of virtualenv created by venv" {
|
||||||
stub pyenv-version-name "echo foo"
|
stub pyenv-version-name "echo foo"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\""
|
|
||||||
create_m_venv "foo" "3.3.6"
|
create_m_venv "foo" "3.3.6"
|
||||||
|
|
||||||
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="foo" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -154,14 +122,10 @@ ${PYENV_ROOT}/versions/3.3.6
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_m_venv "foo" "3.3.6"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefixes of virtualenv created by venv" {
|
@test "display prefixes of virtualenv created by venv" {
|
||||||
stub pyenv-version-name "echo foo:bar"
|
stub pyenv-version-name "echo foo:bar"
|
||||||
stub pyenv-prefix "foo : echo \"${PYENV_ROOT}/versions/foo\"" \
|
|
||||||
"bar : echo \"${PYENV_ROOT}/versions/bar\""
|
|
||||||
create_m_venv "foo" "3.3.6"
|
create_m_venv "foo" "3.3.6"
|
||||||
create_m_venv "bar" "3.4.4"
|
create_m_venv "bar" "3.4.4"
|
||||||
|
|
||||||
|
|
@ -173,14 +137,10 @@ ${PYENV_ROOT}/versions/3.3.6:${PYENV_ROOT}/versions/3.4.4
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_m_venv "foo" "3.3.6"
|
|
||||||
remove_m_venv "bar" "3.4.4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "display prefix of virtualenv created by conda" {
|
@test "display prefix of virtualenv created by conda" {
|
||||||
stub pyenv-version-name "echo miniconda3-3.16.0/envs/foo"
|
stub pyenv-version-name "echo miniconda3-3.16.0/envs/foo"
|
||||||
stub pyenv-prefix "miniconda3-3.16.0/envs/foo : echo \"${PYENV_ROOT}/versions/miniconda3-3.16.0/envs/foo\""
|
|
||||||
create_conda "miniconda3-3.16.0/envs/foo" "miniconda3-3.16.0"
|
create_conda "miniconda3-3.16.0/envs/foo" "miniconda3-3.16.0"
|
||||||
|
|
||||||
PYENV_VERSION="miniconda3-3.16.0/envs/foo" run pyenv-virtualenv-prefix
|
PYENV_VERSION="miniconda3-3.16.0/envs/foo" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -191,8 +151,6 @@ ${PYENV_ROOT}/versions/miniconda3-3.16.0/envs/foo
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_conda "miniconda3-3.16.0/envs/foo" "miniconda3-3.16.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "should fail if the version is the system" {
|
@test "should fail if the version is the system" {
|
||||||
|
|
@ -210,7 +168,6 @@ OUT
|
||||||
|
|
||||||
@test "should fail if the version is not a virtualenv" {
|
@test "should fail if the version is not a virtualenv" {
|
||||||
stub pyenv-version-name "echo 3.4.4"
|
stub pyenv-version-name "echo 3.4.4"
|
||||||
stub pyenv-prefix "3.4.4 : echo \"${PYENV_ROOT}/versions/3.4.4\""
|
|
||||||
create_version "3.4.4"
|
create_version "3.4.4"
|
||||||
|
|
||||||
PYENV_VERSION="3.4.4" run pyenv-virtualenv-prefix
|
PYENV_VERSION="3.4.4" run pyenv-virtualenv-prefix
|
||||||
|
|
@ -221,14 +178,10 @@ pyenv-virtualenv: version \`3.4.4' is not a virtualenv
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_version "3.4.4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "should fail if one of the versions is not a virtualenv" {
|
@test "should fail if one of the versions is not a virtualenv" {
|
||||||
stub pyenv-version-name "echo venv33:3.4.4"
|
stub pyenv-version-name "echo venv33:3.4.4"
|
||||||
stub pyenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/venv33\"" \
|
|
||||||
"3.4.4 : echo \"${PYENV_ROOT}/versions/3.4.4\""
|
|
||||||
create_virtualenv "venv33" "3.3.6"
|
create_virtualenv "venv33" "3.3.6"
|
||||||
create_version "3.4.4"
|
create_version "3.4.4"
|
||||||
|
|
||||||
|
|
@ -240,7 +193,22 @@ pyenv-virtualenv: version \`3.4.4' is not a virtualenv
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-prefix
|
|
||||||
remove_virtualenv "venv33" "3.3.6"
|
|
||||||
remove_version "3.4.4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "resolves a version that is not an exact match" {
|
||||||
|
stub pyenv-version-name "echo 3"
|
||||||
|
create_version "3.4.4"
|
||||||
|
|
||||||
|
stub pyenv-prefix "3 : echo \"$PYENV_ROOT/versions/3.4.4\""
|
||||||
|
|
||||||
|
run pyenv-virtualenv-prefix
|
||||||
|
|
||||||
|
assert_failure
|
||||||
|
assert_output <<OUT
|
||||||
|
pyenv-virtualenv: version \`3' is not a virtualenv
|
||||||
|
OUT
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
unstub pyenv-prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
288
test/stubs/stub
288
test/stubs/stub
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
export PS4='+($$:${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
status=0
|
status=0
|
||||||
|
|
@ -6,40 +7,158 @@ program="${0##*/}"
|
||||||
PROGRAM="$(echo "$program" | tr a-z- A-Z_)"
|
PROGRAM="$(echo "$program" | tr a-z- A-Z_)"
|
||||||
[ -n "$TMPDIR" ] || TMPDIR="/tmp"
|
[ -n "$TMPDIR" ] || TMPDIR="/tmp"
|
||||||
|
|
||||||
_STUB_PLAN="${PROGRAM}_STUB_PLAN"
|
STUB_PLAN="${PROGRAM}_STUB_PLAN"
|
||||||
_STUB_RUN="${PROGRAM}_STUB_RUN"
|
STUB_PLAN="${!STUB_PLAN}"
|
||||||
_STUB_INDEX="${PROGRAM}_STUB_INDEX"
|
|
||||||
_STUB_RESULT="${PROGRAM}_STUB_RESULT"
|
|
||||||
_STUB_END="${PROGRAM}_STUB_END"
|
|
||||||
_STUB_LOG="${PROGRAM}_STUB_LOG"
|
|
||||||
|
|
||||||
[ -n "${!_STUB_LOG}" ] || eval "${_STUB_LOG}"="${TMPDIR}/${program}-stub-log"
|
STUB_RUN="${PROGRAM}_STUB_RUN"
|
||||||
if test -z "${!_STUB_END}"; then echo "$program" "$@" >>"${!_STUB_LOG}"; fi
|
STUB_RUN="${!STUB_RUN:-${TMPDIR}/${program}-stub-run}"
|
||||||
|
STUB_INDEX=
|
||||||
|
STUB_RESULT=
|
||||||
|
|
||||||
[ -e "${!_STUB_PLAN}" ] || exit 1
|
STUB_END="${PROGRAM}_STUB_END"
|
||||||
[ -n "${!_STUB_RUN}" ] || eval "${_STUB_RUN}"="${TMPDIR}/${program}-stub-run"
|
STUB_END="${!STUB_END}"
|
||||||
|
|
||||||
|
STUB_LOG="${PROGRAM}_STUB_LOG"
|
||||||
|
STUB_LOG="${!STUB_LOG:-${TMPDIR}/${program}-stub-log}"
|
||||||
|
|
||||||
|
|
||||||
|
STUB_LOCKFILE="${TMPDIR}/${program}-stub.lock"
|
||||||
|
|
||||||
|
release_lock() {
|
||||||
|
rm -f "$STUB_LOCKFILE"
|
||||||
|
trap - EXIT
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_lock() {
|
||||||
|
local start=$SECONDS
|
||||||
|
local acquire_timeout=10
|
||||||
|
local acquired=
|
||||||
|
while (( SECONDS <= start + $acquire_timeout )); do
|
||||||
|
|
||||||
|
( set -o noclobber; echo -n >"$STUB_LOCKFILE" ) 2>/dev/null && acquired=1
|
||||||
|
|
||||||
|
if [[ -n $acquired ]]; then
|
||||||
|
trap release_lock EXIT
|
||||||
|
break
|
||||||
|
else
|
||||||
|
# POSIX sleep(1) doesn't provide subsecond precision, but many others do
|
||||||
|
sleep 0.1 2>/dev/null || sleep 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -z $acquired ]]; then
|
||||||
|
echo "$0: error: could not acquire stub lock \`$STUB_LOCKFILE' in ${acquire_timeout} seconds" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_lock
|
||||||
|
|
||||||
|
if [[ -z $STUB_END ]]; then echo "$program" "$@" >>"$STUB_LOG"; fi
|
||||||
|
|
||||||
|
[[ -e $STUB_PLAN ]] || exit 1
|
||||||
|
|
||||||
# Initialize or load the stub run information.
|
# Initialize or load the stub run information.
|
||||||
eval "${_STUB_INDEX}"=1
|
read_runfile() {
|
||||||
eval "${_STUB_RESULT}"=0
|
if [[ -e $STUB_RUN ]]; then source "$STUB_RUN"; fi
|
||||||
if test -e "${!_STUB_RUN}"; then source "${!_STUB_RUN}"; fi
|
}
|
||||||
|
write_runfile() {
|
||||||
|
{
|
||||||
|
local i
|
||||||
|
echo "STUB_INDEX=$STUB_INDEX"
|
||||||
|
echo "STUB_RESULT=$STUB_RESULT"
|
||||||
|
echo "STUB_RUNCOUNTS=()"
|
||||||
|
for i in ${!STUB_RUNCOUNTS[@]}; do
|
||||||
|
echo "STUB_RUNCOUNTS[$i]=${STUB_RUNCOUNTS[$i]}"
|
||||||
|
done
|
||||||
|
} > "$STUB_RUN"
|
||||||
|
}
|
||||||
|
update_runfile_index() {
|
||||||
|
( STUB_INDEX=$((STUB_INDEX + 1))
|
||||||
|
write_runfile
|
||||||
|
)
|
||||||
|
}
|
||||||
|
update_runfile_result() {
|
||||||
|
(
|
||||||
|
# Another stubs may have run while we were running payload
|
||||||
|
# So we need to merge possible state changes
|
||||||
|
local our_result="$STUB_RESULT"
|
||||||
|
local -a our_runcounts
|
||||||
|
array_copy STUB_RUNCOUNTS our_runcounts
|
||||||
|
|
||||||
|
read_runfile
|
||||||
|
|
||||||
|
# merge our match_result and their match_result, with failure taking precedence
|
||||||
|
STUB_RESULT=$(( our_result | STUB_RESULT ))
|
||||||
|
|
||||||
|
# 3-way merge STUB_RUNCOUNTS (their changes),
|
||||||
|
# our_runcounts (our changes) and initial_runcounts (base)
|
||||||
|
local i
|
||||||
|
for i in $(printf '%s\n' ${!STUB_RUNCOUNTS[@]} ${!our_runcounts[@]} | sort -u); do
|
||||||
|
STUB_RUNCOUNTS[$i]=$((STUB_RUNCOUNTS[i] + our_runcounts[i] - initial_runcounts[i]))
|
||||||
|
done
|
||||||
|
|
||||||
|
write_runfile
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
array_copy() {
|
||||||
|
#`declare -p' is supposed to produce "declare -a src=([index]="value" <etc>)"
|
||||||
|
local data="$(declare -p ${1:?})"
|
||||||
|
local dest="${2:?}"
|
||||||
|
# Bash 5 dumps empty arrays as "declare -a arr"
|
||||||
|
if [[ $data != *=* ]]; then
|
||||||
|
data="()";
|
||||||
|
else
|
||||||
|
data="${data#*=}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bash 3 and MacPorts version of Bash 5 dump arrays in single quotes "declare -a arr='()'"
|
||||||
|
# but arr='(<value>)' createss "([0]='<value>')" rather than duplicate the array
|
||||||
|
if [[ ${data:0:1} == "'" && ${data:${#data}-1:1} == "'" ]]; then
|
||||||
|
data="${data:1:${#data}-2}"
|
||||||
|
fi
|
||||||
|
eval "$dest=$data"
|
||||||
|
}
|
||||||
|
|
||||||
# Loop over each line in the plan.
|
STUB_INDEX=1
|
||||||
index=0
|
STUB_RESULT=0
|
||||||
while IFS= read -r line; do
|
declare -a STUB_RUNCOUNTS
|
||||||
index=$(($index + 1))
|
read_runfile
|
||||||
|
declare -a initial_runcounts
|
||||||
if [ -z "${!_STUB_END}" ] && [ $index -eq "${!_STUB_INDEX}" ]; then
|
array_copy STUB_RUNCOUNTS initial_runcounts
|
||||||
# We found the plan line we're interested in.
|
|
||||||
# Start off by assuming success.
|
|
||||||
result=0
|
|
||||||
|
|
||||||
|
# ${PROGRAM}_STUB_END envvar is set externally to trigger verification mode for `unstub'
|
||||||
|
# Execution mode
|
||||||
|
if [[ -z $STUB_END ]]; then
|
||||||
|
|
||||||
|
# Loop over each line in the plan.
|
||||||
|
regular_command_index=0
|
||||||
|
no_order_command_index=0
|
||||||
|
match_result=1
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line_flags="${line%% *}"
|
||||||
|
line="${line#${line_flags} }"
|
||||||
|
line_flag_no_order="$(if [[ $line_flags == N ]]; then echo 1; fi)"
|
||||||
|
line_flag_multiple="$(if [[ $line_flags == M ]]; then echo 1; fi)"
|
||||||
|
line_flag_regular="$(if [[ $line_flags == - ]]; then echo 1; fi)"
|
||||||
|
unset line_flags
|
||||||
|
|
||||||
|
# Go through the plan until a match is found.
|
||||||
|
# For regular commands, only check the next command by index.
|
||||||
|
# Also keep track of no-order commands for the purpose of run count tracking
|
||||||
|
if [[ -n $line_flag_regular ]]; then
|
||||||
|
regular_command_index=$(($regular_command_index + 1))
|
||||||
|
if [[ $regular_command_index -ne $STUB_INDEX ]]; then
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
no_order_command_index=$(($no_order_command_index + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
# Split the line into an array of arguments to
|
# Split the line into an array of arguments to
|
||||||
# match and a command to run to produce output.
|
# match and a command to run to produce output.
|
||||||
command=" $line"
|
command=" $line"
|
||||||
if [ "$command" != "${command/ : }" ]; then
|
if [[ $command == *" : "* ]]; then
|
||||||
patterns="${command%% : *}"
|
patterns="${command%% : *}"
|
||||||
command="${command#* : }"
|
command="${command#* : }"
|
||||||
fi
|
fi
|
||||||
|
|
@ -54,67 +173,110 @@ while IFS= read -r line; do
|
||||||
|
|
||||||
# Match the expected argument patterns to actual
|
# Match the expected argument patterns to actual
|
||||||
# arguments.
|
# arguments.
|
||||||
|
match_result=0
|
||||||
for (( i=0; i<${#patterns[@]}; i++ )); do
|
for (( i=0; i<${#patterns[@]}; i++ )); do
|
||||||
pattern="${patterns[$i]}"
|
pattern="${patterns[$i]}"
|
||||||
argument="${arguments[$i]}"
|
argument="${arguments[$i]}"
|
||||||
|
|
||||||
case "$argument" in
|
case "$argument" in
|
||||||
$pattern ) ;;
|
$pattern ) ;;
|
||||||
* ) result=1 ;;
|
* ) match_result=1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# If the arguments matched, evaluate the command
|
# If the arguments matched, evaluate the command
|
||||||
# in a subshell. Otherwise, log the failure.
|
# in a subshell. Otherwise, log the failure.
|
||||||
if [ $result -eq 0 ] ; then
|
if [ $match_result -eq 0 ] ; then
|
||||||
set +e
|
|
||||||
( eval "$command" )
|
# If this is a regular command, push the regular command index for the next stub invocation
|
||||||
status="$?"
|
if [[ -n $line_flag_regular ]]; then
|
||||||
set -e
|
update_runfile_index
|
||||||
else
|
else
|
||||||
eval "${_STUB_RESULT}"=1
|
STUB_RUNCOUNTS[$no_order_command_index]=$((STUB_RUNCOUNTS[no_order_command_index]+1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Release the lock while running the payload to allow another `stub'
|
||||||
|
# of the same program to run concurrently (e.g. in a pipeline).
|
||||||
|
release_lock
|
||||||
|
|
||||||
|
( eval "$command" ) && status="$?" || status="$?"
|
||||||
|
|
||||||
|
break
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
done < "${!_STUB_PLAN}"
|
done < "$STUB_PLAN"
|
||||||
|
|
||||||
|
#If we never matched anything, we failed.
|
||||||
if [ -n "${!_STUB_END}" ]; then
|
if [[ $match_result -eq 1 ]]; then
|
||||||
# If the number of lines in the plan is larger than
|
STUB_RESULT=1
|
||||||
# the requested index, we failed.
|
|
||||||
if [ $index -ge "${!_STUB_INDEX}" ]; then
|
#This also means that we never released the lock
|
||||||
eval "${_STUB_RESULT}"=1
|
# before running the payload
|
||||||
|
else
|
||||||
|
acquire_lock
|
||||||
fi
|
fi
|
||||||
if [ "${!_STUB_RESULT}" -ne 0 ]; then
|
# Write out the match_result information.
|
||||||
|
update_runfile_result
|
||||||
|
release_lock
|
||||||
|
|
||||||
|
exit "$status"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verification mode (`unstub')
|
||||||
|
if [[ -n $STUB_END ]]; then
|
||||||
|
|
||||||
|
# `unstub' is supposed to run after any stubs are finished
|
||||||
|
release_lock
|
||||||
|
|
||||||
|
# If the number of regular commands in the plan is larger than
|
||||||
|
# the final regular_command_index, we failed.
|
||||||
|
if [[ $(grep -Ee '^-' "$STUB_PLAN" | wc -l ) -ge $STUB_INDEX ]]; then
|
||||||
|
STUB_RESULT=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no-order commands weren't executed exactly once
|
||||||
|
# and multiple-times commands at least once, we failed.
|
||||||
|
no_order_command_index=0
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line_flags="${line%% *}"
|
||||||
|
line="${line#${line_flags} }"
|
||||||
|
line_flag_no_order="$(if [[ $line_flags == N ]]; then echo 1; fi)"
|
||||||
|
line_flag_multiple="$(if [[ $line_flags == M ]]; then echo 1; fi)"
|
||||||
|
line_flag_regular="$(if [[ $line_flags == - ]]; then echo 1; fi)"
|
||||||
|
unset line_flags
|
||||||
|
|
||||||
|
if [[ -z $line_flag_regular ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
no_order_command_index=$((no_order_command_index + 1))
|
||||||
|
|
||||||
|
if [[ ( -n $line_flag_no_order && \
|
||||||
|
(( STUB_RUNCOUNTS[no_order_command_index] != 1 )) ) \
|
||||||
|
|| \
|
||||||
|
( -n $line_flag_multiple && \
|
||||||
|
(( STUB_RUNCOUNTS[no_order_command_index] < 1 )) ) ]]
|
||||||
|
then
|
||||||
|
STUB_RESULT=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
done < "$STUB_PLAN"
|
||||||
|
|
||||||
|
if [[ $STUB_RESULT -ne 0 ]]; then
|
||||||
{
|
{
|
||||||
echo "index: $index; stub index: ${!_STUB_INDEX}"
|
|
||||||
echo "plan:"
|
echo "plan:"
|
||||||
cat "${!_STUB_PLAN}" || true
|
cat "$STUB_PLAN" || true
|
||||||
echo "run:"
|
|
||||||
cat "${!_STUB_RUN}" || true
|
|
||||||
echo "log:"
|
echo "log:"
|
||||||
cat "${!_STUB_LOG}" || true
|
cat "$STUB_LOG" || true
|
||||||
} >&2
|
} >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean up the run file.
|
# Clean up the run file.
|
||||||
rm -f "${!_STUB_RUN}"
|
rm -f "$STUB_RUN"
|
||||||
rm -f "${!_STUB_LOG}"
|
rm -f "$STUB_LOG"
|
||||||
|
|
||||||
# Return the result.
|
# Return the run result.
|
||||||
exit "${!_STUB_RESULT}"
|
exit "$STUB_RESULT"
|
||||||
|
|
||||||
else
|
|
||||||
# If the requested index is larger than the number
|
|
||||||
# of lines in the plan file, we failed.
|
|
||||||
if [ "${!_STUB_INDEX}" -gt $index ]; then
|
|
||||||
eval "${_STUB_RESULT}"=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Write out the run information.
|
|
||||||
{ echo "${_STUB_INDEX}=$((${!_STUB_INDEX} + 1))"
|
|
||||||
echo "${_STUB_RESULT}=${!_STUB_RESULT}"
|
|
||||||
} > "${!_STUB_RUN}"
|
|
||||||
|
|
||||||
exit "$status"
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
export TMP="$BATS_TEST_DIRNAME/tmp"
|
export TMP="$BATS_TEST_DIRNAME/tmp"
|
||||||
|
|
||||||
PATH=/usr/bin:/usr/sbin:/bin/:/sbin
|
# Detect stat format for mtime: GNU uses -c %Y, BSD uses -f %m
|
||||||
|
# Must match the detection in bin/pyenv-virtualenv-init
|
||||||
|
if stat -L -c %Y / >/dev/null 2>&1; then
|
||||||
|
_stat_fmt="-L -c %Y"
|
||||||
|
else
|
||||||
|
_stat_fmt="-L -f %m"
|
||||||
|
fi
|
||||||
|
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||||
|
|
||||||
|
PATH=/usr/bin:/usr/sbin:/bin:/sbin
|
||||||
PATH="$BATS_TEST_DIRNAME/../bin:$PATH"
|
PATH="$BATS_TEST_DIRNAME/../bin:$PATH"
|
||||||
PATH="$TMP/bin:$PATH"
|
PATH="$TMP/bin:$PATH"
|
||||||
export PATH
|
export PATH
|
||||||
|
|
@ -10,6 +19,35 @@ teardown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
stub() {
|
stub() {
|
||||||
|
local FLAG_NO_ORDER=
|
||||||
|
local FLAG_MULTIPLE=
|
||||||
|
while (($#)); do
|
||||||
|
case "$1" in
|
||||||
|
-N|--no-order)
|
||||||
|
FLAG_NO_ORDER=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-M|--multiple)
|
||||||
|
FLAG_MULTIPLE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "stub: unrecognized switch: $arg" >$2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local FLAGS=-
|
||||||
|
if [[ -n $FLAG_MULTIPLE ]]; then
|
||||||
|
FLAGS=M
|
||||||
|
elif [[ -n $FLAG_NO_ORDER ]]; then
|
||||||
|
FLAGS=N
|
||||||
|
fi
|
||||||
|
|
||||||
local program="$1"
|
local program="$1"
|
||||||
local prefix="$(echo "$program" | tr a-z- A-Z_)"
|
local prefix="$(echo "$program" | tr a-z- A-Z_)"
|
||||||
shift
|
shift
|
||||||
|
|
@ -23,7 +61,9 @@ stub() {
|
||||||
ln -sf "${BATS_TEST_DIRNAME}/stubs/stub" "${TMP}/bin/${program}"
|
ln -sf "${BATS_TEST_DIRNAME}/stubs/stub" "${TMP}/bin/${program}"
|
||||||
|
|
||||||
touch "${TMP}/${program}-stub-plan"
|
touch "${TMP}/${program}-stub-plan"
|
||||||
for arg in "$@"; do printf "%s\n" "$arg" >> "${TMP}/${program}-stub-plan"; done
|
for arg in "$@"; do
|
||||||
|
echo "$FLAGS" "$arg" >> "${TMP}/${program}-stub-plan"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
unstub() {
|
unstub() {
|
||||||
|
|
@ -83,6 +123,16 @@ assert_equal() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal_wildcards() {
|
||||||
|
if [[ $1 != $2 ]]; then
|
||||||
|
{ echo "expected:"
|
||||||
|
echo "$2"
|
||||||
|
echo "actual:"
|
||||||
|
echo "$1"
|
||||||
|
} | flunk
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
assert_output() {
|
assert_output() {
|
||||||
local expected
|
local expected
|
||||||
if [ $# -eq 0 ]; then expected="$(cat -)"
|
if [ $# -eq 0 ]; then expected="$(cat -)"
|
||||||
|
|
@ -91,6 +141,14 @@ assert_output() {
|
||||||
assert_equal "$expected" "$output"
|
assert_equal "$expected" "$output"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_output_wildcards() {
|
||||||
|
local expected
|
||||||
|
if [ $# -eq 0 ]; then expected="$(cat -)"
|
||||||
|
else expected="$1"
|
||||||
|
fi
|
||||||
|
assert_equal_wildcards "$output" "$expected"
|
||||||
|
}
|
||||||
|
|
||||||
assert_output_contains() {
|
assert_output_contains() {
|
||||||
local expected="$1"
|
local expected="$1"
|
||||||
echo "$output" | grep -F "$expected" >/dev/null || {
|
echo "$output" | grep -F "$expected" >/dev/null || {
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,79 @@
|
||||||
|
|
||||||
load test_helper
|
load test_helper
|
||||||
|
|
||||||
setup() {
|
create_m_system_venv() {
|
||||||
export PYENV_ROOT="${TMP}/pyenv"
|
# Create a mock virtual environment in the same way a venv created from
|
||||||
mkdir -p "${PYENV_ROOT}/versions/2.7.6"
|
# the system Python version looks.
|
||||||
mkdir -p "${PYENV_ROOT}/versions/3.3.3"
|
#
|
||||||
mkdir -p "${PYENV_ROOT}/versions/venv27"
|
# The venv is in ${PYENV_ROOT}/versions, is not a symlink, and
|
||||||
mkdir -p "${PYENV_ROOT}/versions/venv33"
|
# home is /usr/bin in the pyenv.cfg.
|
||||||
|
create_executable "$2" "python"
|
||||||
|
create_executable "$2" "activate"
|
||||||
|
|
||||||
|
local version="$1"
|
||||||
|
local venv="$2"
|
||||||
|
local venv_dir="${PYENV_ROOT}/versions/${venv}"
|
||||||
|
|
||||||
|
echo "home = /usr/bin" > "${venv_dir}/pyvenv.cfg"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "list virtual environments only" {
|
|
||||||
stub pyenv-version-name ": echo system"
|
create_m_venv() {
|
||||||
stub pyenv-virtualenv-prefix "2.7.6 : false"
|
# Create a mock virtual environment from an installed (not system) Python version.
|
||||||
stub pyenv-virtualenv-prefix "3.3.3 : false"
|
#
|
||||||
stub pyenv-virtualenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/2.7.6\""
|
# The venv name is a symlink inside ${PYENV_ROOT}/versions that points to
|
||||||
stub pyenv-virtualenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/3.3.3\""
|
# the real venv directory inside the Python version used to created and
|
||||||
|
# home points to the bin directory inside the venv dir.
|
||||||
|
setup_m_venv "$1/envs/$2"
|
||||||
|
|
||||||
|
local version="$1"
|
||||||
|
local venv="$2"
|
||||||
|
local venv_dir="${PYENV_ROOT}/versions/${version}/envs/${venv}"
|
||||||
|
|
||||||
|
echo "home = ${PYENV_ROOT}/versions/${version}/bin" > "${venv_dir}/pyvenv.cfg"
|
||||||
|
ln -sf "${venv_dir}" "${PYENV_ROOT}/versions/${venv}"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
export PYENV_ROOT="${TMP}/pyenv"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "system venv" {
|
||||||
|
stub pyenv-version-name ": echo venv314"
|
||||||
|
stub pyenv-version-origin ": echo PYENV_VERSION"
|
||||||
|
|
||||||
|
create_m_venv "3.14.3" "venv314"
|
||||||
|
create_m_system_venv "3.9.11" "system_venv"
|
||||||
|
|
||||||
run pyenv-virtualenvs
|
run pyenv-virtualenvs
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
venv27 (created from ${PYENV_ROOT}/versions/2.7.6)
|
3.14.3/envs/venv314 (created from ${PYENV_ROOT}/versions/3.14.3)
|
||||||
venv33 (created from ${PYENV_ROOT}/versions/3.3.3)
|
system_venv (created from /usr)
|
||||||
|
* venv314 --> ${PYENV_ROOT}/versions/3.14.3/envs/venv314 (set by PYENV_VERSION)
|
||||||
|
OUT
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
unstub pyenv-version-origin
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "list virtual environments" {
|
||||||
|
stub pyenv-version-name ": echo system"
|
||||||
|
stub pyenv-virtualenv-prefix "2.7.6/envs/venv27 : echo \"${PYENV_ROOT}/versions/2.7.6\""
|
||||||
|
stub pyenv-virtualenv-prefix "3.3.3/envs/venv33 : echo \"${PYENV_ROOT}/versions/3.3.3\""
|
||||||
|
|
||||||
|
create_m_venv "2.7.6" "venv27"
|
||||||
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
|
run pyenv-virtualenvs
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
2.7.6/envs/venv27 (created from ${PYENV_ROOT}/versions/2.7.6)
|
||||||
|
3.3.3/envs/venv33 (created from ${PYENV_ROOT}/versions/3.3.3)
|
||||||
|
venv27 --> ${PYENV_ROOT}/versions/2.7.6/envs/venv27
|
||||||
|
venv33 --> ${PYENV_ROOT}/versions/3.3.3/envs/venv33
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
|
|
@ -30,37 +82,101 @@ OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "list virtual environments with hit prefix" {
|
@test "list virtual environments with hit prefix" {
|
||||||
stub pyenv-version-name ": echo venv33"
|
stub pyenv-version-name ": echo 3.3.3/envs/venv33"
|
||||||
stub pyenv-virtualenv-prefix "2.7.6 : false"
|
stub pyenv-version-origin ": echo PYENV_VERSION"
|
||||||
stub pyenv-virtualenv-prefix "3.3.3 : false"
|
|
||||||
stub pyenv-virtualenv-prefix "venv27 : echo \"/usr\""
|
create_m_venv "2.7.6" "venv27"
|
||||||
stub pyenv-virtualenv-prefix "venv33 : echo \"/usr\""
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
run pyenv-virtualenvs
|
run pyenv-virtualenvs
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
venv27 (created from /usr)
|
2.7.6/envs/venv27 (created from ${PYENV_ROOT}/versions/2.7.6)
|
||||||
* venv33 (created from /usr)
|
* 3.3.3/envs/venv33 (created from ${PYENV_ROOT}/versions/3.3.3) (set by PYENV_VERSION)
|
||||||
|
venv27 --> ${PYENV_ROOT}/versions/2.7.6/envs/venv27
|
||||||
|
venv33 --> ${PYENV_ROOT}/versions/3.3.3/envs/venv33
|
||||||
OUT
|
OUT
|
||||||
|
|
||||||
unstub pyenv-version-name
|
unstub pyenv-version-name
|
||||||
unstub pyenv-virtualenv-prefix
|
unstub pyenv-version-origin
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "list virtual environments with --bare" {
|
@test "list bare virtual environments" {
|
||||||
stub pyenv-virtualenv-prefix "2.7.6 : false"
|
create_m_venv "2.7.6" "venv27"
|
||||||
stub pyenv-virtualenv-prefix "3.3.3 : false"
|
create_m_venv "3.3.3" "venv33"
|
||||||
stub pyenv-virtualenv-prefix "venv27 : echo \"/usr\""
|
|
||||||
stub pyenv-virtualenv-prefix "venv33 : echo \"/usr\""
|
|
||||||
|
|
||||||
run pyenv-virtualenvs --bare
|
run pyenv-virtualenvs --bare
|
||||||
|
|
||||||
assert_success
|
assert_success
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
|
2.7.6/envs/venv27
|
||||||
|
3.3.3/envs/venv33
|
||||||
venv27
|
venv27
|
||||||
venv33
|
venv33
|
||||||
OUT
|
OUT
|
||||||
|
}
|
||||||
unstub pyenv-virtualenv-prefix
|
|
||||||
|
@test "list bare virtual environments without aliases" {
|
||||||
|
create_m_venv "2.7.6" "venv27"
|
||||||
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
|
run pyenv-virtualenvs --bare --skip-aliases
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
2.7.6/envs/venv27
|
||||||
|
3.3.3/envs/venv33
|
||||||
|
OUT
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "list virtual environments without aliases" {
|
||||||
|
stub pyenv-version-name ": echo system"
|
||||||
|
|
||||||
|
create_m_venv "2.7.6" "venv27"
|
||||||
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
|
run pyenv-virtualenvs --skip-aliases
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
2.7.6/envs/venv27 (created from ${PYENV_ROOT}/versions/2.7.6)
|
||||||
|
3.3.3/envs/venv33 (created from ${PYENV_ROOT}/versions/3.3.3)
|
||||||
|
OUT
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "hit prefix matches alias version name" {
|
||||||
|
stub pyenv-version-name ": echo venv27"
|
||||||
|
stub pyenv-version-origin ": echo PYENV_VERSION"
|
||||||
|
|
||||||
|
create_m_venv "2.7.6" "venv27"
|
||||||
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
|
run pyenv-virtualenvs
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
2.7.6/envs/venv27 (created from ${PYENV_ROOT}/versions/2.7.6)
|
||||||
|
3.3.3/envs/venv33 (created from ${PYENV_ROOT}/versions/3.3.3)
|
||||||
|
* venv27 --> ${PYENV_ROOT}/versions/2.7.6/envs/venv27 (set by PYENV_VERSION)
|
||||||
|
venv33 --> ${PYENV_ROOT}/versions/3.3.3/envs/venv33
|
||||||
|
OUT
|
||||||
|
|
||||||
|
unstub pyenv-version-name
|
||||||
|
unstub pyenv-version-origin
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "completions output" {
|
||||||
|
create_m_venv "2.7.6" "venv27"
|
||||||
|
create_m_venv "3.3.3" "venv33"
|
||||||
|
|
||||||
|
run pyenv-virtualenvs --complete
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
--bare
|
||||||
|
--skip-aliases
|
||||||
|
OUT
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue