Skip to content

Commit d89d18d

Browse files
committed
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
1 parent 8c9f7fa commit d89d18d

File tree

6 files changed

+112
-41
lines changed

6 files changed

+112
-41
lines changed

bin/pyenv-sh-activate

+4-2
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ EOS
177177
esac
178178

179179
# anaconda/miniconda
180-
if [ -x "${prefix}/bin/conda" ]; then
180+
if [ -d "${prefix}/conda-meta" ] ||
181+
[ -x "${prefix}/bin/conda" ]; then
181182
if [[ "${prefix}" != "${prefix%/envs/*}" ]]; then
182183
CONDA_DEFAULT_ENV="${venv##*/envs/}"
183184
else
@@ -233,7 +234,8 @@ EOS
233234
fi
234235

235236
# conda package anaconda/miniconda scripts (#173)
236-
if [ -x "${prefix}/bin/conda" ]; then
237+
if [ -d "${prefix}/conda-meta" ] ||
238+
[ -x "${prefix}/bin/conda" ]; then
237239
shopt -s nullglob
238240
case "${shell}" in
239241
fish )

bin/pyenv-sh-deactivate

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ if [ -n "$PYENV_VIRTUALENV_VERBOSE_ACTIVATE" ]; then
5959
fi
6060

6161
# conda package anaconda/miniconda scripts (#173)
62-
if [ -x "${prefix}/bin/conda" ]; then
62+
if [ -d "${prefix}/conda-meta" ] ||
63+
[ -x "${prefix}/bin/conda" ]; then
6364
shopt -s nullglob
6465
case "${shell}" in
6566
fish )

bin/pyenv-virtualenv-prefix

+15-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
set -e
88
[ -n "$PYENV_DEBUG" ] && set -x
9+
. "${BASH_SOURCE%/*}"/../libexec/pyenv-virtualenv-realpath
910

1011
if [ -z "$PYENV_ROOT" ]; then
1112
PYENV_ROOT="${HOME}/.pyenv"
@@ -19,6 +20,15 @@ else
1920
IFS=: versions=($(pyenv-version-name))
2021
fi
2122

23+
append_virtualenv_prefix() {
24+
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
25+
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}")
26+
else
27+
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
28+
exit 1
29+
fi
30+
}
31+
2232
VIRTUALENV_PREFIX_PATHS=()
2333
for version in "${versions[@]}"; do
2434
if [ "$version" = "system" ]; then
@@ -55,12 +65,11 @@ for version in "${versions[@]}"; do
5565
fi
5666
fi
5767
fi
58-
if [ -d "${VIRTUALENV_PREFIX_PATH}" ]; then
59-
VIRTUALENV_PREFIX_PATHS=("${VIRTUALENV_PREFIX_PATHS[@]}" "${VIRTUALENV_PREFIX_PATH:-${PYENV_PREFIX_PATH}}")
60-
else
61-
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
62-
exit 1
63-
fi
68+
append_virtualenv_prefix
69+
elif [ -d "${PYENV_PREFIX_PATH}/conda-meta" ]; then
70+
# conda
71+
VIRTUALENV_PREFIX_PATH="$(realpath "$(realpath "${PYENV_PREFIX_PATH}")"/../..)"
72+
append_virtualenv_prefix
6473
else
6574
echo "pyenv-virtualenv: version \`${version}' is not a virtualenv" 1>&2
6675
exit 1

bin/pyenv-virtualenvs

+1-32
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
set -e
99
[ -n "$PYENV_DEBUG" ] && set -x
10+
. "${BASH_SOURCE%/*}"/../libexec/pyenv-virtualenv-realpath
1011

1112
if [ -z "$PYENV_ROOT" ]; then
1213
PYENV_ROOT="${HOME}/.pyenv"
@@ -32,38 +33,6 @@ done
3233

3334
versions_dir="${PYENV_ROOT}/versions"
3435

