Support virtualenvwrapper with / without pyenv virtualenv-init or virtualenvwrapper plugins

The desired logic is:

For the `pyenv` plugins `virtualenv-init` and `virtualenvwrapper`:
1. If either plugin is present, activate it
2. If `virtualenvwrapper` plugin is not present, then
   [fallback to standard
   `virtualenvwrapper`](https://github.com/sorin-ionescu/prezto/pull/1414#issuecomment-320306421).
3. If `virtualenvwrapper` plugin is present, then [don't fallback to
   standard `virtualenvwrapper`, regardless of whether `virtualenv-init`
   is
   present](https://github.com/sorin-ionescu/prezto/pull/1981#issue-1123766676).

Previously, if the `virtualenv` command was present but `pyenv` was
missing, then the fallback wouldn't be hit. This bug was introduced by
https://github.com/sorin-ionescu/prezto/pull/1981/ which ensured that
the `pyenv` `virtualenvwrapper` plugin was activated if present,
regardless of the presence of the `virtualenv-init` plugin.

As an optimization, the check for the `pyenv` plugins are skipped if
`pyenv` itself isn't found.

Since we only want to fallback if the `pyenv` `virtualenvwrapper` plugin
is missing, but that's buried within the `pyenv` logic and we also need
to handle when `pyenv` itself is missing, this switches to using a flag
variable.

I also renamed the `virtualenv_sources` var to
`virtualenvwrapper_sources` as `virtualenv` is distinct from
`virtualenvwrapper`, so using one name for a var that is really about
the other is confusing.

Looking at `git blame`, there's a _lot_ of prior art here around trying
to support all the permutations of `pyenv` and various plugins:
* https://github.com/sorin-ionescu/prezto/issues/1413
* https://github.com/sorin-ionescu/prezto/pull/1414
* https://github.com/sorin-ionescu/prezto/pull/1433
* https://github.com/sorin-ionescu/prezto/pull/1434

So we need to be extremely careful to continue to support all these
permutations.

Fix https://github.com/sorin-ionescu/prezto/issues/2022
This commit is contained in:
Jeff Widman 2022-10-25 21:24:51 -07:00
parent ca9012c776
commit e3a9583f33

View file

@ -116,38 +116,42 @@ if (( $+VIRTUALENVWRAPPER_VIRTUALENV || $+commands[virtualenv] )) \
# look for plugins of interest. Scanning shell '$path' isn't enough as they
# can exist in 'pyenv' synthesized paths (e.g., '~/.pyenv/plugins') instead.
local -a pyenv_plugins
local pyenv_virtualenvwrapper_plugin_found
if (( $+commands[pyenv] )); then
pyenv_plugins=(${(@oM)${(f)"$(pyenv commands --no-sh 2> /dev/null)"}:#virtualenv*})
# Optionally activate 'virtualenv-init' plugin when available.
if (( $pyenv_plugins[(i)virtualenv-init] <= $#pyenv_plugins )); then
eval "$(pyenv virtualenv-init - zsh)"
fi
# Optionally activate 'virtualenvwrapper' plugin when available.
if (( $pyenv_plugins[(i)virtualenvwrapper(_lazy|)] <= $#pyenv_plugins )); then
pyenv "$pyenv_plugins[(R)virtualenvwrapper(_lazy|)]"
pyenv_virtualenvwrapper_plugin_found="true"
fi
unset pyenv_plugins
fi
# Optionally activate 'virtualenv' plugin when available.
if (( $pyenv_plugins[(i)virtualenv-init] <= $#pyenv_plugins )); then
eval "$(pyenv virtualenv-init - zsh)"
if [[ $pyenv_virtualenvwrapper_plugin_found != "true" ]]; then
# Fallback to standard 'virtualenvwrapper' if 'python' is available in '$path'.
if (( ! $+VIRTUALENVWRAPPER_PYTHON )) && (( $#commands[(i)python[23]#] )); then
VIRTUALENVWRAPPER_PYTHON=$commands[(i)python[23]#]
fi
virtualenvwrapper_sources=(
${(@Ov)commands[(I)virtualenvwrapper(_lazy|).sh]}
/usr/share/virtualenvwrapper/virtualenvwrapper(_lazy|).sh(OnN)
)
if (( $#virtualenvwrapper_sources )); then
source "$virtualenvwrapper_sources[1]"
fi
unset virtualenvwrapper_sources
fi
# Optionally activate 'virtualenvwrapper' plugin when available.
if (( $pyenv_plugins[(i)virtualenvwrapper(_lazy|)] <= $#pyenv_plugins )); then
pyenv "$pyenv_plugins[(R)virtualenvwrapper(_lazy|)]"
fi
unset pyenv_plugins
else
# Fallback to 'virtualenvwrapper' without 'pyenv' wrapper if 'python' is
# available in '$path'.
if (( ! $+VIRTUALENVWRAPPER_PYTHON )) && (( $#commands[(i)python[23]#] )); then
VIRTUALENVWRAPPER_PYTHON=$commands[(i)python[23]#]
fi
virtenv_sources=(
${(@Ov)commands[(I)virtualenvwrapper(_lazy|).sh]}
/usr/share/virtualenvwrapper/virtualenvwrapper(_lazy|).sh(OnN)
)
if (( $#virtenv_sources )); then
source "$virtenv_sources[1]"
fi
unset virtenv_sources
unset pyenv_virtualenvwrapper_plugin_found
fi
# Load conda into the shell session, if requested.