From af6c157a79534f932041a2e015422dcbf539eed3 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 2 Jun 2014 20:13:48 +0900 Subject: [PATCH 1/5] Add `eval "$(pyenv virtualenv-init -)"` to setup _precmd_ for user's shell --- bin/pyenv-virtualenv-init | 106 ++++++++++++++++++++++++++++++++++++++ test/installer.bats | 3 ++ 2 files changed, 109 insertions(+) create mode 100755 bin/pyenv-virtualenv-init diff --git a/bin/pyenv-virtualenv-init b/bin/pyenv-virtualenv-init new file mode 100755 index 0000000..d1b71ee --- /dev/null +++ b/bin/pyenv-virtualenv-init @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# Summary: Configure the shell environment for pyenv-virtualenv +# Usage: eval "$(pyenv virtualenv-init - [])" +# +# Automatically activates a Python virtualenv environment based on current +# pyenv version. +# + +set -e +[ -n "$PYENV_DEBUG" ] && set -x + +print="" +for args in "$@" +do + if [ "$args" = "-" ]; then + print=1 + shift + fi +done + +shell="$1" +if [ -z "$shell" ]; then + shell="$(ps c -p "$PPID" -o 'ucomm=' 2>/dev/null || true)" + shell="${shell##-}" + shell="${shell%% *}" + shell="$(basename "${shell:-$SHELL}")" +fi + +if [ -z "$print" ]; then + case "$shell" in + bash ) + profile='~/.bash_profile' + ;; + zsh ) + profile='~/.zshrc' + ;; + ksh ) + profile='~/.profile' + ;; + fish ) + profile='~/.config/fish/config.fish' + ;; + * ) + profile='your profile' + ;; + esac + + { echo "# Load pyenv-virtualenv automatically by adding" + echo "# the following to ${profile}:" + echo + case "$shell" in + fish ) + echo 'status --is-interactive; and . (pyenv virtualenv-init -|psub)' + ;; + * ) + echo 'eval "$(pyenv virtualenv-init -)"' + ;; + esac + echo + } >&2 + + exit 1 +fi + +case "$shell" in +bash ) + cat </dev/null || true + fi +}; +if ! [[ "\$PROMPT_COMMAND" =~ _pyenv_virtualenv_hook ]]; then + PROMPT_COMMAND="_pyenv_virtualenv_hook;\$PROMPT_COMMAND"; +fi +EOS + ;; +fish ) + cat </dev/null; or true + end +end +EOS + ;; +zsh ) + cat </dev/null || true + fi +} +typeset -a precmd_functions +if [[ -z \$precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then + precmd_functions+=_pyenv_virtualenv_hook; +fi +EOS + ;; +* ) + # FIXME: what should i do here?? + ;; +esac diff --git a/test/installer.bats b/test/installer.bats index 16423c4..b324078 100644 --- a/test/installer.bats +++ b/test/installer.bats @@ -9,9 +9,12 @@ load test_helper cd usr + assert [ -x bin/pyenv-activate ] + assert [ -x bin/pyenv-deactivate ] assert [ -x bin/pyenv-sh-activate ] assert [ -x bin/pyenv-sh-deactivate ] assert [ -x bin/pyenv-virtualenv ] + assert [ -x bin/pyenv-virtualenv-init ] assert [ -x bin/pyenv-virtualenv-prefix ] assert [ -x bin/pyenv-virtualenvs ] } From ea120da0c5059509dd761898f6fc5ab9232157e3 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 2 Jun 2014 22:32:03 +0900 Subject: [PATCH 2/5] fish: Suppress annoying stderr outputs from `pyenv-sh-activate` --- bin/pyenv-virtualenv-init | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pyenv-virtualenv-init b/bin/pyenv-virtualenv-init index d1b71ee..93a566a 100755 --- a/bin/pyenv-virtualenv-init +++ b/bin/pyenv-virtualenv-init @@ -80,8 +80,8 @@ fish ) cat </dev/null; or true + eval (pyenv sh-deactivate) + eval (pyenv sh-activate 2>/dev/null); or true end end EOS From 8a837758dcf81bbcc48f4d3280c602706a4e2305 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 2 Jun 2014 20:16:14 +0900 Subject: [PATCH 3/5] activate: invoke `pyenv shell` only if the arguments passed --- README.md | 15 +-------------- bin/pyenv-sh-activate | 9 ++++++--- bin/pyenv-sh-deactivate | 5 ++--- test/activate.bats | 2 -- test/deactivate.bats | 6 ++---- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index ca530ac..b7baaa0 100644 --- a/README.md +++ b/README.md @@ -86,13 +86,7 @@ version. Some external tools (e.g. [jedi](https://github.com/davidhalter/jedi)) might require you to `activate` the virtualenv. `pyenv activate` lets you to activate the virtualenv into your shell. - $ pyenv activate venv27 - -`pyenv activate` acts almost like following commands. -The activate'd virtualenv will be persisted as _shell_ version. - - $ pyenv shell venv27 - $ source "$(pyenv prefix venv27)/bin/activate" + $ pyenv activate ### Deactivate virtualenv @@ -105,13 +99,6 @@ This is prepared for similality between other `pyenv` commands like `shell` and $ pyenv activate --unset -`pyenv deactivate` acts almost like following commands. -You can also use virtualenv's `deactivate` in place of `pyenv deactivate`, -but be careful with the _shell_ version because it will be persisted even if `deactivate` has invoked. - - $ deactivate - $ pyenv shell --unset - ### Special environment variables You can set certain environment variables to control the pyenv-virtualenv. diff --git a/bin/pyenv-sh-activate b/bin/pyenv-sh-activate index c390459..12e5b79 100755 --- a/bin/pyenv-sh-activate +++ b/bin/pyenv-sh-activate @@ -26,9 +26,8 @@ if [ "$1" = "--unset" ]; then fi versions=("$@") -shell="$(basename "${PYENV_SHELL:-$SHELL}")" - if [ -z "$versions" ]; then + no_shell=1 OLDIFS="$IFS" IFS=: versions=($(pyenv-version-name)) IFS="$OLDIFS" @@ -41,7 +40,11 @@ fi pyenv-virtualenv-prefix "${versions}" 1>/dev/null -echo "pyenv shell \"${versions}\";" +if [ -z "$no_shell" ]; then + echo "pyenv shell \"${versions}\";" +fi + +shell="$(basename "${PYENV_SHELL:-$SHELL}")" case "$shell" in fish ) echo ". \"$(pyenv-prefix "${versions}")/bin/activate.fish\"" ;; * ) echo "source \"$(pyenv-prefix "${versions}")/bin/activate\"" ;; diff --git a/bin/pyenv-sh-deactivate b/bin/pyenv-sh-deactivate index 6383c3e..8cc7568 100755 --- a/bin/pyenv-sh-deactivate +++ b/bin/pyenv-sh-deactivate @@ -11,7 +11,6 @@ set -e shell="$(basename "${PYENV_SHELL:-$SHELL}")" case "$shell" in -fish ) echo "functions -q deactivate; and deactivate;";; -* ) echo "declare -f deactivate 1>/dev/null 2>&1 && deactivate;";; +fish ) echo "functions -q deactivate; and deactivate";; +* ) echo "declare -f deactivate 1>/dev/null 2>&1 && deactivate";; esac -echo "pyenv shell --unset" diff --git a/test/activate.bats b/test/activate.bats index 9f61bc9..405bf39 100644 --- a/test/activate.bats +++ b/test/activate.bats @@ -19,7 +19,6 @@ setup() { assert_success assert_output </dev/null 2>&1 && deactivate; -pyenv shell --unset +declare -f deactivate 1>/dev/null 2>&1 && deactivate EOS } @@ -21,8 +20,7 @@ EOS assert_success assert_output < Date: Wed, 4 Jun 2014 15:27:39 +0900 Subject: [PATCH 4/5] Add test for `pyenv-virtualenv-init` --- test/init.bats | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/init.bats diff --git a/test/init.bats b/test/init.bats new file mode 100644 index 0000000..6edcc47 --- /dev/null +++ b/test/init.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load test_helper + +@test "detect parent shell" { + root="$(cd $BATS_TEST_DIRNAME/.. && pwd)" + SHELL=/bin/false run pyenv-virtualenv-init - + assert_success + assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;$PROMPT_COMMAND";' +} + +@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" { + run pyenv-virtualenv-init fish + assert [ "$status" -eq 1 ] + assert_output_contains 'status --is-interactive; and . (pyenv virtualenv-init -|psub)' +} + +@test "outputs bash-specific syntax" { + run pyenv-virtualenv-init - bash + assert_success + assert_output_contains ' PROMPT_COMMAND="_pyenv_virtualenv_hook;$PROMPT_COMMAND";' +} + +@test "outputs fish-specific syntax" { + run pyenv-virtualenv-init - fish + assert_success + assert_output_contains 'function _pyenv_virtualenv_hook --on-event fish_prompt;' +} + +@test "outputs zsh-specific syntax" { + run pyenv-virtualenv-init - zsh + assert_success + assert_output_contains ' precmd_functions+=_pyenv_virtualenv_hook;' +} From b7535395e86ed59cead95afe7d10346832850814 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Wed, 4 Jun 2014 00:38:11 +0900 Subject: [PATCH 5/5] Update README --- README.md | 74 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index b7baaa0..834bf8c 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,9 @@ to manage your virtualenvs.) ### Installing as a pyenv plugin -Installing pyenv-virtualenv as a pyenv plugin will give you access to the -`pyenv virtualenv` command. - - $ git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv - $ exec "$SHELL" - This will install the latest development version of pyenv-virtualenv into the `~/.pyenv/plugins/pyenv-virtualenv` directory. + **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 installed into. @@ -29,6 +24,21 @@ From inside that directory you can: - Check out a specific release tag. - Get the latest development release by running `git pull` to download the latest changes. +1. **Check out pyenv-virtualenv into plugin directory** + + $ git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv + +2. **Add `pyenv virtualenv-init` to your shell** to enable activation of virtualenv + + $ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile + + **Zsh note**: Modify your `~/.zshenv` file instead of `~/.bash_profile`. + +3. **Restart your shell to the enable pyenv-virtualenv** + + $ exec "$SHELL" + + ### Installing with Homebrew (for OS X users) Mac OS X users can install pyenv-virtualenv with the @@ -39,11 +49,18 @@ installed, you will also be able to use the `pyenv virtualenv` command. *This is recommended method of installation if you installed pyenv with Homebrew.* - brew install pyenv-virtualenv +``` +$ brew install pyenv-virtualenv +``` Or, if you would like to install the latest development release: - brew install --HEAD pyenv-virtualenv +``` +$ brew install --HEAD pyenv-virtualenv +``` + +After installation, you'll still need to add `eval "$(pyenv virtualenv-init -)"` to your +profile (as stated in the caveats). You'll only ever have to do this once. ## Usage @@ -54,10 +71,12 @@ To create a virtualenv for the Python version use with pyenv, run `pyenv virtualenv`, specifying the Python version you want and the name of the virtualenv directory. For example, - $ pyenv virtualenv 2.7.6 my-virtual-env-2.7.6 +``` +$ pyenv virtualenv 2.7.7 my-virtual-env-2.7.7 +``` -will create a virtualenv based on Python 2.7.6 -under `~/.pyenv/versions` in a folder called `my-virtual-env-2.7.6`. +will create a virtualenv based on Python 2.7.7 +under `~/.pyenv/versions` in a folder called `my-virtual-env-2.7.7`. ### Create virtualenv from current version @@ -66,38 +85,29 @@ If there is only one argument is given to `pyenv virtualenv`, virtualenv will be created with given name based on current version. - $ pyenv version - 3.3.3 (set by /home/yyuu/.pyenv/version) - $ pyenv virtualenv venv33 +``` + $ pyenv version + 3.4.1 (set by /home/yyuu/.pyenv/version) + $ pyenv virtualenv venv34 +``` ### List existing virtualenvs `pyenv virtualenvs` shows you the list of existing virtualenvs. - $ pyenv shell venv27 - $ pyenv virtualenvs - * venv27 (created from /home/yyuu/.pyenv/versions/2.7.6) - venv33 (created from /home/yyuu/.pyenv/versions/3.3.3) +``` +$ pyenv shell venv27 +$ pyenv virtualenvs +* venv27 (created from /home/yyuu/.pyenv/versions/2.7.7) + venv34 (created from /home/yyuu/.pyenv/versions/3.4.1) +``` ### Activate virtualenv Some external tools (e.g. [jedi](https://github.com/davidhalter/jedi)) might require you to `activate` the virtualenv. -`pyenv activate` lets you to activate the virtualenv into your shell. - - $ pyenv activate - -### Deactivate virtualenv - -You can `deactivate` the activate'd virtualenv by `pyenv deactivate`. - - $ pyenv deactivate - -Or, there is an alias in `activate` command. -This is prepared for similality between other `pyenv` commands like `shell` and `local`. - - $ pyenv activate --unset +The `pyenv-virtualenv` will automatically activate/deactivate the virtualenv if the `eval "$(pyenv virtualenv-init -)"` is properly configured in your shell. ### Special environment variables