35-
if ! enable -f "${BASH_SOURCE%/*}"/../libexec/pyenv-realpath.dylib realpath 2>/dev/null; then
36-
if [ -n "$PYENV_NATIVE_EXT" ]; then
37-
echo "pyenv: failed to load \`realpath' builtin" >&2
38-
exit 1
39-
fi
40-
41-
READLINK=$(type -p greadlink readlink | head -1)
42-
if [ -z "$READLINK" ]; then
43-
echo "pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
44-
exit 1
45-
fi
46-
47-
resolve_link() {
48-
$READLINK "$1"
49-
}
50-
51-
realpath() {
52-
local cwd="$PWD"
53-
local path="$1"
54-
local name
55-
56-
while [ -n "$path" ]; do
57-
name="${path##*/}"
58-
[ "$name" = "$path" ] || cd "${path%/*}"
59-
path="$(resolve_link "$name" || true)"
60-
done
61-
62-
echo "${PWD}/$name"
63-
cd "$cwd"
64-
}
65-
fi
66-
6736
if [ -d "$versions_dir" ]; then
6837
versions_dir="$(realpath "$versions_dir")"
6938
fi

etc/pyenv.d/which/conda.bash

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# newer versions of conda share programs from the real prefix
2+
# this hook tries to find the executable there
3+
4+
if [ ! -x "${PYENV_COMMAND_PATH}" ] && [[ "${PYENV_COMMAND_PATH##*/}" == "conda" ]]; then
5+
if [ -d "${PYENV_ROOT}/versions/${version}/conda-meta" ]; then
6+
conda_command_path="$(pyenv-virtualenv-prefix "$version")"/bin/"${PYENV_COMMAND_PATH##*/}"
7+
if [ -x "${conda_command_path}" ]; then
8+
PYENV_COMMAND_PATH="${conda_command_path}"
9+
fi
10+
fi
11+
fi

libexec/pyenv-virtualenv-realpath

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
# Summary: Substitute realpath if unavailable as a builtin or file
3+
# Usage: . pyenv-virtualenv-realpath
4+
5+
if ! {
6+
enable -f "${BASH_SOURCE%/*}"/../libexec/pyenv-realpath.dylib realpath ||
7+
type realpath
8+
} >/dev/null 2>&1; then
9+
if [ -n "$PYENV_NATIVE_EXT" ]; then
10+
echo "pyenv: failed to load \`realpath' builtin" >&2
11+
exit 1
12+
fi
13+
14+
READLINK=$(type -p greadlink readlink | head -1)
15+
if [ -z "$READLINK" ]; then
16+
echo "pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
17+
exit 1
18+
fi
19+
20+
resolve_link() {
21+
$READLINK "$1"
22+
}
23+
24+
normalize() {
25+
local IFS=/
26+
declare -a segments buffer
27+
for i in $*
28+
do
29+
segments=("$i" "${segments[@]}")
30+
done
31+
unset IFS
32+
declare -i skip=0
33+
for segment in "${segments[@]}"
34+
do
35+
case "$segment" in
36+
. | '')
37+
:
38+
;;
39+
..)
40+
((skip++))
41+
;;
42+
*)
43+
if ((skip))
44+
then
45+
((skip--))
46+
else
47+
buffer=("$segment" "${buffer[@]}")
48+
fi
49+
esac
50+
done
51+
while ((skip))
52+
do
53+
buffer=(.. "${buffer[@]}")
54+
((skip--))
55+
done
56+
if [[ "$*" == /* ]]
57+
then
58+
buffer=('' "${buffer[@]}")
59+
fi
60+
IFS=/
61+
path=${buffer[*]}
62+
echo "$path"
63+
}
64+
65+
realpath() {
66+
local cwd="$PWD"
67+
local path="$(normalize "$1")"
68+
local name
69+
70+
while [ -n "$path" ]; do
71+
name="${path##*/}"
72+
[ "$name" = "$path" ] || cd "${path%/*}"
73+
path="$(resolve_link "$name" || true)"
74+
done
75+
76+
echo "${PWD}/$name"
77+
cd "$cwd"
78+
}
79+
fi

0 commit comments

Comments
 (0)