Compare commits

...

183 commits

Author SHA1 Message Date
Ivan Pozdeev eda64556af
1.4.0
Some checks failed
tests / tests (ubuntu-22.04) (push) Has been cancelled
tests / tests (ubuntu-24.04) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (macos-15) (push) Has been cancelled
tests / tests (macos-15-intel) (push) Has been cancelled
tests / tests (macos-26) (push) Has been cancelled
2026-04-29 08:24:00 +03:00
Sam Doran 37ab83f1b0
Improve performance and output of pyenv virtualenvs (#502)
* With 160 envs, cuts time from ~14s to ~2.5s
* Change the output to be more like `pyenv-versions'
* Shellcheck fixes
* virtualenv: Only show non-envs for completion since env engines don't support piggy-backing envs
* Remove dead/unused code
* Fix IFS handling
`IFS=: <command>' doesn't apply that IFS to expansions in <command>,
it has to be set separately earlier
* Adjust and refactor tests

---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-04-29 08:08:52 +03:00
Chris Caldwell 99d35f201c
Fix POSIX sh (dash) compatibility in pyenv-virtualenv-init (#526)
* Refactor cache code generation
* Don't generate prompt_command for non bash/zsh/fish

---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-04-21 18:53:01 +03:00
Ivan Pozdeev 6a832cacbb
CI: use macos-26
the Github runner is out of beta
2026-04-17 22:54:31 +03:00
Ivan Pozdeev 90dfbcad93
1.3.0 2026-03-25 23:46:29 +03:00
Ivan Pozdeev f046752219
Reformat changelog to conform to Pyenv and Github release notes 2026-03-25 23:45:47 +03:00
Jake Lodwick 72cb35b2b4
Drastically speed up precommand hook by caching active version to skip redundant activate calls (#523) 2026-03-25 23:33:43 +03:00
native-api 38f3333f3a
Merge pull request #520 from native-api/prevent-deletion-of-contents-in-generic-prefix-env-var
CI: tests: use Bats 1.10; support concurrent, out-of-order and multiple-times execution of stub commands; fix race condition between concurrent stubs
2025-12-18 03:52:21 +03:00
Ivan Pozdeev 10c8ace3c3
Fix a race condition between concurrently executing stubs 2025-12-18 03:47:17 +03:00
Ivan Pozdeev 7d9840478c
stub: -unnecessary indirection 2025-12-18 03:47:16 +03:00
Ivan Pozdeev bf7d3b0584
stub, test_helper: support concurrent, out-of-order and multiple-times stub command execution 2025-12-18 03:46:38 +03:00
Ivan Pozdeev dd2ad3ee65
stub: dumping the plan vars is redundant
They proved to not be useful for diagnostics
2025-12-18 03:30:05 +03:00
Ivan Pozdeev 4785e89a3b
Use Bats v1.10.0 2025-12-18 03:06:38 +03:00
native-api b83e2c3c83
CI: - commented-out code; - macos-11 workaround (#521) 2025-12-18 00:41:30 +03:00
Ivan Pozdeev b5c88a7a15
1.2.6 2025-12-14 18:41:47 +03:00
SabriRamadanTNG 64233612fb
Prevent loss of data on virtualenv-delete -f if the env doesn't exist and the PREFIX envvar is set elsewhere (#518)
* Rename the PREFIX var just in case as too generic

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2025-12-13 20:05:26 +03:00
native-api 4d37a6e477
Convert issue template to new Github format (#519)
* Convert issue template to new Github format

the old format seems to be dropped altogether now

[no ci]
2025-12-13 17:19:41 +03:00
Ivan Pozdeev f5b2602597
CI: change macos-13 to macos-15-intel 2025-12-11 14:47:13 +03:00
Charlie (cshen.dev) 387f627464
docs: fix the link to Pyenv shell setup steps (#516) 2025-09-22 08:36:00 +03:00
Seokhee Park 4b3f5f8468
docs: add WSL note about core.autocrlf to prevent CRLF issues (#512) 2025-05-17 10:19:25 +03:00
Ivan Pozdeev 3057e1549b [CI] Update environments
ubuntu-20.04 is dropped, macos-15 is available
2025-05-06 19:14:54 +03:00
Jason N. White aa9b8e9a5a
Update LICENSE, fix license year (#499)
Some checks failed
tests / tests (ubuntu-22.04) (push) Failing after 1s
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
Signed-off-by: JasonnnW3000 <sufssl04@gmail.com>
2025-01-01 20:46:21 +03:00
native-api e8c8fd9b84
Fix errorneously creating a symlink inside env directory if running with -f (#496)
Some checks failed
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
tests / tests (ubuntu-22.04) (push) Failing after 0s
2024-12-08 23:30:27 +03:00
native-api db299cada3
Fix confusing activate/deactivate error messages (#495) 2024-12-08 21:43:35 +03:00
native-api c6bb0694bf
Fix pyenv-virtualenv using a different Python version in a conda environment (#492)
Some checks failed
tests / tests (ubuntu-22.04) (push) Failing after 0s
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
Allow output checking with wildcards
2024-11-25 00:54:05 +03:00
Zac Holland 28cd9be54e
README: fix and distinguish syntax highlighting in Bash vs Fish snippets (#489)
Some checks failed
tests / tests (ubuntu-22.04) (push) Failing after 0s
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
Co-authored-by: native-api <vano@mail.mipt.ru>
2024-09-18 22:08:52 +03:00
Jovier Jimenez d4c9655e26
Add prompt customization (#476)
Some checks failed
tests / tests (ubuntu-22.04) (push) Failing after 1s
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
2024-09-15 09:40:44 +03:00
Ivan Pozdeev e9b88cc366 1.2.4
Some checks failed
tests / tests (ubuntu-22.04) (push) Failing after 1s
tests / tests (macos-13) (push) Has been cancelled
tests / tests (macos-14) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
2024-07-22 00:37:02 +03:00
native-api d811b3fef2
Merge pull request #484 from native-api/pyenv_latest_f
Reflect pyenv-latest switch change in 2.4.8
2024-07-22 00:34:28 +03:00
Ivan Pozdeev d6756cab9b CI: bump macos
Github dropped macos-11, introduced 13 and 14
2024-07-22 00:32:59 +03:00
Ivan Pozdeev 6179ac76c4 Reflect pyenv-latest switch change in 2.4.8 2024-07-21 23:31:47 +03:00
Alex Galonsky cf45718a1b
README: Remove dollar signs from commands that are meant to be copied (#481)
Some checks failed
tests / tests (ubuntu-22.04) (push) Has been cancelled
tests / tests (macos-11) (push) Has been cancelled
tests / tests (macos-12) (push) Has been cancelled
tests / tests (ubuntu-20.04) (push) Has been cancelled
2024-06-27 20:16:45 +03:00
native-api 37917069ec
Fix failing to detect -m venv when "python" is not provided by the distro (#479) 2024-04-10 00:14:13 +03:00
Ivan Pozdeev b90bd92853 1.2.3 2024-04-07 22:59:10 +03:00
Ivan Pozdeev 33f54ecad9 Add maintenance guide 2024-04-07 22:50:45 +03:00
native-api f8469a1c67
Merge pull request #478 from native-api/3drparty_venv_over_ours
Don't activate if a 3rd-party venv is activated over ours
2024-04-03 23:12:47 +03:00
Ivan Pozdeev ac28398fc0 Don't activate if a 3rd-party virtualenv is active over ours 2024-04-03 21:09:22 +03:00
Ivan Pozdeev 45a28ac094 bump stub and stub fns to Pyenv version 2024-04-03 21:09:22 +03:00
Romir K 0f83c33a3b
Add fish prompt changing (#475) 2024-02-12 12:58:27 +03:00
John HU 2b2b87a25a
Bump pyenv-virtualenv reporting version to match release (#471)
The latest release so far (Dec 2023) is 1.2.2, but the version reported is still 1.2.1:
https://github.com/pyenv/pyenv-virtualenv/releases/tag/v1.2.2
2023-12-06 06:56:52 +03:00
Jason Mobarak 38a6561f96
fix: add colorize helper (#470) 2023-11-29 11:37:00 +03:00
native-api c85c1c9ed5
Link python*-config into VE (#460)
Required to build binaries that link against Python.
Carl Meyer, the champion for PEP 0405, has confirmed that there isn't a particular reason why `venv` doesn't do that.
2023-06-27 01:36:04 +03:00
Elijah Lynn cd6a51ad68
Add fish install oneliner (#322)
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2023-04-17 00:01:19 +03:00
Marcin Konowalczyk 85d8c5aabf
More helpful error message when env's base version is not installed (#454) 2023-04-10 21:42:47 +03:00
Josh French fca12418ca
Add activate/deactivate hooks (#452) 2023-03-22 20:39:55 +03:00
Jack McIvor 13bc1877ef
Update PYENV_VIRTUALENV_VERSION (#449)
Co-authored-by: Jack McIvor <j.mcivor@draftkings.com>
2023-02-07 19:37:47 +03:00
Ivan Pozdeev a724aaa149 Merge branch 'master' of https://github.com/pyenv/pyenv-virtualenv 2023-02-01 00:27:32 +03:00
Ivan Pozdeev f4162706d8 Remove Bountysource from advertized donation sources
Same as in Pyenv, as it's gone rogue
2023-02-01 00:27:13 +03:00
native-api 77a7644ff7
Remove prompt deprecation warning (#447)
Prompt removal was never done and is not planned anymore
2023-01-31 23:14:52 +03:00
Ivan Pozdeev 826f3fbe6f ISSUE_TEMPLATE.md: Add Zsh PS4 2023-01-31 23:02:54 +03:00
native-api a6ab660b72
Support a prefix resolved by pyenv-latest as base version (#446) 2023-01-29 23:47:22 +03:00
Ville Skyttä d5f2878a97
Strip -<suffix> when autodetecting shell (#377)
For example bash-5.1, bash-static.
2022-10-18 20:37:46 +03:00
Andrew Christianson c4de2555b7
Use realpath of scripts to determine relative locations (#308)
Just using paths relative to ${BASH_SOURCE} to access `libexec`
fails if the scripts are symlinked to a location,
such as when installed with Homebrew,
since the `libexec` directory is not linked into `brew --prefix`.

Implement a simple version of `realpath`
and run `${BASH_SOURCE}` through it.
This gets the actual installation directory
relative to which `libexec` is located.

Co-authored-by: Andrew Christianson <achristianson@edmunds.com>
2022-10-14 04:37:08 +03:00
Diego Fernández Giraldo 633711a0bc
Return control to pyenv-uninstall in uninstall/envs.bash (#321) 2022-10-12 22:36:52 +03:00
P M 177eb67af3
Enhance documentation about options for pyenv virtualenv (#425)
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2022-10-12 22:12:21 +03:00
native-api 0a1839d22a
Set up Github Actions CI (#440)
* Adjust tests: update Pip URLs, update expected output to match newer code
* Test library: improve failure message to eliminate the illusion of extra leading space in "actual" output
* Use Bats 1.2.0 like Pyenv
* Install greadlink for old MacOS
* Delete duplicate test
2022-10-12 21:30:36 +03:00
Ville Skyttä 4054162a1c
Fix errors when set -u is set in the user's shell (#350) 2022-10-12 07:41:29 +03:00
Ville Skyttä 9a57cd7711
Clone bats with --depth=1, gitignore it (#351) 2022-10-11 22:53:34 +03:00
Ville Skyttä 3c0edf888e
Spelling fixes (#352) 2022-10-10 21:50:28 +03:00
Ville Skyttä 057b9be9d8
fix: relative path to pyenv-realpath.dylib (#378) 2022-10-10 21:48:29 +03:00
Joseph Egan 7932bb4cc0
Stop delete force failing when virtualenv does not exist (#330) 2022-10-10 21:47:19 +03:00
laggardkernel a911a2223f
Upgrade uninstall hook after pyenv/pyenv#2432 (#438) 2022-10-10 20:34:24 +03:00
Eric N. Vander Weele c6ff093344
Deduplicate shims in $PATH for the fish shell during initialization (#430)
When a fish login shell is invoked within an existing login shell, avoid
duplicating path to the shims by removing existing occurrences before
prepending.
2022-05-19 19:03:51 +03:00
Nick cc9d5f168e
Update get-pip.py URLs in pyenv-virtualenv (#426) 2022-02-26 09:41:41 +03:00
Alain Kalker 017ea60cd3
Fix another unbound variable error (#424)
* Fix tests failing after #423
2022-01-30 21:14:28 +03:00
Alain Kalker 1ee7ca6346
Fix unbound variable errors when running pyenv activate with set -u (#423) 2022-01-29 20:53:52 +03:00
Ville Skyttä 91609e25f3
perf(sh-activate): avoid a duplicate pyenv-version-name call (#380) 2021-11-14 02:30:56 +03:00
Seonghyeon Cho 5509c25ac1
Add (y/N) prompt help text (#404) 2021-11-08 18:15:23 +03:00
jivanf c3110d874e
Fix get-pip.py URLs for older versions of Python (#403) 2021-11-08 18:14:47 +03:00
native-api f95d6a9bee
Create FUNDING.yml 2021-10-08 11:55:00 +03:00
native-api afa008ec95
Update ISSUE_TEMPLATE.md 2021-10-08 11:15:55 +03:00
native-api 6fa056912b
Create no-response.yml 2021-10-05 04:40:56 +03:00
native-api 2648a4af29
Update ISSUE_TEMPLATE.md 2021-10-05 01:30:31 +03:00
native-api ce08a8ee72
Create ISSUE_TEMPLATE.md 2021-10-05 01:29:37 +03:00
Anton Petrov 29fb3c7cd1
Merge pull request #388 from native-api/patch-1
Fix installation steps to allow for Pyenv 2
2021-07-25 12:13:35 +03:00
Anton Petrov c537bfff26
Merge pull request #395 from Gauravtalreja1/fix-394
Fixes #394 - update pyenv virtualenvs to list virtualenvs start with dot prefixes
2021-06-17 20:35:52 +03:00
Gaurav Talreja b334dde5ef Fix #394 - update pyenv virtualenvs command to list virtualenvs starting with dot prefixes 2021-06-16 15:20:14 +05:30
native-api 582b693c11
Fix installation steps to allow for Pyenv 2
The text included info on Pyenv startup which is now outdated and incorrect.

Closes https://github.com/pyenv/pyenv/issues/1947, https://github.com/pyenv/pyenv-virtualenv/issues/387
2021-05-26 00:49:31 +03:00
Anton Petrov 6742d0ef10
Merge pull request #384 from native-api/profile_2_rc
~/.*rc should be modified instead of ~/.*profile
2021-05-09 20:56:31 +03:00
Anton Petrov 8c7ef734f9
Update pyenv-virtualenv-init
https://github.com/pyenv/pyenv-installer/pull/109
2021-05-09 20:17:17 +03:00
Ivan Pozdeev 90f7b999ff ~/.*rc should be modified instead of ~/.*profile
Otherwise, there's no effect for non-login interactive shells
2021-05-09 20:16:35 +03:00
Yamashita, Yuu 294f64f76b v1.1.5 2019-02-13 15:27:07 +00:00
Yamashita, Yuu e39b112676 Install libexec as well under the given prefix (#290, #302) 2019-02-13 15:25:00 +00:00
Yamashita, Yuu 74bba45b9c v1.1.4 2019-02-08 02:04:46 +00:00
Yamashita, Yuu 2d947be5d9
Merge pull request #296 from pyenv/yy-py-venv-major-minor
Prefer `python3.x` executable if available
2019-01-12 14:41:57 +09:00
Yamashita, Yuu a9e1891e8b Prefer python3.x executable if avaialble (closes #206, #282) 2019-01-12 05:38:21 +00:00
Yamashita, Yuu bfdeb31d78
Merge pull request #238 from pgrzesik/master
Add other way of deleting existing virtualenv
2019-01-12 07:51:41 +09:00
Yamashita, Yuu e3203f795a
Merge pull request #286 from faho/patch-1
Improve fish installation instructions
2019-01-12 07:50:52 +09:00
Yamashita, Yuu 6d90f61726
Merge pull request #290 from lmmarsano/fix-conda
Fix: support newer conda
2018-11-23 21:57:29 +09:00
Luis Marsano ed779fea14
cleanup pyenv virtualenv on ERR
also cleanup compatibility paths
2018-11-21 22:00:57 -05:00
Luis Marsano e0a1e9b35c
support newer conda
pyenv-virtualenvs could not list conda environments & pyenv shell would only activate the base conda environment
the conda detection criteria of testing the presence of `conda` or `activate` files under `$(pyenv root)/versions/$version/bin` appears to be the culprit, since newer environments no longer include these files: those files reside in the base conda environment
- add detection criteria of `$(pyenv root)/versions/$version/conda-meta`
- compute the real prefix to the base environment from `realpath $(realpath $(pyenv root)/versions/$version)/../..`
- to allow that, enhance substitute `realpath` in `pyenv-virtualenvs` to reduce relative paths `.` & `..`, and factor that code out to a file under `libexec` for reuse
- hook `which` to locate conda from the real prefix
2018-11-21 22:00:56 -05:00
Fabian Homborg cec39359ec
Improve fish installation instructions
`psub` here is entirely unnecessary.
2018-10-31 13:22:46 +01:00
Yamashita, Yuu 8c9f7fa766
Merge pull request #285 from alanyee/master
Update README.md
2018-10-30 14:49:25 +09:00
Alan Yee be6d917f16
Update README.md
-Replace Mac OS X with macOS
-Added links
2018-10-29 21:54:24 -07:00
Yamashita, Yuu 32718e80b9
Merge pull request #280 from bradleyhurley/master
Updating ReadMe to include information for Fish
2018-08-22 09:07:37 +09:00
Brad Hurley 8310e73b43 Updating ReadMe to include information for Fish 2018-08-21 12:04:51 -04:00
Yamashita, Yuu 5d1dcaa94c
Merge pull request #272 from YumaInaura/master
update README about PYENV_VIRTUALENV_VERBOSE_ACTIVATE
2018-07-06 07:49:39 +09:00
Yuma Inaura (稲浦悠馬) aa9baa8e03 update README about PYENV_VIRTUALENV_VERBOSE_ACTIVATE 2018-07-06 07:31:34 +09:00
Yamashita, Yuu 75e84742db Update change log [ci skip] 2018-05-24 12:33:57 +00:00
Yamashita, Yuu 829dd1c9cb Updated .travis.yml [ci skip] 2018-05-24 12:33:27 +00:00
Yamashita, Yuu 42f8ed2dce v1.1.3 2018-05-24 12:28:04 +00:00
Yamashita, Yuu a75aa66490 Automate release 2018-05-24 12:27:02 +00:00
Yamashita, Yuu 9a03eb5b9c v1.1.2 2018-05-18 00:59:28 +00:00
Yamashita, Yuu e67dd07f1b
Merge pull request #255 from pyenv/workaround-get-pip-url-py26-py32
Use custom get-pip URL based on the target version (pyenv/pyenv#1127)
2018-03-29 12:20:50 +09:00
Yamashita, Yuu 077edc3b4d Update warning message on presence of PIP_VERSION 2018-03-29 03:17:49 +00:00
Yamashita, Yuu 0b24ff557e I should have used custom GET_PIP_URL for 3.3 2018-03-29 01:07:48 +00:00
Yamashita, Yuu 6a3172ff47 Unlike python-build, DEFINITION_PATH isn't available within pyenv-virtualenv 2018-03-29 01:01:16 +00:00
Yamashita, Yuu 894d4af8a3 Show some warning on the use of PIP_VERSION 2018-03-29 00:59:01 +00:00
Yamashita, Yuu 980159f221 Use custom get-pip URL based on the target version (pyenv/pyenv#1127) 2018-03-29 00:39:30 +00:00
Yamashita, Yuu 051cd5880c
Merge pull request #254 from pyenv/pip-version-workaround2
Refactoring around `GET_PIP_URL`
2018-03-22 11:04:41 +09:00
Yamashita, Yuu cfb8691fc5 Refactoring
Manage `GET_PIP_URL` value at single place for readability.
2018-03-22 01:36:48 +00:00
Yamashita, Yuu 74ff2ce7af
Merge pull request #253 from pyenv/pip-version-workaround
Unset `PIP_VERSION` before invoking `get-pip.py` as a workaround for `invalid truth value` error
2018-03-20 13:24:23 +09:00
Yamashita, Yuu b1d0d72343 Unset PIP_VERSION before invoking get-pip.py as a workaround for invalid truth value error (pyenv/pyenv-installer#70) 2018-03-20 04:04:58 +00:00
Yamashita, Yuu 219a527a78
Merge pull request #251 from teake/conda/sourcing
Source conda 4.4.4 shell files
2018-03-09 10:16:55 +09:00
Teake Nutma 393bcc36b8 Source conda 4.4.4 shell files
Conda 4.4.4 (https://github.com/conda/conda/releases/tag/4.4.0)
made some changes on how to set up conda in the shell.
This commit addresses these.

This fixes some of the discussion in #178.
2018-03-08 10:08:53 +01:00
Yamashita, Yuu 5419dc7320
Merge pull request #244 from adamscharf/patch-1
Move pyenv note to its own line
2017-12-07 10:00:51 +09:00
Adam Scharf 94b2c9d5d6
Move pyenv note to its own line 2017-12-06 10:35:35 -05:00
Piotr Grzesik a0b17033fc Add other way of deleting existing virtualenv 2017-10-16 22:08:34 +02:00
Yamashita, Yuu e690650fd6 Merge pull request #237 from honza/fish-virtualenv-init
Add a note about virtualenv-init for fish users
2017-09-27 11:05:28 +09:00
Honza Pokorny 74bc08b7dc Add a note about virtualenv-init for fish users 2017-09-26 08:31:48 -03:00
Yamashita, Yuu a22521e946 Fix wrong path to pyvenv.cfg (fixes #209) 2017-09-13 01:52:13 +00:00
Yamashita, Yuu b4eb09d1dd Merge pull request #232 from logikone/fix-force-option
evaluate force flag before testing if venv exists
2017-09-11 10:19:52 +09:00
Chris Larsen 52cb0b1086 evaluate force flag before testing if venv exists
fixes #161, fixes #187
2017-09-08 15:27:49 -06:00
Yamashita, Yuu 1e66783091 Merge pull request #231 from scop/spelling
Spelling fix
2017-09-05 16:54:33 +09:00
Ville Skyttä b8dd4fcb53 Spelling fix 2017-09-05 10:12:45 +03:00
Yamashita, Yuu 4c8da67f02 v1.1.1 2017-08-24 00:30:36 +00:00
Yamashita, Yuu c2ba4952ff Merge pull request #230 from pyenv/gen-pydoc-executable
Generate `pydoc` executable after creating new virtualenv
2017-08-23 20:17:57 +09:00
Yamashita, Yuu 927914b25f Make sure pydoc executable exists after creating virtualenv 2017-08-23 11:14:42 +00:00
Yamashita, Yuu e339fde2f3 Create virtualenv's bin directory explicitly to avoid CI failures 2017-08-22 23:04:39 +00:00
Yamashita, Yuu e83a1f12c2 Generate pydoc executable after creating new virtualenv (fixes #197, pyenv/pyenv#963) 2017-08-22 23:00:41 +00:00
Yamashita, Yuu 2727087757 Merge pull request #224 from cpaulik/support-conda-prefix
Set CONDA_PREFIX to make is useable in conda activate/deactivate scripts
2017-07-21 10:01:08 +09:00
Christoph Paulik f64c8ed0dd Set CONDA_PREFIX to make is useable in conda activate/deactivate scripts. 2017-07-20 15:53:55 +02:00
Yamashita, Yuu e4d2c367cc v1.1.0 2017-07-03 00:39:50 +00:00
Yamashita, Yuu c67762742a Merge pull request #220 from jcrben/patch-1
Be more explicit about `.python-version` file
2017-06-21 16:43:44 +09:00
Ben Creasy 1593b0e6b0 Be more explicit about .python-version file
When I came back to this after a few months - despite setting it up properly previously - I was a bit confused since I'm so used to setting an actual Python version in `.python-version` files. Explain exactly how the file should look.
2017-06-20 23:44:53 -07:00
Drummond Ogilvie 862be21a32 fish: use "set -gx" instead of "setenv" (#218)
Use `set -gx` instead of `setenv` for fish shell.

Fix test "activate if the first virtualenv is a virtualenv": it was asserting
the output was of bash form, but not specifying that in the test — it now does.

Fixes https://github.com/pyenv/pyenv-virtualenv/issues/216.
2017-06-08 21:52:57 +02:00
Yamashita, Yuu 252d6763f9 Update build status link target 2017-03-06 04:43:41 +00:00
Yamashita, Yuu 832244fe13 Update project URL to https://github.com/pyenv/pyenv-virtualenv 2017-03-06 04:16:48 +00:00
Yamashita, Yuu 61a5c7f807 Merge pull request #201 from yamotonalds/fix-typo
Fix typo
2017-02-18 09:21:12 -08:00
yamotonalds 304dff741f Fix typo 2017-02-18 22:06:05 +09:00
Yamashita, Yuu 53dd8bcf46 Merge pull request #198 from massongit/develop
Fix the installation command of README.md
2017-01-31 12:51:01 +09:00
massongit f9b1814b82 Fix the installation command of README.md 2017-01-31 12:38:21 +09:00
Yamashita, Yuu a3bc42cb93 v1.0.0 (yyuu/pyenv#520) 2016-08-15 08:45:05 +00:00
Yamashita, Yuu 0fd8a161e6 v20160716 2016-07-16 07:00:03 +00:00
Yamashita, Yuu 704f08f866 Merge pull request #185 from yyuu/python-m-venv
Use `-m venv` instead of `pyvenv` executable (fixes #184)
2016-07-16 15:53:01 +09:00
Yamashita, Yuu 8c7dd01954 Replaced pyvenv by -m venv 2016-07-16 06:50:50 +00:00
Yamashita, Yuu 99a90ab774 Fix still broken tests 2016-07-16 06:43:47 +00:00
Yamashita, Yuu 187156d600 Use python -m venv instead on pyvenv in tests 2016-07-16 06:31:30 +00:00
Yamashita, Yuu 7dc9f78589 sed -e s/pyvenv/venv/g README.md [ci skip] 2016-07-16 05:49:41 +00:00
Yamashita, Yuu 24b494a858 Use -m venv instead of pyvenv executable (fixes #184) 2016-07-16 05:46:43 +00:00
Yamashita, Yuu 1488c3ed65 Merge pull request #176 from yyuu/fish-dot-to-source
Use `source` in favor of `.` (fixes #175)
2016-05-30 09:17:17 +09:00
Yamashita, Yuu 5c2d7dc291 Use source in favor of . (fixes #175)
* https://github.com/yyuu/pyenv/pull/615
* https://github.com/fish-shell/fish-shell/issues/310
2016-05-30 00:13:49 +00:00
Yamashita, Yuu f58bdb5cd5 Merge pull request #174 from yyuu/conda-activate-d
Source conda package activate/deactivat scripts if exist
2016-05-25 10:02:12 +09:00
Yamashita, Yuu d9391b4fb9 Add tests for conda's package activate/deactivate script 2016-05-25 00:53:44 +00:00
Yamashita, Yuu d6bc583753 Source conda package activate/deactivat scripts if exist (fixes #173) 2016-05-24 00:39:40 +00:00
Yamashita, Yuu 98bb240843 Merge pull request #171 from yyuu/simplified-messaging-levels
Simplified messaging levels
2016-05-07 22:50:33 +09:00
Yamashita, Yuu 1cb6bb06ef Turn PYENV_VIRTUALENV_VERBOSE_ACTIVATE on if --verbose is given 2016-05-07 13:45:00 +00:00
Yamashita, Yuu 08cfea259c Remove backward compat --no-error option 2016-05-07 13:40:48 +00:00
Yamashita, Yuu c64aebef08 1) Made --quiet as opposite of --verbose 2) Suppress warning about prompts on --quiet 2016-05-07 13:40:32 +00:00
Yamashita, Yuu b952f573ba Merge pull request #169 from puhitaku/verbose_env
Suppress activate/deactivate messages by default
2016-04-19 09:58:26 +09:00
puhitaku 62e32f9cb3 Fix test: add unsets 2016-04-15 11:56:28 +09:00
puhitaku 8ab4463d80 Fix test: unnecessary env 2016-04-13 11:44:21 +09:00
puhitaku 34dc769a5d Fix test: conda env 2016-04-13 11:40:47 +09:00
puhitaku 16597f0bb8 Fix test: deactivate 2016-04-13 11:40:17 +09:00
puhitaku fa0876685e Fix test: wrongly removed lines 2016-04-13 11:27:00 +09:00
puhitaku ab5b5b9221 Fix tests 2016-04-08 17:27:11 +09:00
puhitaku f627609419 Suppress activate/deactivate messages by default 2016-04-08 15:45:26 +09:00
Yamashita, Yuu 23f7027ce4 Merge pull request #165 from shangsunset/master
change minor typo in bin/pyenv-sh-activate
2016-03-28 09:23:26 +09:00
shangsunset 55f7e3e1e1 fix minor typos in test 2016-03-26 23:25:14 -04:00
shangsunset d26852e274 fix minor typos in test 2016-03-25 19:24:58 -04:00
shangsunset 7938c89aff change minor typo in bin/pyenv-sh-activate 2016-03-25 17:02:33 -04:00
Yamashita, Yuu 1ce2e2d730 v20160315 2016-03-15 00:37:46 +00:00
Yamashita, Yuu d3d6504e01 Set proper CONDA_DEFAULT_ENV for shorter name (#160) 2016-03-14 12:50:27 +00:00
Yamashita, Yuu 15981986e5 Merge pull request #154 from seanfisk/eval-path-later
Evaluate ${PATH} when outputted code is eval'd.
2016-03-07 11:40:54 +09:00
Yamashita, Yuu ddda0d7200 Merge pull request #158 from marco-buttu/master
`pyenv virtualenvs` lists two entries for each virtualenv
2016-03-05 21:55:47 +09:00
Marco Buttu 4f39ac4623 "pyenv virtualenvs" lists two entries for each virtualenv 2016-03-05 08:50:10 +01:00
Sean Fisk dbbbc33206 Evaluate ${PATH} when outputted code is eval'd.
It was previously evaluated when 'pyenv virtualenv-init' is run.
2016-03-01 01:12:06 -05:00
Yamashita, Yuu 17ee6e72b6 v20160202 2016-02-02 08:47:11 +00:00
Yamashita, Yuu 1f761275cd Install virtualenv 13.1.2 for CPython 3.2 (yyuu/pyenv#531) 2016-01-30 04:34:23 +00:00
Yamashita, Yuu 51ebc8ff8a v20160112 2016-01-12 01:53:27 +00:00
Yamashita, Yuu 4c8eeebbff Add missing declaration of virtualenv_prefix to fix looking up executables from source version (#62) 2016-01-12 00:33:34 +00:00
Yamashita, Yuu 433992e376 Merge pull request #138 from kerstin/autoactivate
Clarification of auto-activation/deactivation feature
2016-01-03 07:44:19 +09:00
Kerstin Kollmann efe6d6757c clarify how auto-activation works (requirements) 2016-01-02 16:31:37 +01:00
45 changed files with 2319 additions and 800 deletions

12
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [pyenv] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: pyenv # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

46
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,46 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
### Prerequisite
* [ ] 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 reporting a problem in Pyenv-Virtualenv and not seeking consultation with Pyenv-Virtualenv use.
* 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)).
* Please refer to the package documentation for the installation issues, etc.
* [ ] 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.
### 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):
- [ ] OS architecture (e.g. amd64):
- [ ] pyenv version:
- [ ] pyenv-virtualenv version:
- [ ] Python version:
- [ ] virtualenv version (if installed):
- [ ] 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 outside of a Pyenv invocation, get the debug log like this:
```bash
# for Bash
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
# for Zsh
export PS4='+(%x:%I): %N(%i): '
set -x
<reproduce the problem>
set +x
```

View 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.

13
.github/no-response.yml vendored Normal file
View file

@ -0,0 +1,13 @@
# Configuration for probot-no-response - https://github.com/probot/no-response
# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 30
# Label requiring a response
responseRequiredLabel: need-feedback
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.

19
.github/workflows/tests.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: tests
on: [pull_request, push]
jobs:
tests:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- ubuntu-24.04
- macos-14
- macos-15
- macos-15-intel
- macos-26
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git clone https://github.com/bats-core/bats-core.git --depth=1 -b v1.10.0 bats
- run: bats/bin/bats --tap test

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/bats/
/libexec/pyenv-virtualenv/*/*.class /libexec/pyenv-virtualenv/*/*.class
/libexec/pyenv-virtualenv/*/*.pyc /libexec/pyenv-virtualenv/*/*.pyc
/libexec/pyenv-virtualenv/*/*.pyo /libexec/pyenv-virtualenv/*/*.pyo

View file

@ -1,7 +1,14 @@
sudo: false sudo: false
install: git clone https://github.com/sstephenson/bats.git install: git clone --depth=1 https://github.com/sstephenson/bats.git
script: bats/bin/bats --tap test script: bats/bin/bats --tap test
language: c language: c
notifications: notifications:
email: email:
on_success: never on_success: never
deploy:
provider: releases
api_key:
secure: DsGAt0UmTSGVfsNJ6LmM+LvsV6FYmvX4FcET82XrskPiQW+N8+8JZR8WuZxfmwdJZu+dkkdoq6gYgL2xF7m4LxRG7aw3B5TtbMTrJQeW0hdtCSBwbbYyvwcp2m7ywE8lGAfZQITaGj1R6f2Cgh8cgtcrErjcF0KJsYlVlgNv+/M=
on:
repo: pyenv/pyenv-virtualenv
tags: true

View file

@ -1,62 +1,183 @@
## Version History ## Version History
#### 20151229 ## 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
* 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
## v1.2.3
* 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
* 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
## 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
* 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
* More helpful error message when requesting a nonexistent base version by @MarcinKonowalczyk in https://github.com/pyenv/pyenv-virtualenv/pull/454
* 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
## 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
## v1.2.0
* ~/.*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
* Fix installation steps to allow for Pyenv 2 by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/388
* Fix get-pip.py URLs for older versions of Python by @jivanf in https://github.com/pyenv/pyenv-virtualenv/pull/403
* Add (y/N) prompt help text by @sh-cho in https://github.com/pyenv/pyenv-virtualenv/pull/404
* perf(sh-activate): avoid a pyenv-version-name call by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/380
* Fix unbound variable errors when running `pyenv activate` with `set -u` Use default empty value. This fixes #422. by @ackalker in https://github.com/pyenv/pyenv-virtualenv/pull/423
* Fix another unbound variable error by @ackalker in https://github.com/pyenv/pyenv-virtualenv/pull/424
* Update `get-pip.py` URLs in `pyenv-virtualenv` by @mcdonnnj in https://github.com/pyenv/pyenv-virtualenv/pull/426
* Deduplicate shims in $PATH for the fish shell during initialization by @ericvw in https://github.com/pyenv/pyenv-virtualenv/pull/430
* Upgrade uninstall hook after pyenv/pyenv#2432 by @laggardkernel in https://github.com/pyenv/pyenv-virtualenv/pull/438
* Stop delete force failing when virtualenv does not exist by @eganjs in https://github.com/pyenv/pyenv-virtualenv/pull/330
* fix: relative path to pyenv-realpath.dylib by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/378
* Spelling fixes by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/352
* Clone bats with --depth=1, gitignore it by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/351
* set -u fixes by @scop in https://github.com/pyenv/pyenv-virtualenv/pull/350
* Set up Github Actions CI by @native-api in https://github.com/pyenv/pyenv-virtualenv/pull/440
* Enhance documentation about options for `pyenv virtualenv` by @pylipp in https://github.com/pyenv/pyenv-virtualenv/pull/425
* Return control to pyenv-uninstall in uninstall/envs.bash by @aiguofer in https://github.com/pyenv/pyenv-virtualenv/pull/321
* 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
## v1.1.5
* Fix install script (#290, #302)
## v1.1.4
* Support newer conda (#290)
* Prefer `python3.x` executable if available (#206, #282, #296)
## v1.1.3
* No code changes since 1.1.2
## v1.1.2
* Use custom get-pip URL based on the target version (#253, #254, #255)
* Source conda 4.4.4 shell files (#251)
* Evaluate force flag before testing if venv exists (#232)
## v1.1.1
* Set `CONDA_PREFIX` to make is useable in conda activate/deactivate scripts (#224)
* Generate `pydoc` executable after creating new virtualenv (#197, #230)
## v1.1.0
* fish: use "set -gx" instead of "setenv" (#215, #216, #217, #218)
## v1.0.0
* Use similar versioning scheme as pyenv; YYYYMMDD -> X.Y.Z
## v20160716
* Suppress activate/deactivate messages by default (#169, #170, #171)
* Source conda package activate/deactivat scripts if exist (#173)
* 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)
## v20160315
* Evaluate `${PATH}` when outputted code is eval'd. (#154)
* Set proper `CONDA_DEFAULT_ENV` for shorter name (#160)
## v20160202
* Install virtualenv 13.1.2 for CPython/Stackless 3.2.x (yyuu/pyenv#531)
## v20160112
* Fix problem with `virtualenv` to look up executables from source version with `--system-site-packages` (#62)
## 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)
* Rewrite `pyenv activate` and `pyenv deactivate` without using scripts provided by virtualenv and conda (#51, #69, #103, #104, #121) * Rewrite `pyenv activate` and `pyenv deactivate` without using scripts provided by virtualenv and conda (#51, #69, #103, #104, #121)
* Improve the `pyenv activate` behaviour on multipe versions (#105, #111) * Improve the `pyenv activate` behaviour on multiple versions (#105, #111)
* Reject creating a virtualenv named `system` (yyuu/pyenv#475) * Reject creating a virtualenv named `system` (yyuu/pyenv#475)
* 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)
@ -64,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.

View file

@ -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

15
MAINTENANCE.md Normal file
View file

@ -0,0 +1,15 @@
Creating a release
==================
The release of the new version of Pyenv is done via GitHub Releases.
Release checklist:
* Start [drafting a new release on GitHub](https://github.com/pyenv/pyenv-virtualenv/releases) to generate a summary of changes. Save the summary locally.
* The summary may need editing. E.g. rephrase entries, delete/merge entries that are too minor or irrelevant to the users (e.g. typo fixes, CI)
* Push the version number in `bin/pyenv-virtualenv`
* Minor version is pushed if there are significant functional changes (not e.g. bugfixes/formula adaptations/supporting niche use cases).
* Major version is pushed if there are breaking changes
* Update `CHANGELOG.md` with the new version number and the edited summary (only the changes section), reformatting it like the rest of the changelog sections
* Commit the changes locally into `master`
* Create a new tag with the new version number and push the changes including the tag
* Create a new release on GitHub based on the tag, using the saved summary

105
README.md
View file

@ -2,14 +2,14 @@
[![Join the chat at https://gitter.im/yyuu/pyenv-virtualenv](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/yyuu/pyenv-virtualenv?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/yyuu/pyenv-virtualenv](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/yyuu/pyenv-virtualenv?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/yyuu/pyenv-virtualenv.svg?branch=master)](https://travis-ci.org/yyuu/pyenv-virtualenv) [![Build Status](https://travis-ci.org/pyenv/pyenv-virtualenv.svg?branch=master)](https://travis-ci.org/pyenv/pyenv-virtualenv)
pyenv-virtualenv is a [pyenv](https://github.com/yyuu/pyenv) plugin pyenv-virtualenv is a [pyenv](https://github.com/pyenv/pyenv) plugin
that provides features to manage virtualenvs and conda environments that provides features to manage virtualenvs and conda environments
for Python on UNIX-like systems. for Python on UNIX-like systems.
(NOTICE: If you are an existing user of [virtualenvwrapper](http://pypi.python.org/pypi/virtualenvwrapper) (NOTICE: If you are an existing user of [virtualenvwrapper](http://pypi.python.org/pypi/virtualenvwrapper)
and you love it, [pyenv-virtualenvwrapper](https://github.com/yyuu/pyenv-virtualenvwrapper) may help you and you love it, [pyenv-virtualenvwrapper](https://github.com/pyenv/pyenv-virtualenvwrapper) may help you
(additionally) to manage your virtualenvs.) (additionally) to manage your virtualenvs.)
## Installation ## Installation
@ -17,7 +17,7 @@ and you love it, [pyenv-virtualenvwrapper](https://github.com/yyuu/pyenv-virtual
### Installing as a pyenv plugin ### Installing as a pyenv plugin
This will install the latest development version of pyenv-virtualenv into This will install the latest development version of pyenv-virtualenv into
the `~/.pyenv/plugins/pyenv-virtualenv` directory. the `$(pyenv root)/plugins/pyenv-virtualenv` directory.
**Important note:** If you installed pyenv into a non-standard directory, make **Important note:** If you installed pyenv into a non-standard directory, make
sure that you clone this repo into the 'plugins' directory of wherever you sure that you clone this repo into the 'plugins' directory of wherever you
@ -28,32 +28,49 @@ 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/yyuu/pyenv-virtualenv.git ~/.pyenv/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 virtualenv. This is entirely optional but pretty useful. For the Fish shell:
```sh ```fish
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile git clone https://github.com/pyenv/pyenv-virtualenv.git (pyenv root)/plugins/pyenv-virtualenv
``` ```
**Zsh note**: Modify your `~/.zshenv` file instead of `~/.bash_profile`. 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.
**Pyenv note**: You may also need to add `eval "$(pyenv init -)"` to your profile if you haven't done so already.
```bash
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
```
**Fish shell note**: Add this to your `~/.config/fish/config.fish`
```fish
status --is-interactive; and pyenv virtualenv-init - | source
```
**Zsh note**: Modify your `~/.zshrc` file instead of `~/.bashrc`.
3. **Restart your shell to enable pyenv-virtualenv** 3. **Restart your shell to enable pyenv-virtualenv**
```sh ```bash
$ exec "$SHELL" exec "$SHELL"
``` ```
### Installing with Homebrew (for OS X users) ### Installing with Homebrew (for macOS users)
Mac OS X users can install pyenv-virtualenv with the macOS users can install pyenv-virtualenv with the
[Homebrew](http://brew.sh) package manager. [Homebrew](https://brew.sh) package manager.
This will give you access to the `pyenv-virtualenv` command. If you have pyenv This will give you access to the `pyenv-virtualenv` command. If you have pyenv
installed, you will also be able to use the `pyenv virtualenv` command. installed, you will also be able to use the `pyenv virtualenv` command.
@ -61,21 +78,22 @@ installed, you will also be able to use the `pyenv virtualenv` command.
with Homebrew.* with Homebrew.*
```sh ```sh
$ brew install pyenv-virtualenv brew install pyenv-virtualenv
``` ```
Or, if you would like to install the latest development release: Or, if you would like to install the latest development release:
```sh ```sh
$ brew install --HEAD pyenv-virtualenv brew install --HEAD pyenv-virtualenv
``` ```
After installation, you'll still need to add After installation, you'll still need to do
[Pyenv shell setup steps](https://github.com/pyenv/pyenv#b-set-up-your-shell-environment-for-pyenv)
then add
```sh ```sh
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)" eval "$(pyenv virtualenv-init -)"
``` ```
to your profile (as stated in the caveats). You'll only ever have to do this once. to your shell's `.rc` file (as stated in the caveats). You'll only ever have to do this once.
## Usage ## Usage
@ -87,12 +105,15 @@ To create a virtualenv for the Python version used with pyenv, run
of the virtualenv directory. For example, of the virtualenv directory. For example,
```sh ```sh
$ pyenv virtualenv 2.7.10 my-virtual-env-2.7.10 pyenv virtualenv 2.7.10 my-virtual-env-2.7.10
``` ```
will create a virtualenv based on Python 2.7.10 under `~/.pyenv/versions` in a will create a virtualenv based on Python 2.7.10 under `$(pyenv root)/versions` in a
folder called `my-virtual-env-2.7.10`. folder called `my-virtual-env-2.7.10`.
`pyenv virtualenv` forwards any options to the underlying command that actually
creates the virtual environment (`conda`, `virtualenv`, or `python -m venv`).
See the output of `pyenv virtualenv --help` for details.
### Create virtualenv from current version ### Create virtualenv from current version
@ -111,22 +132,25 @@ $ pyenv virtualenv venv34
`pyenv virtualenvs` shows you the list of existing virtualenvs and `conda` environments. `pyenv virtualenvs` shows you the list of existing virtualenvs and `conda` environments.
```sh ```sh
$ pyenv shell venv27 $ pyenv shell venv34
$ pyenv virtualenvs $ pyenv virtualenvs
miniconda3-3.9.1 (created from /home/yyuu/.pyenv/versions/miniconda3-3.9.1) miniconda3-3.9.1 (created from /home/yyuu/.pyenv/versions/miniconda3-3.9.1)
miniconda3-3.9.1/envs/myenv (created from /home/yyuu/.pyenv/versions/miniconda3-3.9.1) miniconda3-3.9.1/envs/myenv (created from /home/yyuu/.pyenv/versions/miniconda3-3.9.1)
* venv27 (created from /home/yyuu/.pyenv/versions/2.7.10) 2.7.10/envs/my-virtual-env-2.7.10 (created from /home/yyuu/.pyenv/versions/2.7.10)
venv34 (created from /home/yyuu/.pyenv/versions/3.4.3) 3.4.3/envs/venv34 (created from /home/yyuu/.pyenv/versions/3.4.3)
my-virtual-env-2.7.10 (created from /home/yyuu/.pyenv/versions/2.7.10)
* venv34 (created from /home/yyuu/.pyenv/versions/3.4.3)
``` ```
There are two entries for each virtualenv, and the shorter one is just a symlink.
### Activate virtualenv ### Activate virtualenv
Some external tools (e.g. [jedi](https://github.com/davidhalter/jedi)) might Some external tools (e.g. [jedi](https://github.com/davidhalter/jedi)) might
require you to `activate` the virtualenv and `conda` environments. require you to `activate` the virtualenv and `conda` environments.
`pyenv-virtualenv` will automatically activate/deactivate the virtualenv if If `eval "$(pyenv virtualenv-init -)"` is configured in your shell, `pyenv-virtualenv` will automatically activate/deactivate virtualenvs on entering/leaving directories which contain a `.python-version` file that contains the name of a valid virtual environment as shown in the output of `pyenv virtualenvs` (e.g., `venv34` or `3.4.3/envs/venv34` in example above) . `.python-version` files are used by pyenv to denote local Python versions and can be created and deleted with the [`pyenv local`](https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local) command.
the `eval "$(pyenv virtualenv-init -)"` is properly configured in your shell.
You can also activate and deactivate a pyenv virtualenv manually: You can also activate and deactivate a pyenv virtualenv manually:
@ -138,21 +162,27 @@ pyenv deactivate
### Delete existing virtualenv ### Delete existing virtualenv
Removing the directories in `~/.pyenv/versions` and `~/.pyenv/versions/{version}/envs` will delete the virtualenv, or you can run: Removing the directories in `$(pyenv root)/versions` and `$(pyenv root)/versions/{version}/envs` will delete the virtualenv, or you can run:
```sh ```sh
pyenv uninstall my-virtual-env pyenv uninstall my-virtual-env
``` ```
You can also delete existing virtualenvs by using `virtualenv-delete` command, e.g. you can run:
```sh
pyenv virtualenv-delete my-virtual-env
```
This will delete virtualenv called `my-virtual-env`.
### virtualenv and pyvenv
### virtualenv and venv
There is a [venv](http://docs.python.org/3/library/venv.html) module available There is a [venv](http://docs.python.org/3/library/venv.html) module available
for CPython 3.3 and newer. for CPython 3.3 and newer.
It provides a command-line tool `pyvenv` which is the successor of `virtualenv` It provides an executable module `venv` which is the successor of `virtualenv`
and distributed by default. and distributed by default.
`pyenv-virtualenv` uses `pyvenv` if it is available and the `virtualenv` `pyenv-virtualenv` uses `python -m venv` if it is available and the `virtualenv`
command is not available. command is not available.
@ -212,13 +242,14 @@ You can set certain environment variables to control pyenv-virtualenv.
* `VIRTUALENV_VERSION`, if set, forces pyenv-virtualenv to install the desired * `VIRTUALENV_VERSION`, if set, forces pyenv-virtualenv to install the desired
version of virtualenv. If `virtualenv` has not been installed, version of virtualenv. If `virtualenv` has not been installed,
pyenv-virtualenv will try to install the given version of virtualenv. pyenv-virtualenv will try to install the given version of virtualenv.
* `GET_PIP`, if set and `pyvenv` is preferred over `virtualenv`, * `GET_PIP`, if set and `venv` is preferred over `virtualenv`,
use `get_pip.py` from the specified location. use `get_pip.py` from the specified location.
* `GET_PIP_URL`, if set and `pyvenv` is preferred over * `GET_PIP_URL`, if set and `venv` is preferred over
`virtualenv`, download `get_pip.py` from the specified URL. `virtualenv`, download `get_pip.py` from the specified URL.
* `PIP_VERSION`, if set and `pyvenv` 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_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
@ -227,7 +258,7 @@ See [CHANGELOG.md](CHANGELOG.md).
### License ### License
(The MIT License) [(The MIT License)](LICENSE)
* Copyright (c) 2015 Yamashita, Yuu * Copyright (c) 2015 Yamashita, Yuu

View file

@ -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

View file

@ -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

View file

@ -24,7 +24,27 @@ resolve_link() {
unset FORCE unset FORCE
unset QUIET unset QUIET
unset VERBOSE
# Define `before_activate` and `after_activate` functions that allow
# plugin hooks to register a string of code for execution before or
# after activating a virtualenv.
declare -a before_hooks after_hooks
before_activate() {
local hook="$1"
before_hooks["${#before_hooks[@]}"]="$hook"
}
after_activate() {
local hook="$1"
after_hooks["${#after_hooks[@]}"]="$hook"
}
# Load plugin hooks.
OLDIFS="$IFS"
IFS=$'\n' scripts=(`pyenv-hooks activate`)
IFS="$OLDIFS"
for script in "${scripts[@]}"; do source "$script"; done
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
@ -36,10 +56,6 @@ while [ $# -gt 0 ]; do
"-f" | "--force" ) "-f" | "--force" )
FORCE=1 FORCE=1
;; ;;
"--no-error" )
# for backward compatibility with v20151103 and earlier
QUIET=1
;;
"-q" | "--quiet" ) "-q" | "--quiet" )
QUIET=1 QUIET=1
;; ;;
@ -47,7 +63,8 @@ while [ $# -gt 0 ]; do
exec pyenv-sh-deactivate exec pyenv-sh-deactivate
;; ;;
"-v" | "--verbose" ) "-v" | "--verbose" )
VERBOSE=1 unset QUIET
PYENV_VIRTUALENV_VERBOSE_ACTIVATE=1
;; ;;
* ) * )
break break
@ -56,13 +73,18 @@ while [ $# -gt 0 ]; do
shift 1 shift 1
done done
get_current_versions() {
local IFS=:
current_versions=($(pyenv-version-name 2>/dev/null))
}
no_shell= no_shell=
versions=("$@") versions=("$@")
current_versions=()
if [ -z "${versions}" ]; then if [ -z "${versions}" ]; then
no_shell=1 no_shell=1
OLDIFS="$IFS" get_current_versions
IFS=: versions=($(pyenv-version-name 2>/dev/null)) versions=("${current_versions[@]}")
IFS="$OLDIFS"
fi fi
if [ -z "${PYENV_VIRTUALENV_INIT}" ]; then if [ -z "${PYENV_VIRTUALENV_INIT}" ]; then
@ -74,8 +96,8 @@ fi
venv="${versions}" venv="${versions}"
if [ -n "${VIRTUAL_ENV}" ]; then if [ -n "${VIRTUAL_ENV}" ]; then
# exit as success if some virtualenv is already activated outside from pyenv-virtualenv # exit as success if a non-pyenv virtualenv is active
if [ -z "${PYENV_VIRTUAL_ENV}" ]; then if [[ -z $PYENV_VIRTUAL_ENV || $PYENV_VIRTUAL_ENV != "$VIRTUAL_ENV" ]]; then
if [ -z "${FORCE}" ]; then if [ -z "${FORCE}" ]; then
if [ -z "${QUIET}" ]; then if [ -z "${QUIET}" ]; then
echo "pyenv-virtualenv: virtualenv \`${VIRTUAL_ENV}' is already activated" 1>&2 echo "pyenv-virtualenv: virtualenv \`${VIRTUAL_ENV}' is already activated" 1>&2
@ -88,9 +110,7 @@ fi
if ! pyenv-virtualenv-prefix "${venv}" 1>/dev/null 2>&1; then if ! pyenv-virtualenv-prefix "${venv}" 1>/dev/null 2>&1; then
# fallback to virtualenv of current version # fallback to virtualenv of current version
OLDIFS="$IFS" [ -n "${current_versions}" ] || get_current_versions
IFS=: current_versions=($(pyenv-version-name))
IFS="$OLDIFS"
new_venv="${current_versions%/envs/*}/envs/${venv}" new_venv="${current_versions%/envs/*}/envs/${venv}"
if pyenv-virtualenv-prefix "${new_venv}" 1>/dev/null 2>&1; then if pyenv-virtualenv-prefix "${new_venv}" 1>/dev/null 2>&1; then
venv="${new_venv}" venv="${new_venv}"
@ -136,9 +156,14 @@ if [[ "${VIRTUAL_ENV}" == "${prefix}" ]]; then
fi fi
fi fi
pyenv-sh-deactivate --force --quiet ${VERBOSE+--verbose} || true pyenv-sh-deactivate --force --quiet || true
echo "pyenv-virtualenv: activate ${venv}" 1>&2 # Execute `before_activate` hooks.
for hook in "${before_hooks[@]}"; do eval "$hook"; done
if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then
echo "pyenv-virtualenv: activate ${venv}" 1>&2
fi
if [ -z "$no_shell" ]; then if [ -z "$no_shell" ]; then
# shell version set in pyenv-sh-activate should be unset # shell version set in pyenv-sh-activate should be unset
@ -148,8 +173,8 @@ if [ -z "$no_shell" ]; then
case "$shell" in case "$shell" in
fish ) fish )
cat <<EOS cat <<EOS
setenv PYENV_VERSION "${versions[*]}"; set -gx PYENV_VERSION "${versions[*]}";
setenv PYENV_ACTIVATE_SHELL 1; set -gx PYENV_ACTIVATE_SHELL 1;
EOS EOS
;; ;;
* ) * )
@ -162,12 +187,12 @@ EOS
IFS="$OLDIFS" IFS="$OLDIFS"
fi fi
# virtualenv/pyvenv # virtualenv/venv
case "${shell}" in case "${shell}" in
fish ) fish )
cat <<EOS cat <<EOS
setenv PYENV_VIRTUAL_ENV "${prefix}"; set -gx PYENV_VIRTUAL_ENV "${prefix}";
setenv VIRTUAL_ENV "${prefix}"; set -gx VIRTUAL_ENV "${prefix}";
EOS EOS
;; ;;
* ) * )
@ -179,15 +204,16 @@ EOS
esac esac
# anaconda/miniconda # anaconda/miniconda
if [ -x "${prefix}/bin/conda" ]; then if [ -d "${prefix}/conda-meta" ] ||
if [[ "${venv}" != "${venv%/envs/*}" ]]; then [ -x "${prefix}/bin/conda" ]; then
if [[ "${prefix}" != "${prefix%/envs/*}" ]]; then
CONDA_DEFAULT_ENV="${venv##*/envs/}" CONDA_DEFAULT_ENV="${venv##*/envs/}"
else else
CONDA_DEFAULT_ENV="root" CONDA_DEFAULT_ENV="root"
fi fi
case "${shell}" in case "${shell}" in
fish ) fish )
echo "setenv CONDA_DEFAULT_ENV \"${CONDA_DEFAULT_ENV}\";" echo "set -gx CONDA_DEFAULT_ENV \"${CONDA_DEFAULT_ENV}\";"
;; ;;
* ) * )
echo "export CONDA_DEFAULT_ENV=\"${CONDA_DEFAULT_ENV}\";" echo "export CONDA_DEFAULT_ENV=\"${CONDA_DEFAULT_ENV}\";"
@ -199,7 +225,7 @@ if [ -n "${PYTHONHOME}" ]; then
case "${shell}" in case "${shell}" in
fish ) fish )
cat <<EOS cat <<EOS
setenv _OLD_VIRTUAL_PYTHONHOME "${PYTHONHOME}"; set -gx _OLD_VIRTUAL_PYTHONHOME "${PYTHONHOME}";
set -e PYTHONHOME; set -e PYTHONHOME;
EOS EOS
;; ;;
@ -218,14 +244,62 @@ PYENV_VIRTUALENV_DISABLE_PROMPT="${PYENV_VIRTUALENV_DISABLE_PROMPT:-${VIRTUAL_EN
if [ -z "${PYENV_VIRTUALENV_DISABLE_PROMPT}" ]; then if [ -z "${PYENV_VIRTUALENV_DISABLE_PROMPT}" ]; then
case "${shell}" in case "${shell}" in
fish ) fish )
echo "pyenv-virtualenv: prompt changing not work for fish." 1>&2 if [ -z "${QUIET}" ]; then
cat <<EOS
functions -e _pyenv_old_prompt # remove old prompt function if exists.
# since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(${venv}) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS
fi
;; ;;
* ) * )
echo "pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior." 1>&2 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
fi fi
# conda package anaconda/miniconda scripts (#173)
if [ -d "${prefix}/conda-meta" ] ||
[ -x "${prefix}/bin/conda" ]; then
shopt -s nullglob
case "${shell}" in
fish )
# conda 4.4 and above
for script in "${prefix}/etc/fish/conf.d"/*.fish; do
echo "source \"${script}\";"
done
;;
* )
CONDA_PREFIX="$prefix"
echo "export CONDA_PREFIX=\"${CONDA_PREFIX}\";"
for script in "${prefix}/etc/conda/activate.d"/*.sh; do
echo ". \"${script}\";"
done
# conda 4.4 and above
for script in "${prefix}/etc/profile.d"/*.sh; do
echo ". \"${script}\";"
done
;;
esac
shopt -u nullglob
fi
# Execute `after_activate` hooks.
for hook in "${after_hooks[@]}"; do eval "$hook"; done

View file

@ -15,22 +15,39 @@ fi
unset FORCE unset FORCE
unset QUIET unset QUIET
unset VERBOSE
# Define `before_deactivate` and `after_deactivate` functions that allow
# plugin hooks to register a string of code for execution before or
# after deactivating a virtualenv.
declare -a before_hooks after_hooks
before_deactivate() {
local hook="$1"
before_hooks["${#before_hooks[@]}"]="$hook"
}
after_deactivate() {
local hook="$1"
after_hooks["${#after_hooks[@]}"]="$hook"
}
# Load plugin hooks.
OLDIFS="$IFS"
IFS=$'\n' scripts=(`pyenv-hooks deactivate`)
IFS="$OLDIFS"
for script in "${scripts[@]}"; do source "$script"; done
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
"-f" | "--force" ) "-f" | "--force" )
FORCE=1 FORCE=1
;; ;;
"--no-error" )
# for backward compatibility with v20151103 and earlier
QUIET=1
;;
"-q" | "--quiet") "-q" | "--quiet")
QUIET=1 QUIET=1
;; ;;
"-v" | "--verbose" ) "-v" | "--verbose" )
VERBOSE=1 unset QUIET
PYENV_VIRTUALENV_VERBOSE_ACTIVATE=1
;; ;;
* ) * )
break break
@ -58,7 +75,30 @@ else
venv="${prefix##*/}" venv="${prefix##*/}"
fi fi
echo "pyenv-virtualenv: deactivate ${venv}" 1>&2 # Execute `before_deactivate` hooks.
for hook in "${before_hooks[@]}"; do eval "$hook"; done
if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then
echo "pyenv-virtualenv: deactivate ${venv}" 1>&2
fi
# conda package anaconda/miniconda scripts (#173)
if [ -d "${prefix}/conda-meta" ] ||
[ -x "${prefix}/bin/conda" ]; then
shopt -s nullglob
case "${shell}" in
fish )
: # conda doesn't support fish
;;
* )
for script in "${prefix}/etc/conda/deactivate.d"/*.sh; do
echo ". \"${script}\";"
done
echo "unset CONDA_PREFIX"
;;
esac
shopt -u nullglob
fi
if [ -n "${PYENV_ACTIVATE_SHELL}" ]; then if [ -n "${PYENV_ACTIVATE_SHELL}" ]; then
# shell version set in pyenv-sh-activate should be unset # shell version set in pyenv-sh-activate should be unset
@ -79,7 +119,7 @@ EOS
esac esac
fi fi
# virtualenv/pyvenv # virtualenv/venv
case "${shell}" in case "${shell}" in
fish ) fish )
cat <<EOS cat <<EOS
@ -111,14 +151,14 @@ case "${shell}" in
fish ) fish )
cat <<EOS cat <<EOS
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
EOS EOS
;; ;;
* ) * )
cat <<EOS cat <<EOS
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
@ -130,14 +170,14 @@ case "${shell}" in
fish ) fish )
cat <<EOS cat <<EOS
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
EOS EOS
;; ;;
* ) * )
cat <<EOS cat <<EOS
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
@ -147,11 +187,19 @@ esac
case "${shell}" in case "${shell}" in
fish ) fish )
: cat <<EOS
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
EOS
;; ;;
* ) * )
cat <<EOS cat <<EOS
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -175,3 +223,6 @@ fi;
EOS EOS
;; ;;
esac esac
# Execute `after_deactivate` hooks.
for hook in "${after_hooks[@]}"; do eval "$hook"; done

View file

@ -6,10 +6,14 @@
# pyenv virtualenv --version # pyenv virtualenv --version
# pyenv virtualenv --help # pyenv virtualenv --help
# #
# -f/--force Install even if the version appears to be installed already # -f/--force Install even if the version appears to be installed already. Skip
# prompting for confirmation
#
# Notable VIRTUALENV_OPTIONS passed to venv-creating executable, if applicable:
# -u/--upgrade Imply --force
# #
PYENV_VIRTUALENV_VERSION="20151229" PYENV_VIRTUALENV_VERSION="1.4.0"
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
@ -20,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
@ -50,6 +54,12 @@ parse_options() {
done done
} }
colorize() {
if [ -t 1 ]; then printf "\e[%sm%s\e[m" "$1" "$2"
else echo -n "$2"
fi
}
resolve_link() { resolve_link() {
$(type -p greadlink readlink | head -1) "$1" $(type -p greadlink readlink | head -1) "$1"
} }
@ -101,17 +111,18 @@ http_get_wget() {
} }
version() { version() {
if [[ -z "${PYENV_VERSION:-}" ]]; then
# `PYENV_VERSION` might not be declared if this was invoked via `--version`
export PYENV_VERSION="$(pyenv-version-name)"
fi
detect_venv detect_venv
local version local version
if [ -n "${USE_CONDA}" ]; then if [ -n "${USE_CONDA}" ]; then
version="$(pyenv-exec conda --version 2>/dev/null || true)" version="$(pyenv-exec conda --version 2>/dev/null || true)"
echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (conda ${version:-unknown})" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (conda ${version:-unknown})"
else else
if [ -n "$USE_PYVENV" ]; then if [ -n "$USE_M_VENV" ]; then
version="$(pyenv-which pyvenv 2>/dev/null || true)" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (${M_VENV_PYTHON_BIN:-python} -m venv)"
version="${version#${PYENV_ROOT}/versions/}"
version="${version%/bin/pyvenv}"
echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (pyvenv ${version:-unknown})"
else else
version="$(pyenv-exec virtualenv --version 2>/dev/null || true)" version="$(pyenv-exec virtualenv --version 2>/dev/null || true)"
echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (virtualenv ${version:-unknown})" echo "pyenv-virtualenv ${PYENV_VIRTUALENV_VERSION} (virtualenv ${version:-unknown})"
@ -125,8 +136,8 @@ usage() {
if [ -n "${USE_CONDA}" ]; then if [ -n "${USE_CONDA}" ]; then
pyenv-exec conda create --help 2>/dev/null || true pyenv-exec conda create --help 2>/dev/null || true
else else
if [ -n "${USE_PYVENV}" ]; then if [ -n "${USE_M_VENV}" ]; then
pyenv-exec pyvenv --help 2>/dev/null || true pyenv-exec "${M_VENV_PYTHON_BIN:-python}" -m venv --help 2>/dev/null || true
else else
pyenv-exec virtualenv --help 2>/dev/null || true pyenv-exec virtualenv --help 2>/dev/null || true
fi fi
@ -144,16 +155,30 @@ detect_venv() {
if [ -x "${prefix}/bin/virtualenv" ]; then if [ -x "${prefix}/bin/virtualenv" ]; then
HAS_VIRTUALENV=1 HAS_VIRTUALENV=1
fi fi
if [ -x "${prefix}/bin/pyvenv" ]; then local python
HAS_PYVENV=1 local -a pythons
if [[ $PYENV_VERSION == "system" ]]; then
# Prefer `python3.x` executable if available (#206, #282)
pythons=("python3" "python" "python2")
else
# as per PEP 394, custom activated Python environments should provide the "python" command
# this includes Pyenv-provided installations
pythons=("python")
fi fi
for python in "${pythons[@]}"; do
if pyenv-exec "${python}" -m venv --help 1>/dev/null 2>&1; then
HAS_M_VENV=1
M_VENV_PYTHON_BIN="${python}"
break
fi
done
fi fi
# Use pyvenv only if there is pyvenv, virtualenv is not installed, and `-p` not given # Use `python -m venv` only if there is venv available, virtualenv is not installed, and `-p` not given
if [ -n "${HAS_CONDA}" ]; then if [ -n "${HAS_CONDA}" ]; then
USE_CONDA=1 USE_CONDA=1
else else
if [ -n "${HAS_PYVENV}" ] && [ -z "${HAS_VIRTUALENV}" ] && [ -z "${VIRTUALENV_PYTHON}" ]; then if [ -n "${HAS_M_VENV}" ] && [ -z "${HAS_VIRTUALENV}" ] && [ -z "${VIRTUALENV_PYTHON}" ]; then
USE_PYVENV=1 USE_M_VENV=1
fi fi
fi fi
} }
@ -165,7 +190,7 @@ build_package_ez_setup() {
echo "Installing setuptools from ${EZ_SETUP}..." 1>&2 echo "Installing setuptools from ${EZ_SETUP}..." 1>&2
cat "${EZ_SETUP}" cat "${EZ_SETUP}"
else else
[ -n "${EZ_SETUP_URL}" ] || EZ_SETUP_URL="https://bootstrap.pypa.io/ez_setup.py" [ -n "${EZ_SETUP_URL}" ]
echo "Installing setuptools from ${EZ_SETUP_URL}..." 1>&2 echo "Installing setuptools from ${EZ_SETUP_URL}..." 1>&2
http get "${EZ_SETUP_URL}" http get "${EZ_SETUP_URL}"
fi fi
@ -183,7 +208,7 @@ build_package_get_pip() {
echo "Installing pip from ${GET_PIP}..." 1>&2 echo "Installing pip from ${GET_PIP}..." 1>&2
cat "${GET_PIP}" cat "${GET_PIP}"
else else
[ -n "${GET_PIP_URL}" ] || GET_PIP_URL="https://bootstrap.pypa.io/get-pip.py" [ -n "${GET_PIP_URL}" ]
echo "Installing pip from ${GET_PIP_URL}..." 1>&2 echo "Installing pip from ${GET_PIP_URL}..." 1>&2
http get "${GET_PIP_URL}" http get "${GET_PIP_URL}"
fi fi
@ -299,6 +324,10 @@ else
VIRTUALENV_NAME="${ARGUMENTS[1]}" VIRTUALENV_NAME="${ARGUMENTS[1]}"
fi fi
if [[ -n "${VERSION_NAME}" ]] && command -v pyenv-latest >/dev/null; then
VERSION_NAME="$(pyenv-latest -f "${VERSION_NAME}")"
fi
if [ -z "${VERSION_NAME}" ] || [ -z "${VIRTUALENV_NAME}" ]; then if [ -z "${VERSION_NAME}" ] || [ -z "${VIRTUALENV_NAME}" ]; then
usage 1 usage 1
fi fi
@ -321,10 +350,20 @@ fi
# Set VERSION_NAME as default version in this script # Set VERSION_NAME as default version in this script
export PYENV_VERSION="${VERSION_NAME}" export PYENV_VERSION="${VERSION_NAME}"
not_installed_message() {
local is_available=$(python-build --definitions | grep -F -x "$1")
echo "pyenv-virtualenv: \`${1}' is not installed in pyenv." 1>&2
if [[ $is_available ]]; then
echo "Run \`pyenv install ${1}' to install it." 1>&2
else
echo "It does not look like a valid Python version. See \`pyenv install --list' for available versions." 1>&2
fi
}
# Source version must exist before creating virtualenv. # Source version must exist before creating virtualenv.
PREFIX="$(pyenv-prefix 2>/dev/null || true)" PREFIX="$(pyenv-prefix 2>/dev/null || true)"
if [ ! -d "${PREFIX}" ]; then if [ ! -d "${PREFIX}" ]; then
echo "pyenv-virtualenv: \`${PYENV_VERSION}' is not installed in pyenv." 1>&2 not_installed_message "${PYENV_VERSION}"
exit 1 exit 1
fi fi
@ -352,16 +391,18 @@ if [[ "${VIRTUALENV_PATH/*/envs/*}" != "${PYENV_ROOT}/versions" ]]; then
fi fi
if [ -n "${COMPAT_VIRTUALENV_PATH}" ]; then if [ -n "${COMPAT_VIRTUALENV_PATH}" ]; then
if [ -e "${COMPAT_VIRTUALENV_PATH}" ] || [ -L "${COMPAT_VIRTUALENV_PATH}" ]; then if [ -z ${FORCE} ]; then
echo "pyenv-virtualenv: \`${COMPAT_VIRTUALENV_PATH}' already exists." 1>&2 if [ -e "${COMPAT_VIRTUALENV_PATH}" ] || [ -L "${COMPAT_VIRTUALENV_PATH}" ]; then
exit 1 echo "pyenv-virtualenv: \`${COMPAT_VIRTUALENV_PATH}' already exists." 1>&2
exit 1
fi
fi fi
fi fi
unset HAS_VIRTUALENV unset HAS_VIRTUALENV
unset HAS_PYVENV unset HAS_M_VENV
unset USE_CONDA unset USE_CONDA
unset USE_PYVENV unset USE_M_VENV
detect_venv detect_venv
SEED="$(date "+%Y%m%d%H%M%S").$$" SEED="$(date "+%Y%m%d%H%M%S").$$"
@ -371,13 +412,30 @@ REQUIREMENTS="${TMP}/requirements.${SEED}.txt"
# Upgrade existing virtualenv # Upgrade existing virtualenv
if [ -n "$UPGRADE" ]; then if [ -n "$UPGRADE" ]; then
FORCE=1 FORCE=1
# pyvenv has `--upgrade` by default # `python -m venv` has `--upgrade` by default
if [ -n "${USE_PYVENV}" ]; then if [ -n "${USE_M_VENV}" ]; then
unset UPGRADE unset UPGRADE
VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--upgrade" VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--upgrade"
fi fi
fi fi
if [ -z "${VIRTUALENV_VERSION}" ]; then
case "${PYENV_VERSION}" in
"3.0"* )
NO_ENSUREPIP=1
;;
"3.1"* )
NO_ENSUREPIP=1
;;
"3.2"* | "stackless-3.2"* )
# pip 8.x (bundled with virtualenv 14+) doesn't support 3.2 anymore
# https://github.com/yyuu/pyenv/issues/531
VIRTUALENV_VERSION="13.1.2"
NO_ENSUREPIP=1
;;
esac
fi
if [ -n "${USE_CONDA}" ]; then if [ -n "${USE_CONDA}" ]; then
# e.g. `conda create -n py35 python=3.5 anaconda` # e.g. `conda create -n py35 python=3.5 anaconda`
if [ -n "${VIRTUALENV_PYTHON}" ]; then if [ -n "${VIRTUALENV_PYTHON}" ]; then
@ -388,12 +446,12 @@ if [ -n "${USE_CONDA}" ]; then
fi fi
fi fi
else else
if [ -n "${USE_PYVENV}" ]; then if [ -n "${USE_M_VENV}" ]; then
# Unset some arguments not supported by pyvenv # Unset some arguments not supported by `python -m venv`
unset QUIET unset QUIET
unset VERBOSE unset VERBOSE
if [ -n "${VIRTUALENV_PYTHON}" ]; then if [ -n "${VIRTUALENV_PYTHON}" ]; then
echo "pyenv-virtualenv: \`--python=${VIRTUALENV_PYTHON}' is not supported by pyvenv." 1>&2 echo "pyenv-virtualenv: \`--python=${VIRTUALENV_PYTHON}' is not supported by \`python -m venv'." 1>&2
exit 1 exit 1
fi fi
else else
@ -407,7 +465,8 @@ else
if [ -x "${python}" ]; then if [ -x "${python}" ]; then
VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--python=${python}" VIRTUALENV_OPTIONS[${#VIRTUALENV_OPTIONS[*]}]="--python=${python}"
else else
echo "pyenv-virtualenv: \`${VIRTUALENV_PYTHON##*/}' is not installed in pyenv." 1>&2 # echo "pyenv-virtualenv: \`${VIRTUALENV_PYTHON##*/}' is not installed in pyenv." 1>&2
not_installed_message "${VIRTUALENV_PYTHON##*/}"
exit 1 exit 1
fi fi
fi fi
@ -416,8 +475,12 @@ else
fi fi
fi fi
if [ -z "${HAS_VIRTUALENV}" ]; then if [ -z "${HAS_VIRTUALENV}" ]; then
VIRTUALENV_VERSION="==${VIRTUALENV_VERSION}" if [ -n "${VIRTUALENV_VERSION}" ]; then
pyenv-exec pip install $QUIET $VERBOSE "virtualenv${VIRTUALENV_VERSION%==}" virtualenv_spec="virtualenv==${VIRTUALENV_VERSION}"
else
virtualenv_spec="virtualenv"
fi
pyenv-exec pip install $QUIET $VERBOSE "${virtualenv_spec}"
HAS_VIRTUALENV=1 HAS_VIRTUALENV=1
fi fi
fi fi
@ -429,11 +492,51 @@ unset VIRTUALENV_VERSION
# Download specified version of ez_setup.py/get-pip.py. # Download specified version of ez_setup.py/get-pip.py.
if [ -n "${SETUPTOOLS_VERSION}" ]; then if [ -z "${EZ_SETUP_URL}" ]; then
EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION}/ez_setup.py" if [ -n "${SETUPTOOLS_VERSION}" ]; then
EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION}/ez_setup.py"
unset SETUPTOOLS_VERSION
else
EZ_SETUP_URL="https://bootstrap.pypa.io/ez_setup.py"
fi
fi fi
if [ -n "${PIP_VERSION}" ]; then if [ -z "${GET_PIP_URL}" ]; then
GET_PIP_URL="https://raw.githubusercontent.com/pypa/pip/${PIP_VERSION}/contrib/get-pip.py" if [ -n "${PIP_VERSION}" ]; then
{ colorize 1 "WARNING"
echo ": Setting PIP_VERSION=${PIP_VERSION} is no longer supported and may cause failures during the install process."
} 1>&2
GET_PIP_URL="https://raw.githubusercontent.com/pypa/pip/${PIP_VERSION}/contrib/get-pip.py"
# Unset `PIP_VERSION` from environment before invoking `get-pip.py` to deal with "ValueError: invalid truth value" (pypa/pip#4528)
unset PIP_VERSION
else
# Use custom get-pip URL based on the target version (#1127)
case "${PYENV_VERSION}" in
2.6 | 2.6.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/2.6/get-pip.py"
;;
2.7 | 2.7.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/2.7/get-pip.py"
;;
3.2 | 3.2.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.2/get-pip.py"
;;
3.3 | 3.3.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.3/get-pip.py"
;;
3.4 | 3.4.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.4/get-pip.py"
;;
3.5 | 3.5.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.5/get-pip.py"
;;
3.6 | 3.6.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.6/get-pip.py"
;;
* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/get-pip.py"
;;
esac
fi
fi fi
@ -489,10 +592,11 @@ for hook in "${before_hooks[@]}"; do eval "$hook"; done
# Plan cleanup on unsuccessful installation. # Plan cleanup on unsuccessful installation.
cleanup() { cleanup() {
[[ -L "${COMPAT_VIRTUALENV_PATH}" ]] && rm "${COMPAT_VIRTUALENV_PATH}"
[ -z "${PREFIX_EXISTS}" ] && rm -rf "$VIRTUALENV_PATH" [ -z "${PREFIX_EXISTS}" ] && rm -rf "$VIRTUALENV_PATH"
} }
trap cleanup SIGINT trap cleanup SIGINT ERR
# Invoke virtualenv and record exit status in $STATUS. # Invoke virtualenv and record exit status in $STATUS.
STATUS=0 STATUS=0
@ -501,18 +605,45 @@ 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_PYVENV}" ]; then if [ -n "${USE_M_VENV}" ]; then
pyenv-exec pyvenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" pyenv-exec "${M_VENV_PYTHON_BIN:-python}" -m venv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?"
else else
pyenv-exec virtualenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?" pyenv-exec virtualenv $QUIET $VERBOSE "${VIRTUALENV_OPTIONS[@]}" "${VIRTUALENV_PATH}" || STATUS="$?"
fi fi
fi fi
(
shopt -s nullglob
for extra_binary in "$PREFIX"/bin/python*-config; do
extra_binary_linkname="$VIRTUALENV_PATH/bin/$(basename $extra_binary)"
[[ -e "$extra_binary_linkname" ]] || \
ln -s "$extra_binary" "$extra_binary_linkname"
done
)
## 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
if [ ! -e "${VIRTUALENV_PATH}/bin/pydoc" ]; then
mkdir -p "${VIRTUALENV_PATH}/bin"
cat <<EOS > "${VIRTUALENV_PATH}/bin/pydoc"
#!${VIRTUALENV_PATH}/bin/python
import pydoc
if __name__ == '__main__':
pydoc.cli()
EOS
chmod +x "${VIRTUALENV_PATH}/bin/pydoc"
fi fi
if [ -z "${NO_ENSUREPIP}" ]; then if [ -z "${NO_ENSUREPIP}" ]; then

View file

@ -55,50 +55,54 @@ 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
else 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
fi fi
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? " 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

View file

@ -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"
} }
@ -45,12 +62,13 @@ if [ -z "$shell" ]; then
shell="${shell%% *}" shell="${shell%% *}"
shell="${shell:-$SHELL}" shell="${shell:-$SHELL}"
shell="${shell##*/}" shell="${shell##*/}"
shell="${shell%%-*}"
fi fi
if [ -z "$print" ]; then if [ -z "$print" ]; then
case "$shell" in case "$shell" in
bash ) bash )
profile='~/.bash_profile' profile='~/.bashrc'
;; ;;
zsh ) zsh )
profile='~/.zshrc' profile='~/.zshrc'
@ -71,7 +89,7 @@ if [ -z "$print" ]; then
echo echo
case "$shell" in case "$shell" in
fish ) fish )
echo 'status --is-interactive; and . (pyenv virtualenv-init -|psub)' echo 'status --is-interactive; and source (pyenv virtualenv-init -|psub)'
;; ;;
* ) * )
echo 'eval "$(pyenv virtualenv-init -)"' echo 'eval "$(pyenv virtualenv-init -)"'
@ -86,13 +104,15 @@ fi
case "$shell" in case "$shell" in
fish ) fish )
cat <<EOS cat <<EOS
setenv PATH '${PYENV_VIRTUALENV_ROOT:-${PYENV_VIRTUALENV_INSTALL_PREFIX}}/shims' \$PATH; while set index (contains -i -- "${PYENV_VIRTUALENV_ROOT:-${PYENV_VIRTUALENV_INSTALL_PREFIX}}/shims" \$PATH)
setenv PYENV_VIRTUALENV_INIT 1; set -eg PATH[\$index]; end; set -e index
set -gx PATH '${PYENV_VIRTUALENV_ROOT:-${PYENV_VIRTUALENV_INSTALL_PREFIX}}/shims' \$PATH;
set -gx PYENV_VIRTUALENV_INIT 1;
EOS EOS
;; ;;
* ) * )
cat <<EOS cat <<EOS
export PATH="${PYENV_VIRTUALENV_ROOT:-${PYENV_VIRTUALENV_INSTALL_PREFIX}}/shims:${PATH}"; export PATH="${PYENV_VIRTUALENV_ROOT:-${PYENV_VIRTUALENV_INSTALL_PREFIX}}/shims:\${PATH}";
export PYENV_VIRTUALENV_INIT=1; export PYENV_VIRTUALENV_INIT=1;
EOS EOS
;; ;;
@ -103,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=\$?
if [ -n "\$VIRTUAL_ENV" ]; then 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
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

View file

@ -6,18 +6,46 @@
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
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() {
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}")
else
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
exit 1
fi
}
VIRTUALENV_PREFIX_PATHS=() VIRTUALENV_PREFIX_PATHS=()
for version in "${versions[@]}"; do for version in "${versions[@]}"; do
@ -25,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
@ -33,7 +72,7 @@ for version in "${versions[@]}"; do
VIRTUALENV_PREFIX_PATH="${PYENV_PREFIX_PATH}" VIRTUALENV_PREFIX_PATH="${PYENV_PREFIX_PATH}"
else else
if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then
# pyvenv # venv
virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)" virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)"
VIRTUALENV_PREFIX_PATH="${virtualenv_binpath%/bin}" VIRTUALENV_PREFIX_PATH="${virtualenv_binpath%/bin}"
else else
@ -55,12 +94,11 @@ for version in "${versions[@]}"; do
fi fi
fi fi
fi fi
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then append_virtualenv_prefix
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}") elif [ -d "${PYENV_PREFIX_PATH}/conda-meta" ]; then
else # conda
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2 VIRTUALENV_PREFIX_PATH="$(realpath "${PYENV_PREFIX_PATH}"/../..)"
exit 1 append_virtualenv_prefix
fi
else else
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
@ -71,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"

View file

@ -6,9 +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 [ -z "$PYENV_ROOT" ]; then if [[ -z $PYENV_ROOT ]]; then
PYENV_ROOT="${HOME}/.pyenv" PYENV_ROOT="${HOME}/.pyenv"
fi fi
@ -32,60 +32,26 @@ done
versions_dir="${PYENV_ROOT}/versions" versions_dir="${PYENV_ROOT}/versions"
if ! enable -f "${BASH_SOURCE%/*}"/../libexec/pyenv-realpath.dylib realpath 2>/dev/null; then if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then
if [ -n "$PYENV_NATIVE_EXT" ]; then declare -A current_versions
echo "pyenv: failed to load \`realpath' builtin" >&2
exit 1
fi
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 "$1"
}
realpath() {
local cwd="$PWD"
local path="$1"
local name
while [ -n "$path" ]; do
name="${path##*/}"
[ "$name" = "$path" ] || cd "${path%/*}"
path="$(resolve_link "$name" || true)"
done
echo "${PWD}/$name"
cd "$cwd"
}
fi
if [ -d "$versions_dir" ]; then
versions_dir="$(realpath "$versions_dir")"
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
@ -99,37 +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 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
shopt -u nullglob
if [ "$num_versions" -eq 0 ] && [ -n "$include_system" ]; then for env_path in "${version_dir_entries[@]}"; do
echo "Warning: no Python virtualenv detected on the system" >&2 if [[ -d ${env_path} ]]; then
exit 1 if [[ -L ${env_path} ]]; then
fi 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 nullglob

View file

@ -2,29 +2,31 @@ resolve_link() {
$(type -p greadlink readlink | head -1) "$1" $(type -p greadlink readlink | head -1) "$1"
} }
if [ -n "${DEFINITION}" ]; then uninstall_related_virtual_env() {
if [[ "${DEFINITION}" != "${DEFINITION%/envs/*}" ]]; then if [ -n "${DEFINITION}" ]; then
# Uninstall virtualenv by long name if [[ "${DEFINITION}" != "${DEFINITION%/envs/*}" ]]; then
exec pyenv-virtualenv-delete ${FORCE+-f} "${DEFINITION}" # Uninstall virtualenv by long name
exit 128 pyenv-virtualenv-delete ${FORCE+-f} "${DEFINITION}"
else
VERSION_NAME="${VERSION_NAME:-${DEFINITION##*/}}"
PREFIX="${PREFIX:-${PYENV_ROOT}/versions/${VERSION_NAME}}"
if [ -L "${PREFIX}" ]; then
REAL_PREFIX="$(resolve_link "${PREFIX}" 2>/dev/null || true)"
REAL_DEFINITION="${REAL_PREFIX#${PYENV_ROOT}/versions/}"
if [[ "${REAL_DEFINITION}" != "${REAL_DEFINITION%/envs/*}" ]]; then
# Uninstall virtualenv by short name
exec pyenv-virtualenv-delete ${FORCE+-f} "${REAL_DEFINITION}"
exit 128
fi
else else
# Uninstall all virtualenvs inside `envs` directory too VERSION_NAME="${VERSION_NAME:-${DEFINITION##*/}}"
shopt -s nullglob PREFIX="${PREFIX:-${PYENV_ROOT}/versions/${VERSION_NAME}}"
for virtualenv in "${PREFIX}/envs/"*; do if [ -L "${PREFIX}" ]; then
pyenv-virtualenv-delete ${FORCE+-f} "${DEFINITION}/envs/${virtualenv##*/}" REAL_PREFIX="$(resolve_link "${PREFIX}" 2>/dev/null || true)"
done REAL_DEFINITION="${REAL_PREFIX#${PYENV_ROOT}/versions/}"
shopt -u nullglob if [[ "${REAL_DEFINITION}" != "${REAL_DEFINITION%/envs/*}" ]]; then
# Uninstall virtualenv by short name
pyenv-virtualenv-delete ${FORCE+-f} "${REAL_DEFINITION}"
fi
else
# Uninstall all virtualenvs inside `envs` directory too
shopt -s nullglob
for virtualenv in "${PREFIX}/envs/"*; do
pyenv-virtualenv-delete ${FORCE+-f} "${DEFINITION}/envs/${virtualenv##*/}"
done
shopt -u nullglob
fi
fi fi
fi fi
fi }
before_uninstall "uninstall_related_virtual_env"

View file

@ -0,0 +1,11 @@
# newer versions of conda share programs from the real prefix
# this hook tries to find the executable there
if [ ! -x "${PYENV_COMMAND_PATH}" ] && [[ "${PYENV_COMMAND_PATH##*/}" == "conda" ]]; then
if [ -d "${PYENV_ROOT}/versions/${version}/conda-meta" ]; then
conda_command_path="$(pyenv-virtualenv-prefix "$version")"/bin/"${PYENV_COMMAND_PATH##*/}"
if [ -x "${conda_command_path}" ]; then
PYENV_COMMAND_PATH="${conda_command_path}"
fi
fi
fi

View file

@ -12,8 +12,8 @@ if [ ! -x "${PYENV_COMMAND_PATH}" ] && [[ "${PYENV_COMMAND_PATH##*/}" == "python
if [ -f "${PYENV_ROOT}/versions/${version}/bin/conda" ]; then if [ -f "${PYENV_ROOT}/versions/${version}/bin/conda" ]; then
: # do nothing for conda's environments : # do nothing for conda's environments
else else
if [ -f "${PYENV_ROOT}/versions/${version}/bin/pyvenv.cfg" ]; then if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then
# pyvenv # venv
virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)" virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)"
virtualenv_prefix="${virtualenv_binpath%/bin}" virtualenv_prefix="${virtualenv_binpath%/bin}"
else else

View file

@ -14,7 +14,7 @@ if [ ! -x "${PYENV_COMMAND_PATH}" ]; then
: # do nothing for conda's environments : # do nothing for conda's environments
else else
if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then if [ -f "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" ]; then
# pyvenv # venv
virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)" virtualenv_binpath="$(cut -b 1-1024 "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" | sed -n '/^ *home *= */s///p' || true)"
virtualenv_prefix="${virtualenv_binpath%/bin}" virtualenv_prefix="${virtualenv_binpath%/bin}"
if grep -q -i "include-system-site-packages *= *true" "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" 1>/dev/null 2>&1; then if grep -q -i "include-system-site-packages *= *true" "${PYENV_ROOT}/versions/${version}/pyvenv.cfg" 1>/dev/null 2>&1; then
@ -37,8 +37,12 @@ if [ ! -x "${PYENV_COMMAND_PATH}" ]; then
if [ ! -f "${no_global_site_packages}" ]; then if [ ! -f "${no_global_site_packages}" ]; then
include_system_site_packages=1 include_system_site_packages=1
fi fi
virtualenv_orig_prefix="$(find "${virtualenv_libpath}/" -maxdepth 2 -type f -and -name "orig-prefix.txt" 2>/dev/null | head -1)"
if [ -f "${virtualenv_orig_prefix}" ]; then
virtualenv_prefix="$(cat "${virtualenv_orig_prefix}" 2>/dev/null || true)"
fi
fi fi
if [ -n "${include_system_site_packages}" ]; then if [ -n "${include_system_site_packages}" ] && [ -n "${virtualenv_prefix}" ]; then
# virtualenv is created with `--system-site-packages` # virtualenv is created with `--system-site-packages`
virtualenv_command_path="${virtualenv_prefix}/bin/${PYENV_COMMAND_PATH##*/}" virtualenv_command_path="${virtualenv_prefix}/bin/${PYENV_COMMAND_PATH##*/}"
if [ -x "${virtualenv_command_path}" ]; then if [ -x "${virtualenv_command_path}" ]; then

View file

@ -12,14 +12,17 @@ if [ -z "${PREFIX}" ]; then
fi fi
BIN_PATH="${PREFIX}/bin" BIN_PATH="${PREFIX}/bin"
LIBEXEC_PATH="${PREFIX}/libexec"
SHIMS_PATH="${PREFIX}/shims" SHIMS_PATH="${PREFIX}/shims"
HOOKS_PATH="${PREFIX}/etc/pyenv.d" HOOKS_PATH="${PREFIX}/etc/pyenv.d"
mkdir -p "$BIN_PATH" mkdir -p "$BIN_PATH"
mkdir -p "$LIBEXEC_PATH"
mkdir -p "$SHIMS_PATH" mkdir -p "$SHIMS_PATH"
mkdir -p "$HOOKS_PATH" mkdir -p "$HOOKS_PATH"
install -p bin/* "$BIN_PATH" install -p bin/* "$BIN_PATH"
install -p libexec/* "$LIBEXEC_PATH"
install -p shims/* "$SHIMS_PATH" install -p shims/* "$SHIMS_PATH"
for hook in etc/pyenv.d/*; do for hook in etc/pyenv.d/*; do
if [ -d "$hook" ]; then if [ -d "$hook" ]; then

View file

@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Summary: Substitute realpath if unavailable as a builtin or file
# Usage: . pyenv-virtualenv-realpath
if ! {
enable -f "${BASH_SOURCE%/*}"/../../../libexec/pyenv-realpath.dylib realpath ||
type realpath
} >/dev/null 2>&1; then
if [ -n "$PYENV_NATIVE_EXT" ]; then
echo "pyenv: failed to load \`realpath' builtin" >&2
exit 1
fi
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 "$1"
}
realpath() {
local f="$*" \
name dir
[[ $f ]] || {
>&2 echo ${FUNCNAME[0]}: missing operand
return
}
while [[ -L $f ]]; do
f="$(resolve_link "$f")"
done
if [[ ! -d $f ]]; then
name="/${f##*/}"
# parent?
dir="${f%/*}"
if [[ $dir == $f ]]; then
#lacks /: parent is current directory
f="$PWD"
else
f="$dir"
fi
fi
#absolute directory
dir="$(cd "$f"
pwd)"
echo "$dir$name"
}
fi

View file

@ -11,10 +11,13 @@ setup() {
unset CONDA_DEFAULT_ENV unset CONDA_DEFAULT_ENV
unset PYTHONHOME unset PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME
unset PYENV_VIRTUALENV_VERBOSE_ACTIVATE
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"
} }
@test "activate virtualenv from current version" { @test "activate virtualenv from current version" {
@ -30,12 +33,60 @@ setup() {
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv) \${PS1:-}";
export PS1="(venv) \${PS1}"; EOS
unstub pyenv-version-name
unstub pyenv-virtualenv-prefix
unstub pyenv-prefix
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)" {
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" run pyenv-sh-activate --quiet
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) \${PS1:-}";
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -46,11 +97,12 @@ EOS
@test "activate virtualenv from current version (verbose)" { @test "activate virtualenv from current version (verbose)" {
export PYENV_VIRTUALENV_INIT=1 export PYENV_VIRTUALENV_INIT=1
export PYENV_VIRTUALENV_VERBOSE_ACTIVATE=1
stub pyenv-version-name "echo venv" stub pyenv-version-name "echo venv"
stub pyenv-virtualenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\"" stub pyenv-virtualenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
stub pyenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\"" stub pyenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
stub pyenv-sh-deactivate "--force --quiet --verbose : echo deactivated" stub pyenv-sh-deactivate "--force --quiet : echo deactivated"
PYENV_SHELL="bash" PYENV_VERSION="venv" run pyenv-sh-activate --verbose PYENV_SHELL="bash" PYENV_VERSION="venv" run pyenv-sh-activate --verbose
@ -60,9 +112,8 @@ deactivated
pyenv-virtualenv: activate venv pyenv-virtualenv: activate venv
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv) \${PS1:-}";
export PS1="(venv) \${PS1}";
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -84,14 +135,12 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv
export PYENV_VERSION="venv"; export PYENV_VERSION="venv";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv) \${PS1:-}";
export PS1="(venv) \${PS1}";
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -113,10 +162,20 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv set -gx PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv";
setenv PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv"; set -gx VIRTUAL_ENV "${PYENV_ROOT}/versions/venv";
setenv VIRTUAL_ENV "${PYENV_ROOT}/versions/venv"; functions -e _pyenv_old_prompt # remove old prompt function if exists.
pyenv-virtualenv: prompt changing not work for fish. # since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(venv) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -138,12 +197,22 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv set -gx PYENV_VERSION "venv";
setenv PYENV_VERSION "venv"; set -gx PYENV_ACTIVATE_SHELL 1;
setenv PYENV_ACTIVATE_SHELL 1; set -gx PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv";
setenv PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv"; set -gx VIRTUAL_ENV "${PYENV_ROOT}/versions/venv";
setenv VIRTUAL_ENV "${PYENV_ROOT}/versions/venv"; functions -e _pyenv_old_prompt # remove old prompt function if exists.
pyenv-virtualenv: prompt changing not work for fish. # since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(venv) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -164,14 +233,12 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv27
export PYENV_VERSION="venv27"; export PYENV_VERSION="venv27";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv27) \${PS1:-}";
export PS1="(venv27) \${PS1}";
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -191,14 +258,12 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv27
export PYENV_VERSION="venv27"; export PYENV_VERSION="venv27";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv27) \${PS1:-}";
export PS1="(venv27) \${PS1}";
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -218,12 +283,22 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv27 set -gx PYENV_VERSION "venv27";
setenv PYENV_VERSION "venv27"; set -gx PYENV_ACTIVATE_SHELL 1;
setenv PYENV_ACTIVATE_SHELL 1; set -gx PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27";
setenv PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27"; set -gx VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27";
setenv VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27"; functions -e _pyenv_old_prompt # remove old prompt function if exists.
pyenv-virtualenv: prompt changing not work for fish. # since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(venv27) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -243,12 +318,22 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv27 set -gx PYENV_VERSION "venv27";
setenv PYENV_VERSION "venv27"; set -gx PYENV_ACTIVATE_SHELL 1;
setenv PYENV_ACTIVATE_SHELL 1; set -gx PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27";
setenv PYENV_VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27"; set -gx VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27";
setenv VIRTUAL_ENV "${PYENV_ROOT}/versions/venv27"; functions -e _pyenv_old_prompt # remove old prompt function if exists.
pyenv-virtualenv: prompt changing not work for fish. # since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(venv27) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -362,19 +447,17 @@ EOS
stub pyenv-virtualenv-prefix "2.7.10 : false" stub pyenv-virtualenv-prefix "2.7.10 : false"
stub pyenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/venv27\"" stub pyenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/venv27\""
run pyenv-sh-activate "venv27" "2.7.10" PYENV_SHELL="bash" run pyenv-sh-activate "venv27" "2.7.10"
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate venv27
export PYENV_VERSION="venv27:2.7.10"; export PYENV_VERSION="venv27:2.7.10";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv27";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(venv27) \${PS1:-}";
export PS1="(venv27) \${PS1}";
EOS EOS
unstub pyenv-sh-deactivate unstub pyenv-sh-deactivate
@ -382,6 +465,34 @@ EOS
unstub pyenv-prefix unstub pyenv-prefix
} }
@test "do nothing if a 3rd-party virtualenv is active" {
export PYENV_VIRTUALENV_INIT=1
export VIRTUAL_ENV="${TMP}/venv-3rd-party"
unset PYENV_VIRTUAL_ENV
PYENV_SHELL="bash" run pyenv-sh-activate "venv"
assert_success
assert_output <<EOS
pyenv-virtualenv: virtualenv \`${TMP}/venv-3rd-party' is already activated
true
EOS
}
@test "do nothing if a 3rd-party virtualenv is active over ours" {
export PYENV_VIRTUALENV_INIT=1
export VIRTUAL_ENV="${TMP}/venv-3rd-party"
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
PYENV_SHELL="bash" run pyenv-sh-activate "venv"
assert_success
assert_output <<EOS
pyenv-virtualenv: virtualenv \`${TMP}/venv-3rd-party' is already activated
true
EOS
}
@test "should fail if activate is invoked as a command" { @test "should fail if activate is invoked as a command" {
run pyenv-activate run pyenv-activate

View file

@ -12,10 +12,17 @@ setup() {
unset CONDA_DEFAULT_ENV unset CONDA_DEFAULT_ENV
unset PYTHONHOME unset PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME
unset PYENV_VIRTUALENV_VERBOSE_ACTIVATE
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"
}
teardown() {
unstub pyenv-hooks
} }
@test "activate conda root from current version" { @test "activate conda root from current version" {
@ -32,13 +39,41 @@ setup() {
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate anaconda-2.3.0
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0";
export 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 CONDA_DEFAULT_ENV="root";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(anaconda-2.3.0) \${PS1:-}";
export PS1="(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 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 EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -62,11 +97,21 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate anaconda-2.3.0 set -gx PYENV_VIRTUAL_ENV "${TMP}/pyenv/versions/anaconda-2.3.0";
setenv PYENV_VIRTUAL_ENV "${TMP}/pyenv/versions/anaconda-2.3.0"; set -gx VIRTUAL_ENV "${TMP}/pyenv/versions/anaconda-2.3.0";
setenv VIRTUAL_ENV "${TMP}/pyenv/versions/anaconda-2.3.0"; set -gx CONDA_DEFAULT_ENV "root";
setenv CONDA_DEFAULT_ENV "root"; functions -e _pyenv_old_prompt # remove old prompt function if exists.
pyenv-virtualenv: prompt changing not work for fish. # since everything is in memory, it's safe to
# remove it.
functions -c fish_prompt _pyenv_old_prompt # backup old prompt function
# from python-venv
function fish_prompt
set -l prompt (_pyenv_old_prompt) # call old prompt function first since it might
# read exit status
echo -n "(anaconda-2.3.0) " # add virtualenv to prompt
string join -- \n \$prompt # handle multiline prompts
end
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -90,15 +135,14 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate miniconda-3.9.1
export PYENV_VERSION="miniconda-3.9.1"; export PYENV_VERSION="miniconda-3.9.1";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1";
export CONDA_DEFAULT_ENV="root"; export CONDA_DEFAULT_ENV="root";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(miniconda-3.9.1) \${PS1:-}";
export PS1="(miniconda-3.9.1) \${PS1}"; export CONDA_PREFIX="${TMP}/pyenv/versions/miniconda-3.9.1";
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -122,13 +166,13 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate anaconda-2.3.0/envs/foo
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo";
export CONDA_DEFAULT_ENV="foo"; export CONDA_DEFAULT_ENV="foo";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(anaconda-2.3.0/envs/foo) \${PS1:-}";
export PS1="(anaconda-2.3.0/envs/foo) \${PS1}"; export CONDA_PREFIX="${TMP}/pyenv/versions/anaconda-2.3.0/envs/foo";
. "${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo/etc/conda/activate.d/activate.sh";
EOS EOS
unstub pyenv-version-name unstub pyenv-version-name
@ -152,15 +196,15 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
deactivated deactivated
pyenv-virtualenv: activate miniconda-3.9.1/envs/bar
export PYENV_VERSION="miniconda-3.9.1/envs/bar"; export PYENV_VERSION="miniconda-3.9.1/envs/bar";
export PYENV_ACTIVATE_SHELL=1; export PYENV_ACTIVATE_SHELL=1;
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1/envs/bar"; export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1/envs/bar";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1/envs/bar"; export VIRTUAL_ENV="${PYENV_ROOT}/versions/miniconda-3.9.1/envs/bar";
export CONDA_DEFAULT_ENV="bar"; export CONDA_DEFAULT_ENV="bar";
pyenv-virtualenv: prompt changing will be removed from future release. configure \`export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. export _OLD_VIRTUAL_PS1="\${PS1:-}";
export _OLD_VIRTUAL_PS1="\${PS1}"; export PS1="(miniconda-3.9.1/envs/bar) \${PS1:-}";
export PS1="(miniconda-3.9.1/envs/bar) \${PS1}"; export CONDA_PREFIX="${TMP}/pyenv/versions/miniconda-3.9.1/envs/bar";
. "${PYENV_ROOT}/versions/miniconda-3.9.1/envs/bar/etc/conda/activate.d/activate.sh";
EOS EOS
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix

View file

@ -11,10 +11,16 @@ setup() {
unset CONDA_DEFAULT_ENV unset CONDA_DEFAULT_ENV
unset PYTHONHOME unset PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME
unset PYENV_VIRTUALENV_VERBOSE_ACTIVATE
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 _OLD_VIRTUAL_PS1 unset _OLD_VIRTUAL_PS1
stub pyenv-hooks "deactivate : echo"
}
teardown() {
unstub pyenv-hooks
} }
@test "deactivate conda root" { @test "deactivate conda root" {
@ -29,19 +35,19 @@ setup() {
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate anaconda-2.3.0 unset CONDA_PREFIX
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
unset CONDA_DEFAULT_ENV; unset CONDA_DEFAULT_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -65,18 +71,24 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate anaconda-2.3.0
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
set -e CONDA_DEFAULT_ENV; set -e CONDA_DEFAULT_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;
@ -97,19 +109,20 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate anaconda-2.3.0/envs/foo . "${PYENV_ROOT}/versions/anaconda-2.3.0/envs/foo/etc/conda/deactivate.d/deactivate.sh";
unset CONDA_PREFIX
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
unset CONDA_DEFAULT_ENV; unset CONDA_DEFAULT_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;

View file

@ -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"
} }

View file

@ -26,21 +26,22 @@ 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
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "miniconda3-3.16.0" teardown_m_venv "miniconda3-3.16.0"
} }
@test "create virtualenv by conda create with -p" { @test "create virtualenv by conda create with -p" {
@ -49,21 +50,21 @@ 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
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "miniconda3-3.16.0" teardown_m_venv "miniconda3-3.16.0"
} }
@test "create virtualenv by conda create with --python" { @test "create virtualenv by conda create with --python" {
@ -72,19 +73,19 @@ 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
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "miniconda3-3.16.0" teardown_m_venv "miniconda3-3.16.0"
} }

View file

@ -11,10 +11,12 @@ setup() {
unset CONDA_DEFAULT_ENV unset CONDA_DEFAULT_ENV
unset PYTHONHOME unset PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME
unset PYENV_VIRTUALENV_VERBOSE_ACTIVATE
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 _OLD_VIRTUAL_PS1 unset _OLD_VIRTUAL_PS1
stub pyenv-hooks "deactivate : echo"
} }
@test "deactivate virtualenv" { @test "deactivate virtualenv" {
@ -27,49 +29,17 @@ setup() {
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1;
fi;
if declare -f deactivate 1>/dev/null 2>&1; then
unset -f deactivate;
fi;
EOS
}
@test "deactivate virtualenv (verbose)" {
export PYENV_VIRTUALENV_INIT=1
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export PYENV_ACTIVATE_SHELL=
PYENV_SHELL="bash" run pyenv-sh-deactivate --verbose
assert_success
assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH;
fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME;
fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -89,18 +59,49 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1;
fi;
if declare -f deactivate 1>/dev/null 2>&1; then
unset -f deactivate;
fi;
EOS
}
@test "deactivate virtualenv (verbose)" {
export PYENV_VIRTUALENV_INIT=1
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export PYENV_ACTIVATE_SHELL=
export PYENV_VIRTUALENV_VERBOSE_ACTIVATE=1
PYENV_SHELL="bash" run pyenv-sh-deactivate --verbose
assert_success
assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH;
fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME;
fi;
if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -120,20 +121,19 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VERSION; unset PYENV_VERSION;
unset PYENV_ACTIVATE_SHELL; unset PYENV_ACTIVATE_SHELL;
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -153,20 +153,19 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VERSION; unset PYENV_VERSION;
unset PYENV_ACTIVATE_SHELL; unset PYENV_ACTIVATE_SHELL;
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -186,18 +185,17 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
unset PYENV_VIRTUAL_ENV; unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV; unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH}" ]; then if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}"; export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH; unset _OLD_VIRTUAL_PATH;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME}" ]; then if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}"; export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME; unset _OLD_VIRTUAL_PYTHONHOME;
fi; fi;
if [ -n "\${_OLD_VIRTUAL_PS1}" ]; then if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}"; export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1; unset _OLD_VIRTUAL_PS1;
fi; fi;
@ -217,17 +215,23 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;
@ -244,17 +248,23 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;
@ -271,19 +281,25 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
set -e PYENV_VERSION; set -e PYENV_VERSION;
set -e PYENV_ACTIVATE_SHELL; set -e PYENV_ACTIVATE_SHELL;
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;
@ -300,19 +316,25 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
set -e PYENV_VERSION; set -e PYENV_VERSION;
set -e PYENV_ACTIVATE_SHELL; set -e PYENV_ACTIVATE_SHELL;
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;
@ -329,17 +351,23 @@ EOS
assert_success assert_success
assert_output <<EOS assert_output <<EOS
pyenv-virtualenv: deactivate venv
set -e PYENV_VIRTUAL_ENV; set -e PYENV_VIRTUAL_ENV;
set -e VIRTUAL_ENV; set -e VIRTUAL_ENV;
if [ -n "\$_OLD_VIRTUAL_PATH" ]; if [ -n "\$_OLD_VIRTUAL_PATH" ];
setenv PATH "\$_OLD_VIRTUAL_PATH"; set -gx PATH "\$_OLD_VIRTUAL_PATH";
set -e _OLD_VIRTUAL_PATH; set -e _OLD_VIRTUAL_PATH;
end; end;
if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ]; if [ -n "\$_OLD_VIRTUAL_PYTHONHOME" ];
setenv PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME"; set -gx PYTHONHOME "\$_OLD_VIRTUAL_PYTHONHOME";
set -e _OLD_VIRTUAL_PYTHONHOME; set -e _OLD_VIRTUAL_PYTHONHOME;
end; end;
# check if old prompt function exists
if functions -q _pyenv_old_prompt
# remove old prompt function if exists.
functions -e fish_prompt
functions -c _pyenv_old_prompt fish_prompt
functions -e _pyenv_old_prompt
end
if functions -q deactivate; if functions -q deactivate;
functions -e deactivate; functions -e deactivate;
end; end;

View file

@ -23,8 +23,8 @@ setup() {
} }
@test "delete virtualenv by symlink" { @test "delete virtualenv by symlink" {
mkdir -p "${PYENV_ROOT}/versions/2.7.10/envs/venv27" mkdir -p "${PYENV_ROOT}/versions/2.7.11/envs/venv27"
ln -fs "${PYENV_ROOT}/versions/2.7.10/envs/venv27" "${PYENV_ROOT}/versions/venv27" ln -fs "${PYENV_ROOT}/versions/2.7.11/envs/venv27" "${PYENV_ROOT}/versions/venv27"
stub pyenv-rehash "true" stub pyenv-rehash "true"
@ -34,55 +34,55 @@ setup() {
unstub pyenv-rehash unstub pyenv-rehash
[ ! -d "${PYENV_ROOT}/versions/2.7.10/envs/venv27" ] [ ! -d "${PYENV_ROOT}/versions/2.7.11/envs/venv27" ]
[ ! -L "${PYENV_ROOT}/versions/venv27" ] [ ! -L "${PYENV_ROOT}/versions/venv27" ]
} }
@test "delete virtualenv with symlink" { @test "delete virtualenv with symlink" {
mkdir -p "${PYENV_ROOT}/versions/2.7.10/envs/venv27" mkdir -p "${PYENV_ROOT}/versions/2.7.11/envs/venv27"
ln -fs "${PYENV_ROOT}/versions/2.7.10/envs/venv27" "${PYENV_ROOT}/versions/venv27" ln -fs "${PYENV_ROOT}/versions/2.7.11/envs/venv27" "${PYENV_ROOT}/versions/venv27"
stub pyenv-rehash "true" stub pyenv-rehash "true"
run pyenv-virtualenv-delete -f "2.7.10/envs/venv27" run pyenv-virtualenv-delete -f "2.7.11/envs/venv27"
assert_success assert_success
unstub pyenv-rehash unstub pyenv-rehash
[ ! -d "${PYENV_ROOT}/versions/2.7.10/envs/venv27" ] [ ! -d "${PYENV_ROOT}/versions/2.7.11/envs/venv27" ]
[ ! -L "${PYENV_ROOT}/versions/venv27" ] [ ! -L "${PYENV_ROOT}/versions/venv27" ]
} }
@test "not delete virtualenv with different symlink" { @test "not delete virtualenv with different symlink" {
mkdir -p "${PYENV_ROOT}/versions/2.7.8/envs/venv27" mkdir -p "${PYENV_ROOT}/versions/2.7.8/envs/venv27"
mkdir -p "${PYENV_ROOT}/versions/2.7.10/envs/venv27" mkdir -p "${PYENV_ROOT}/versions/2.7.11/envs/venv27"
ln -fs "${PYENV_ROOT}/versions/2.7.8/envs/venv27" "${PYENV_ROOT}/versions/venv27" ln -fs "${PYENV_ROOT}/versions/2.7.8/envs/venv27" "${PYENV_ROOT}/versions/venv27"
stub pyenv-rehash "true" stub pyenv-rehash "true"
run pyenv-virtualenv-delete -f "2.7.10/envs/venv27" run pyenv-virtualenv-delete -f "2.7.11/envs/venv27"
assert_success assert_success
unstub pyenv-rehash unstub pyenv-rehash
[ ! -d "${PYENV_ROOT}/versions/2.7.10/envs/venv27" ] [ ! -d "${PYENV_ROOT}/versions/2.7.11/envs/venv27" ]
[ -L "${PYENV_ROOT}/versions/venv27" ] [ -L "${PYENV_ROOT}/versions/venv27" ]
} }
@test "not delete virtualenv with same name" { @test "not delete virtualenv with same name" {
mkdir -p "${PYENV_ROOT}/versions/2.7.10/envs/venv27" mkdir -p "${PYENV_ROOT}/versions/2.7.11/envs/venv27"
mkdir -p "${PYENV_ROOT}/versions/venv27" mkdir -p "${PYENV_ROOT}/versions/venv27"
stub pyenv-rehash "true" stub pyenv-rehash "true"
run pyenv-virtualenv-delete -f "2.7.10/envs/venv27" run pyenv-virtualenv-delete -f "2.7.11/envs/venv27"
assert_success assert_success
unstub pyenv-rehash unstub pyenv-rehash
[ ! -d "${PYENV_ROOT}/versions/2.7.10/envs/venv27" ] [ ! -d "${PYENV_ROOT}/versions/2.7.11/envs/venv27" ]
[ -d "${PYENV_ROOT}/versions/venv27" ] [ -d "${PYENV_ROOT}/versions/venv27" ]
} }

View file

@ -19,28 +19,29 @@ unstub_pyenv() {
} }
@test "path should be handled properly even if there is 'envs' in PYENV_ROOT" { @test "path should be handled properly even if there is 'envs' in PYENV_ROOT" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-version-name "echo '${PYENV_VERSION}'" stub pyenv-version-name "echo '${PYENV_VERSION}'"
stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'" stub pyenv-prefix " : echo '${PYENV_ROOT}/versions/${PYENV_VERSION}'"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pyvenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.4.1/envs/venv/bin" stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "python -s -m ensurepip : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.4.1/envs/venv/bin/pip" stub pyenv-exec "python -m venv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.5.1/envs/venv/bin"
stub pyenv-exec "python -s -m ensurepip : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pip"
run pyenv-virtualenv venv run pyenv-virtualenv venv
assert_success assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 pyvenv ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 python -m venv ${PYENV_ROOT}/versions/3.5.1/envs/venv
PYENV_VERSION=3.4.1/envs/venv python -s -m ensurepip PYENV_VERSION=3.5.1/envs/venv python -s -m ensurepip
rehashed rehashed
OUT OUT
assert [ -e "${PYENV_ROOT}/versions/3.4.1/envs/venv/bin/pip" ] assert [ -e "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pip" ]
unstub_pyenv unstub_pyenv
unstub pyenv-version-name unstub pyenv-version-name
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }

View file

@ -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" {
@ -13,22 +14,23 @@ setup() {
before_virtualenv 'echo before: \$VIRTUALENV_PATH' before_virtualenv 'echo before: \$VIRTUALENV_PATH'
after_virtualenv 'echo after: \$STATUS' after_virtualenv 'echo after: \$STATUS'
OUT OUT
setup_version "3.2.1" setup_version "3.5.1"
create_executable "3.2.1" "virtualenv" create_executable "3.5.1" "virtualenv"
stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.2.1'" stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.5.1'"
stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.2.1'" stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.5.1'"
stub pyenv-exec "python -m venv --help : true"
stub pyenv-hooks "virtualenv : echo '$HOOK_PATH'/virtualenv.bash" stub pyenv-hooks "virtualenv : echo '$HOOK_PATH'/virtualenv.bash"
stub pyenv-exec "echo PYENV_VERSION=3.2.1 \"\$@\"" stub pyenv-exec "echo PYENV_VERSION=3.5.1 \"\$@\""
stub pyenv-exec "echo PYENV_VERSION=3.2.1 \"\$@\"" stub pyenv-exec "echo PYENV_VERSION=3.5.1 \"\$@\""
stub pyenv-rehash "echo rehashed" stub pyenv-rehash "echo rehashed"
run pyenv-virtualenv "3.2.1" venv run pyenv-virtualenv "3.5.1" venv
assert_success assert_success
assert_output <<-OUT assert_output <<-OUT
before: ${PYENV_ROOT}/versions/3.2.1/envs/venv before: ${PYENV_ROOT}/versions/3.5.1/envs/venv
PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=3.5.1 virtualenv ${PYENV_ROOT}/versions/3.5.1/envs/venv
PYENV_VERSION=3.2.1 python -s -m ensurepip PYENV_VERSION=3.5.1 python -s -m ensurepip
after: 0 after: 0
rehashed rehashed
OUT OUT
@ -37,5 +39,76 @@ OUT
unstub pyenv-hooks unstub pyenv-hooks
unstub pyenv-exec unstub pyenv-exec
unstub pyenv-rehash unstub pyenv-rehash
teardown_version "3.2.1" teardown_version "3.5.1"
}
@test "pyenv-sh-activate hooks" {
cat > "${HOOK_PATH}/activate.bash" <<OUT
before_activate 'echo "before"'
after_activate 'echo "after"'
OUT
export PYENV_VIRTUALENV_INIT=1
stub pyenv-version-name "echo venv"
stub pyenv-virtualenv-prefix ""
stub pyenv-prefix "venv : echo \"${PYENV_ROOT}/versions/venv\""
stub pyenv-hooks "activate : echo '$HOOK_PATH'/activate.bash"
stub pyenv-sh-deactivate ""
PYENV_SHELL="bash" PYENV_VERSION="venv" run pyenv-sh-activate
assert_success
assert_output <<EOS
before
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv";
export _OLD_VIRTUAL_PS1="\${PS1:-}";
export PS1="(venv) \${PS1:-}";
after
EOS
unstub pyenv-version-name
unstub pyenv-virtualenv-prefix
unstub pyenv-prefix
unstub pyenv-hooks
unstub pyenv-sh-deactivate
}
@test "deactivate virtualenv" {
cat > "${HOOK_PATH}/deactivate.bash" <<OUT
before_deactivate 'echo "before"'
after_deactivate 'echo "after"'
OUT
export PYENV_VIRTUALENV_INIT=1
export PYENV_VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export VIRTUAL_ENV="${PYENV_ROOT}/versions/venv"
export PYENV_ACTIVATE_SHELL=
stub pyenv-hooks "deactivate : echo '$HOOK_PATH'/deactivate.bash"
PYENV_SHELL="bash" run pyenv-sh-deactivate
assert_success
assert_output <<EOS
before
unset PYENV_VIRTUAL_ENV;
unset VIRTUAL_ENV;
if [ -n "\${_OLD_VIRTUAL_PATH:-}" ]; then
export PATH="\${_OLD_VIRTUAL_PATH}";
unset _OLD_VIRTUAL_PATH;
fi;
if [ -n "\${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
export PYTHONHOME="\${_OLD_VIRTUAL_PYTHONHOME}";
unset _OLD_VIRTUAL_PYTHONHOME;
fi;
if [ -n "\${_OLD_VIRTUAL_PS1:-}" ]; then
export PS1="\${_OLD_VIRTUAL_PS1}";
unset _OLD_VIRTUAL_PS1;
fi;
if declare -f deactivate 1>/dev/null 2>&1; then
unset -f deactivate;
fi;
after
EOS
unstub pyenv-hooks
} }

View file

@ -6,7 +6,7 @@ load test_helper
unset PYENV_SHELL unset PYENV_SHELL
SHELL=/bin/false run pyenv-virtualenv-init - SHELL=/bin/false run pyenv-virtualenv-init -
assert_success assert_success
assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;$PROMPT_COMMAND";' assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;${PROMPT_COMMAND-}"'
} }
@test "detect parent shell from script (sh)" { @test "detect parent shell from script (sh)" {
@ -15,7 +15,7 @@ load test_helper
chmod +x ${TMP}/script.sh chmod +x ${TMP}/script.sh
run ${TMP}/script.sh run ${TMP}/script.sh
assert_success assert_success
assert_output_contains_not ' PROMPT_COMMAND="_pyenv_virtualenv_hook;$PROMPT_COMMAND";' assert_output_contains_not ' PROMPT_COMMAND="_pyenv_virtualenv_hook;${PROMPT_COMMAND-}"'
rm -f "${TMP}/script.sh" rm -f "${TMP}/script.sh"
} }
@ -25,24 +25,20 @@ load test_helper
chmod +x ${TMP}/script.sh chmod +x ${TMP}/script.sh
run ${TMP}/script.sh run ${TMP}/script.sh
assert_success assert_success
assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;$PROMPT_COMMAND";' assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;${PROMPT_COMMAND-}"'
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 . (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" {
@ -50,19 +46,52 @@ load test_helper
run pyenv-virtualenv-init - bash run pyenv-virtualenv-init - bash
assert_success assert_success
assert_output <<EOS assert_output <<EOS
export PATH="${TMP}/pyenv/plugins/pyenv-virtualenv/shims:${PATH}"; 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 [ -n "\$VIRTUAL_ENV" ]; then 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
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
PROMPT_COMMAND="_pyenv_virtualenv_hook;\$PROMPT_COMMAND"; PROMPT_COMMAND="_pyenv_virtualenv_hook;\${PROMPT_COMMAND-}"
fi fi
EOS EOS
} }
@ -72,15 +101,51 @@ EOS
run pyenv-virtualenv-init - fish run pyenv-virtualenv-init - fish
assert_success assert_success
assert_output <<EOS assert_output <<EOS
setenv PATH '${TMP}/pyenv/plugins/pyenv-virtualenv/shims' \$PATH; while set index (contains -i -- "${TMP}/pyenv/plugins/pyenv-virtualenv/shims" \$PATH)
setenv PYENV_VIRTUALENV_INIT 1; set -eg PATH[\$index]; end; set -e index
set -gx PATH '${TMP}/pyenv/plugins/pyenv-virtualenv/shims' \$PATH;
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
@ -91,15 +156,48 @@ EOS
run pyenv-virtualenv-init - zsh run pyenv-virtualenv-init - zsh
assert_success assert_success
assert_output <<EOS assert_output <<EOS
export PATH="${TMP}/pyenv/plugins/pyenv-virtualenv/shims:${PATH}"; 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 [ -n "\$VIRTUAL_ENV" ]; then 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
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
@ -108,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
}

View file

@ -21,54 +21,57 @@ unstub_pyenv() {
} }
@test "install pip with ensurepip" { @test "install pip with ensurepip" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pyvenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.4.1/envs/venv/bin" stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "python -s -m ensurepip : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.4.1/envs/venv/bin/pip" stub pyenv-exec "python -m venv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.5.1/envs/venv/bin"
stub pyenv-exec "python -s -m ensurepip : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pip"
run pyenv-virtualenv venv run pyenv-virtualenv venv
assert_success assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 pyvenv ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 python -m venv ${TMP}/pyenv/versions/3.5.1/envs/venv
PYENV_VERSION=3.4.1/envs/venv python -s -m ensurepip PYENV_VERSION=3.5.1/envs/venv python -s -m ensurepip
rehashed rehashed
OUT OUT
assert [ -e "${PYENV_ROOT}/versions/3.4.1/envs/venv/bin/pip" ] assert [ -e "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pip" ]
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }
@test "install pip without using ensurepip" { @test "install pip without using ensurepip" {
export PYENV_VERSION="3.3.5" export PYENV_VERSION="3.3.6"
setup_pyvenv "3.3.5" setup_m_venv "3.3.6"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pyvenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.3.5/envs/venv/bin" stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "python -m venv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";mkdir -p \${PYENV_ROOT}/versions/3.3.6/envs/venv/bin"
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.3.5/envs/venv/bin/pip" stub pyenv-exec "python -s */get-pip.py : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\";touch \${PYENV_ROOT}/versions/3.3.6/envs/venv/bin/pip"
stub curl true stub curl true
run pyenv-virtualenv venv run pyenv-virtualenv venv
assert_success assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.3.5 pyvenv ${PYENV_ROOT}/versions/3.3.5/envs/venv PYENV_VERSION=3.3.6 python -m venv ${PYENV_ROOT}/versions/3.3.6/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/3.3/get-pip.py...
PYENV_VERSION=3.3.5/envs/venv python -s ${TMP}/pyenv/cache/get-pip.py PYENV_VERSION=3.3.6/envs/venv python -s ${TMP}/pyenv/cache/get-pip.py
rehashed rehashed
OUT OUT
assert [ -e "${PYENV_ROOT}/versions/3.3.5/envs/venv/bin/pip" ] assert [ -e "${PYENV_ROOT}/versions/3.3.6/envs/venv/bin/pip" ]
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.3.5" teardown_m_venv "3.3.6"
} }

View file

@ -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,22 +36,13 @@ create_virtualenv_pypy() {
touch "${PYENV_ROOT}/versions/$1/bin/activate" touch "${PYENV_ROOT}/versions/$1/bin/activate"
} }
remove_virtualenv() { create_m_venv() {
remove_version "$1"
remove_version "${2:-$1}"
}
create_pyvenv() {
create_version "$1" create_version "$1"
create_version "${2:-$1}" create_version "${2:-$1}"
echo "home = ${PYENV_ROOT}/versions/${2:-$1}/bin" > "${PYENV_ROOT}/versions/$1/pyvenv.cfg" echo "home = ${PYENV_ROOT}/versions/${2:-$1}/bin" > "${PYENV_ROOT}/versions/$1/pyvenv.cfg"
touch "${PYENV_ROOT}/versions/$1/bin/activate" touch "${PYENV_ROOT}/versions/$1/bin/activate"
} }
remove_pyvenv() {
remove_version "${2:-$1}"
}
create_conda() { create_conda() {
create_version "$1" create_version "$1"
create_version "${2:-$1}" create_version "${2:-$1}"
@ -66,30 +53,22 @@ 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.6"
PYENV_VERSION="foo" run pyenv-virtualenv-prefix PYENV_VERSION="foo" run pyenv-virtualenv-prefix
assert_success assert_success
assert_output <<OUT assert_output <<OUT
${PYENV_ROOT}/versions/2.7.6 ${PYENV_ROOT}/versions/2.7.11
OUT OUT
unstub pyenv-version-name unstub pyenv-version-name
unstub pyenv-prefix
remove_virtualenv "foo" "2.7.6"
} }
@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,70 +93,54 @@ ${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\"" \ create_virtualenv "foo" "2.7.11"
"bar : echo \"${PYENV_ROOT}/versions/bar\"" create_virtualenv "bar" "3.5.1"
create_virtualenv "foo" "2.7.6"
create_virtualenv "bar" "3.2.1"
PYENV_VERSION="foo:bar" run pyenv-virtualenv-prefix PYENV_VERSION="foo:bar" run pyenv-virtualenv-prefix
assert_success assert_success
assert_output <<OUT assert_output <<OUT
${PYENV_ROOT}/versions/2.7.6:${PYENV_ROOT}/versions/3.2.1 ${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.6"
remove_virtualenv "bar" "3.2.1"
} }
@test "display prefix of virtualenv created by pyvenv" { @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_pyvenv "foo" "3.3.3"
PYENV_VERSION="foo" run pyenv-virtualenv-prefix PYENV_VERSION="foo" run pyenv-virtualenv-prefix
assert_success assert_success
assert_output <<OUT assert_output <<OUT
${PYENV_ROOT}/versions/3.3.3 ${PYENV_ROOT}/versions/3.3.6
OUT OUT
unstub pyenv-version-name unstub pyenv-version-name
unstub pyenv-prefix
remove_pyvenv "foo" "3.3.3"
} }
@test "display prefixes of virtualenv created by pyvenv" { @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\"" \ create_m_venv "foo" "3.3.6"
"bar : echo \"${PYENV_ROOT}/versions/bar\"" create_m_venv "bar" "3.4.4"
create_pyvenv "foo" "3.3.3"
create_pyvenv "bar" "3.4.0"
PYENV_VERSION="foo:bar" run pyenv-virtualenv-prefix PYENV_VERSION="foo:bar" run pyenv-virtualenv-prefix
assert_success assert_success
assert_output <<OUT assert_output <<OUT
${PYENV_ROOT}/versions/3.3.3:${PYENV_ROOT}/versions/3.4.0 ${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_pyvenv "foo" "3.3.3"
remove_pyvenv "bar" "3.4.0"
} }
@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" {
@ -209,38 +167,48 @@ 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.0" stub pyenv-version-name "echo 3.4.4"
stub pyenv-prefix "3.4.0 : echo \"${PYENV_ROOT}/versions/3.4.0\"" create_version "3.4.4"
create_version "3.4.0"
PYENV_VERSION="3.4.0" run pyenv-virtualenv-prefix PYENV_VERSION="3.4.4" run pyenv-virtualenv-prefix
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
pyenv-virtualenv: version \`3.4.0' is not a virtualenv 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.0"
} }
@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.0" stub pyenv-version-name "echo venv33:3.4.4"
stub pyenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/venv33\"" \ create_virtualenv "venv33" "3.3.6"
"3.4.0 : echo \"${PYENV_ROOT}/versions/3.4.0\"" create_version "3.4.4"
create_virtualenv "venv33" "3.3.3"
create_version "3.4.0"
PYENV_VERSION="venv33:3.4.0" run pyenv-virtualenv-prefix PYENV_VERSION="venv33:3.4.4" run pyenv-virtualenv-prefix
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
pyenv-virtualenv: version \`3.4.0' is not a virtualenv pyenv-virtualenv: version \`3.4.4' is not a virtualenv
OUT
unstub pyenv-version-name
}
@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 OUT
unstub pyenv-version-name unstub pyenv-version-name
unstub pyenv-prefix unstub pyenv-prefix
remove_virtualenv "venv33" "3.3.3"
remove_version "3.4.0"
} }

View file

@ -14,6 +14,7 @@ setup() {
stub pyenv-rehash " : true" stub pyenv-rehash " : true"
stub pyenv-version-name "echo \${PYENV_VERSION}" stub pyenv-version-name "echo \${PYENV_VERSION}"
stub curl true stub curl true
stub python-build "echo python2.7"
} }
teardown() { teardown() {
@ -22,6 +23,7 @@ teardown() {
unstub pyenv-prefix unstub pyenv-prefix
unstub pyenv-hooks unstub pyenv-hooks
unstub pyenv-rehash unstub pyenv-rehash
unstub python-build
teardown_version "2.7.8" teardown_version "2.7.8"
rm -fr "$TMP"/* rm -fr "$TMP"/*
} }
@ -31,19 +33,20 @@ teardown() {
create_executable "2.7.8" "python2.7" create_executable "2.7.8" "python2.7"
remove_executable "2.7.9" "python2.7" remove_executable "2.7.9" "python2.7"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv --verbose * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv --verbose * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : true" stub pyenv-exec "python -s -m ensurepip : true"
stub pyenv-which "python2.7 : echo ${PYENV_ROOT}/versions/2.7.8/bin/python2.7" stub pyenv-which "python2.7 : echo ${PYENV_ROOT}/versions/2.7.8/bin/python2.7"
run pyenv-virtualenv --verbose --python=python2.7 venv run pyenv-virtualenv --verbose --python=python2.7 venv
unstub pyenv-exec
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=2.7.8 virtualenv --verbose --python=${PYENV_ROOT}/versions/2.7.8/bin/python2.7 ${PYENV_ROOT}/versions/2.7.8/envs/venv PYENV_VERSION=2.7.8 virtualenv --verbose --python=${PYENV_ROOT}/versions/2.7.8/bin/python2.7 ${PYENV_ROOT}/versions/2.7.8/envs/venv
OUT OUT
assert_success assert_success
unstub pyenv-which unstub pyenv-which
unstub pyenv-exec
remove_executable "2.7.7" "python2.7" remove_executable "2.7.7" "python2.7"
remove_executable "2.7.8" "python2.7" remove_executable "2.7.8" "python2.7"
@ -55,6 +58,7 @@ OUT
remove_executable "2.7.8" "python2.7" remove_executable "2.7.8" "python2.7"
create_executable "2.7.9" "python2.7" create_executable "2.7.9" "python2.7"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv --verbose * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv --verbose * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : true" stub pyenv-exec "python -s -m ensurepip : true"
stub pyenv-which "python2.7 : false" stub pyenv-which "python2.7 : false"
@ -90,6 +94,7 @@ OUT
assert_output <<OUT assert_output <<OUT
pyenv-virtualenv: \`python2.7' is not installed in pyenv. pyenv-virtualenv: \`python2.7' is not installed in pyenv.
Run \`pyenv install python2.7' to install it.
OUT OUT
assert_failure assert_failure
@ -100,3 +105,13 @@ OUT
remove_executable "2.7.8" "python2.7" remove_executable "2.7.8" "python2.7"
remove_executable "2.7.9" "python2.7" remove_executable "2.7.9" "python2.7"
} }
@test "invalid python name" {
run pyenv-virtualenv --verbose --python=99.99.99 venv
assert_output <<OUT
pyenv-virtualenv: \`99.99.99' is not installed in pyenv.
It does not look like a valid Python version. See \`pyenv install --list' for available versions.
OUT
assert_failure
}

View file

@ -20,88 +20,90 @@ unstub_pyenv() {
unstub pyenv-rehash unstub pyenv-rehash
} }
@test "use pyvenv if virtualenv is not available" { @test "use venv if virtualenv is not available" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pyvenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "python -m venv * : 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_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 pyvenv ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 python -m venv ${PYENV_ROOT}/versions/3.5.1/envs/venv
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }
@test "not use pyvenv if virtualenv is available" { @test "not use venv if virtualenv is available" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
create_executable "3.4.1" "virtualenv" create_executable "3.5.1" "virtualenv"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : 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_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 virtualenv ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 virtualenv ${PYENV_ROOT}/versions/3.5.1/envs/venv
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }
@test "install virtualenv if pyvenv is not avaialble" { @test "install virtualenv if venv is not available" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="3.2.1"
setup_version "3.2.1" setup_version "3.2.1"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pip install virtualenv : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "pip install virtualenv* : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true"
stub curl true
run pyenv-virtualenv venv run pyenv-virtualenv venv
assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 pip install virtualenv PYENV_VERSION=3.2.1 pip install virtualenv==13.1.2
PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.2.1/envs/venv/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
unstub curl
teardown_version "3.2.1" teardown_version "3.2.1"
} }
@test "install virtualenv if -p has given" { @test "install virtualenv if -p has given" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "pip install virtualenv : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "pip install virtualenv : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : true" stub pyenv-exec "python -s -m ensurepip : true"
@ -109,24 +111,26 @@ OUT
run pyenv-virtualenv -p ${TMP}/python3 venv run pyenv-virtualenv -p ${TMP}/python3 venv
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 pip install virtualenv PYENV_VERSION=3.5.1 pip install virtualenv
PYENV_VERSION=3.4.1 virtualenv --python=${TMP}/python3 ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 virtualenv --python=${TMP}/python3 ${PYENV_ROOT}/versions/3.5.1/envs/venv
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pydoc" ]
assert_success assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }
@test "install virtualenv if --python has given" { @test "install virtualenv if --python has given" {
export PYENV_VERSION="3.4.1" export PYENV_VERSION="3.5.1"
setup_pyvenv "3.4.1" setup_m_venv "3.5.1"
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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : true"
stub pyenv-exec "pip install virtualenv : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "pip install virtualenv : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : true" stub pyenv-exec "python -s -m ensurepip : true"
@ -134,16 +138,17 @@ OUT
run pyenv-virtualenv --python=${TMP}/python3 venv run pyenv-virtualenv --python=${TMP}/python3 venv
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.4.1 pip install virtualenv PYENV_VERSION=3.5.1 pip install virtualenv
PYENV_VERSION=3.4.1 virtualenv --python=${TMP}/python3 ${PYENV_ROOT}/versions/3.4.1/envs/venv PYENV_VERSION=3.5.1 virtualenv --python=${TMP}/python3 ${PYENV_ROOT}/versions/3.5.1/envs/venv
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.5.1/envs/venv/bin/pydoc" ]
assert_success assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_pyvenv "3.4.1" teardown_m_venv "3.5.1"
} }
@test "install virtualenv with unsetting troublesome pip options" { @test "install virtualenv with unsetting troublesome pip options" {
@ -152,25 +157,22 @@ 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 " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "pip install virtualenv : echo PIP_REQUIRE_VENV=\${PIP_REQUIRE_VENV} PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "pip install virtualenv* : echo PIP_REQUIRE_VENV=\${PIP_REQUIRE_VENV} PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "virtualenv * : echo PIP_REQUIRE_VENV=\${PIP_REQUIRE_VENV} PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PIP_REQUIRE_VENV=\${PIP_REQUIRE_VENV} PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true"
stub curl true
PIP_REQUIRE_VENV="true" run pyenv-virtualenv venv PIP_REQUIRE_VENV="true" run pyenv-virtualenv venv
assert_success
assert_output <<OUT assert_output <<OUT
PIP_REQUIRE_VENV= PYENV_VERSION=3.2.1 pip install virtualenv PIP_REQUIRE_VENV= PYENV_VERSION=3.2.1 pip install virtualenv==13.1.2
PIP_REQUIRE_VENV= PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv PIP_REQUIRE_VENV= PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/3.2.1/envs/venv/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
unstub pyenv-exec unstub pyenv-exec
unstub curl
teardown_version "3.2.1" teardown_version "3.2.1"
} }

View file

@ -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,41 +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_DEBUG="${PROGRAM}_STUB_DEBUG"
if [ -n "${!_STUB_DEBUG}" ]; then STUB_RUN="${PROGRAM}_STUB_RUN"
echo "$program" "$@" >&${!_STUB_DEBUG} STUB_RUN="${!STUB_RUN:-${TMPDIR}/${program}-stub-run}"
fi 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
[ ! -e "${!_STUB_RUN}" ] || source "${!_STUB_RUN}" }
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
@ -55,55 +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
done < "$STUB_PLAN"
#If we never matched anything, we failed.
if [[ $match_result -eq 1 ]]; then
STUB_RESULT=1
#This also means that we never released the lock
# before running the payload
else
acquire_lock
fi fi
done < "${!_STUB_PLAN}" # Write out the match_result information.
update_runfile_result
release_lock
if [ -n "${!_STUB_END}" ]; then
# Clean up the run file.
rm -f "${!_STUB_RUN}"
# If the number of lines in the plan is larger than
# the requested index, we failed.
if [ $index -ge "${!_STUB_INDEX}" ]; then
eval "${_STUB_RESULT}"=1
fi
# Return the 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" exit "$status"
fi 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 "plan:"
cat "$STUB_PLAN" || true
echo "log:"
cat "$STUB_LOG" || true
} >&2
fi
# Clean up the run file.
rm -f "$STUB_RUN"
rm -f "$STUB_LOG"
# Return the run result.
exit "$STUB_RESULT"
fi

View file

@ -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,19 +19,51 @@ 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
export "${prefix}_STUB_PLAN"="${TMP}/${program}-stub-plan" export "${prefix}_STUB_PLAN"="${TMP}/${program}-stub-plan"
export "${prefix}_STUB_RUN"="${TMP}/${program}-stub-run" export "${prefix}_STUB_RUN"="${TMP}/${program}-stub-run"
export "${prefix}_STUB_LOG"="${TMP}/${program}-stub-log"
export "${prefix}_STUB_END"= export "${prefix}_STUB_END"=
mkdir -p "${TMP}/bin" mkdir -p "${TMP}/bin"
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() {
@ -74,8 +115,20 @@ assert_failure() {
assert_equal() { assert_equal() {
if [ "$1" != "$2" ]; then if [ "$1" != "$2" ]; then
{ echo "expected: $1" { echo "expected:"
echo "actual: $2" echo "$1"
echo "actual:"
echo "$2"
} | flunk
fi
}
assert_equal_wildcards() {
if [[ $1 != $2 ]]; then
{ echo "expected:"
echo "$2"
echo "actual:"
echo "$1"
} | flunk } | flunk
fi fi
} }
@ -88,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 || {
@ -120,7 +181,6 @@ remove_executable() {
setup_version() { setup_version() {
create_executable "$1" "python" create_executable "$1" "python"
remove_executable "$1" "activate" remove_executable "$1" "activate"
remove_executable "$1" "pyvenv"
remove_executable "$1" "conda" remove_executable "$1" "conda"
} }
@ -131,7 +191,6 @@ teardown_version() {
setup_virtualenv() { setup_virtualenv() {
create_executable "$1" "python" create_executable "$1" "python"
create_executable "$1" "activate" create_executable "$1" "activate"
remove_executable "$1" "pyvenv"
remove_executable "$1" "conda" remove_executable "$1" "conda"
} }
@ -139,21 +198,19 @@ teardown_virtualenv() {
rm -fr "${PYENV_ROOT}/versions/$1" rm -fr "${PYENV_ROOT}/versions/$1"
} }
setup_pyvenv() { setup_m_venv() {
create_executable "$1" "python" create_executable "$1" "python"
create_executable "$1" "activate" create_executable "$1" "activate"
create_executable "$1" "pyvenv"
remove_executable "$1" "conda" remove_executable "$1" "conda"
} }
teardown_pyvenv() { teardown_m_venv() {
rm -fr "${PYENV_ROOT}/versions/$1" rm -fr "${PYENV_ROOT}/versions/$1"
} }
setup_conda() { setup_conda() {
create_executable "$1" "python" create_executable "$1" "python"
create_executable "$1" "activate" create_executable "$1" "activate"
remove_executable "$1" "pyvenv"
create_executable "$1" "conda" create_executable "$1" "conda"
local conda="$1" local conda="$1"
shift 1 shift 1
@ -161,12 +218,15 @@ setup_conda() {
for env; do for env; do
create_executable "${conda}/envs/${env}" "python" create_executable "${conda}/envs/${env}" "python"
create_executable "${conda}/envs/${env}" "activate" create_executable "${conda}/envs/${env}" "activate"
remove_executable "${conda}/envs/${env}" "pyvenv"
create_executable "${conda}/envs/${env}" "conda" create_executable "${conda}/envs/${env}" "conda"
mkdir -p "${PYENV_ROOT}/versions/${conda}/envs/${env}/etc/conda/activate.d"
touch "${PYENV_ROOT}/versions/${conda}/envs/${env}/etc/conda/activate.d/activate.sh"
mkdir -p "${PYENV_ROOT}/versions/${conda}/envs/${env}/etc/conda/deactivate.d"
touch "${PYENV_ROOT}/versions/${conda}/envs/${env}/etc/conda/deactivate.d/deactivate.sh"
done done
} }
teardown_conda() { teardown_conda() {
rm -fr "${PYENV_ROOT}/versions/$1" rm -fr "${PYENV_ROOT}/versions/$1"
} }

View file

@ -9,28 +9,31 @@ setup() {
@test "display virtualenv version" { @test "display virtualenv version" {
setup_virtualenv "2.7.7" setup_virtualenv "2.7.7"
stub pyenv-prefix "echo '${PYENV_ROOT}/versions/2.7.7'" stub pyenv-prefix "echo '${PYENV_ROOT}/versions/2.7.7'"
stub pyenv-version-name "echo 2.7.7"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv --version : echo \"1.11\"" stub pyenv-exec "virtualenv --version : echo \"1.11\""
run pyenv-virtualenv --version run pyenv-virtualenv --version
assert_success assert_success
[[ "$output" == "pyenv-virtualenv 20"*" (virtualenv 1.11)" ]] [[ "$output" == "pyenv-virtualenv "?.?.?" (virtualenv 1.11)" ]]
unstub pyenv-prefix unstub pyenv-prefix
unstub pyenv-exec unstub pyenv-exec
teardown_virtualenv "2.7.7" teardown_virtualenv "2.7.7"
} }
@test "display pyvenv version" { @test "display venv version" {
setup_pyvenv "3.4.1" setup_m_venv "3.4.1"
stub pyenv-version-name "echo 3.4.1"
stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.4.1'" stub pyenv-prefix "echo '${PYENV_ROOT}/versions/3.4.1'"
stub pyenv-which "pyvenv : echo \"${PYENV_ROOT}/versions/3.4.1/bin/pyvenv\"" stub pyenv-exec "python -m venv --help : true"
run pyenv-virtualenv --version run pyenv-virtualenv --version
assert_success assert_success
[[ "$output" == "pyenv-virtualenv 20"*" (pyvenv 3.4.1)" ]] [[ "$output" == "pyenv-virtualenv "?.?.?" (python -m venv)" ]]
unstub pyenv-prefix unstub pyenv-prefix
teardown_pyvenv "3.4.1" teardown_m_venv "3.4.1"
} }

View file

@ -23,22 +23,56 @@ unstub_pyenv() {
} }
@test "create virtualenv from given version" { @test "create virtualenv from given version" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="2.7.11"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"; mkdir -p \"\$2/bin\""
stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true"
stub curl true
create_executable "${PYENV_VERSION}" "python-config"
create_executable "${PYENV_VERSION}" "python2-config"
create_executable "${PYENV_VERSION}" "python2.7-config"
run pyenv-virtualenv "2.7.11" "venv"
assert_output <<OUT
PYENV_VERSION=2.7.11 virtualenv ${PYENV_ROOT}/versions/2.7.11/envs/venv
Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed
OUT
assert_success
for x in pydoc python-config python2-config python2.7-config; do
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/venv/bin/$x" ]
done
unstub_pyenv
unstub pyenv-virtualenv-prefix
unstub pyenv-exec
unstub curl
}
@test "create virtualenv from a given prefix" {
stub_pyenv "2.7.11"
stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true" stub pyenv-exec "python -s */get-pip.py : true"
stub curl true stub curl true
stub pyenv-latest "-f 2.7 : echo 2.7.11"
run pyenv-virtualenv "3.2.1" "venv" run pyenv-virtualenv "2.7" "venv"
assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=2.7.11 virtualenv ${PYENV_ROOT}/versions/2.7.11/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/venv/bin/pydoc" ]
assert [ ! -e "${PYENV_ROOT}/versions/2.7" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix
@ -47,10 +81,11 @@ OUT
} }
@test "create virtualenv from current version" { @test "create virtualenv from current version" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="2.7.11"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-version-name "echo \${PYENV_VERSION}" stub pyenv-version-name "echo \${PYENV_VERSION}"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true" stub pyenv-exec "python -s */get-pip.py : true"
@ -58,12 +93,13 @@ OUT
run pyenv-virtualenv venv run pyenv-virtualenv venv
assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=2.7.11 virtualenv ${PYENV_ROOT}/versions/2.7.11/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/venv/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-version-name unstub pyenv-version-name
@ -73,10 +109,11 @@ OUT
} }
@test "create virtualenv with short options" { @test "create virtualenv with short options" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="2.7.11"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-version-name "echo \${PYENV_VERSION}" stub pyenv-version-name "echo \${PYENV_VERSION}"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true" stub pyenv-exec "python -s */get-pip.py : true"
@ -85,10 +122,11 @@ OUT
run pyenv-virtualenv -v -p ${TMP}/python venv run pyenv-virtualenv -v -p ${TMP}/python venv
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 virtualenv --verbose --python=${TMP}/python ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=2.7.11 virtualenv --verbose --python=${TMP}/python ${PYENV_ROOT}/versions/2.7.11/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/venv/bin/pydoc" ]
assert_success assert_success
unstub_pyenv unstub_pyenv
@ -99,10 +137,11 @@ OUT
} }
@test "create virtualenv with long options" { @test "create virtualenv with long options" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="2.7.11"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-version-name "echo \${PYENV_VERSION}" stub pyenv-version-name "echo \${PYENV_VERSION}"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true" stub pyenv-exec "python -s */get-pip.py : true"
@ -111,10 +150,11 @@ OUT
run pyenv-virtualenv --verbose --python=${TMP}/python venv run pyenv-virtualenv --verbose --python=${TMP}/python venv
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 virtualenv --verbose --python=${TMP}/python ${PYENV_ROOT}/versions/3.2.1/envs/venv PYENV_VERSION=2.7.11 virtualenv --verbose --python=${TMP}/python ${PYENV_ROOT}/versions/2.7.11/envs/venv
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/venv/bin/pydoc" ]
assert_success assert_success
unstub_pyenv unstub_pyenv
@ -125,7 +165,7 @@ OUT
} }
@test "no whitespace allowed in virtualenv name" { @test "no whitespace allowed in virtualenv name" {
run pyenv-virtualenv "3.2.1" "foo bar" run pyenv-virtualenv "2.7.11" "foo bar"
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
@ -134,7 +174,7 @@ OUT
} }
@test "no tab allowed in virtualenv name" { @test "no tab allowed in virtualenv name" {
run pyenv-virtualenv "3.2.1" "foo bar baz" run pyenv-virtualenv "2.7.11" "foo bar baz"
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
@ -143,7 +183,7 @@ OUT
} }
@test "system not allowed as virtualenv name" { @test "system not allowed as virtualenv name" {
run pyenv-virtualenv "3.2.1" "system" run pyenv-virtualenv "2.7.11" "system"
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
@ -152,7 +192,7 @@ OUT
} }
@test "no slash allowed in virtualenv name" { @test "no slash allowed in virtualenv name" {
run pyenv-virtualenv "3.2.1" "foo/bar" run pyenv-virtualenv "2.7.11" "foo/bar"
assert_failure assert_failure
assert_output <<OUT assert_output <<OUT
@ -161,22 +201,24 @@ OUT
} }
@test "slash allowed if it is the long name of the virtualenv" { @test "slash allowed if it is the long name of the virtualenv" {
export PYENV_VERSION="3.2.1" export PYENV_VERSION="2.7.11"
stub_pyenv "${PYENV_VERSION}" stub_pyenv "${PYENV_VERSION}"
stub pyenv-virtualenv-prefix " : false" stub pyenv-virtualenv-prefix " : false"
stub pyenv-exec "python -m venv --help : false"
stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\"" stub pyenv-exec "virtualenv * : echo PYENV_VERSION=\${PYENV_VERSION} \"\$@\""
stub pyenv-exec "python -s -m ensurepip : false" stub pyenv-exec "python -s -m ensurepip : false"
stub pyenv-exec "python -s */get-pip.py : true" stub pyenv-exec "python -s */get-pip.py : true"
stub curl true stub curl true
run pyenv-virtualenv "3.2.1" "3.2.1/envs/foo" run pyenv-virtualenv "2.7.11" "2.7.11/envs/foo"
assert_success
assert_output <<OUT assert_output <<OUT
PYENV_VERSION=3.2.1 virtualenv ${PYENV_ROOT}/versions/3.2.1/envs/foo PYENV_VERSION=2.7.11 virtualenv ${PYENV_ROOT}/versions/2.7.11/envs/foo
Installing pip from https://bootstrap.pypa.io/get-pip.py... Installing pip from https://bootstrap.pypa.io/pip/2.7/get-pip.py...
rehashed rehashed
OUT OUT
assert [ -x "${PYENV_ROOT}/versions/2.7.11/envs/foo/bin/pydoc" ]
assert_success
unstub_pyenv unstub_pyenv
unstub pyenv-virtualenv-prefix unstub pyenv-virtualenv-prefix

View file

@ -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
} }