66# List all virtualenvs found in `$PYENV_ROOT/versions/*' and its `$PYENV_ROOT/versions/envs/*'.
77
88set -e
9- [ -n " $PYENV_DEBUG " ] && set -x
10- if [ -L " ${BASH_SOURCE} " ]; then
11- READLINK=$( type -p greadlink readlink | head -1)
12- if [ -z " $READLINK " ]; then
13- echo " pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
14- exit 1
15- fi
16- resolve_link () {
17- $READLINK -f " $1 "
18- }
19- script_path=$( resolve_link ${BASH_SOURCE} )
20- else
21- script_path=${BASH_SOURCE}
22- fi
23-
24- . ${script_path%/* } /../libexec/pyenv-virtualenv-realpath
9+ [[ -n $PYENV_DEBUG ]] && set -x
2510
26- if [ -z " $PYENV_ROOT " ]; then
11+ if [[ -z $PYENV_ROOT ] ]; then
2712 PYENV_ROOT=" ${HOME} /.pyenv"
2813fi
2914
4732
4833versions_dir=" ${PYENV_ROOT} /versions"
4934
50- if [ -d " $versions_dir " ]; then
51- versions_dir=" $( realpath " $versions_dir " ) "
52- fi
53-
54- if [ -n " $bare " ]; then
55- hit_prefix=" "
56- miss_prefix=" "
57- current_versions=()
58- unset print_origin
59- include_system=" "
35+ if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then
36+ declare -A current_versions
6037else
38+ current_versions=()
39+ fi
40+ if [[ -z $bare ]]; then
6141 hit_prefix=" * "
6242 miss_prefix=" "
6343 OLDIFS=" $IFS "
64- IFS=: current_versions=($( pyenv-version-name || true) )
44+ IFS=:
45+ if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then
46+ for i in $( pyenv-version-name || true) ; do
47+ current_versions[" $i " ]=" 1"
48+ done
49+ else
50+ read -r -a current_versions <<< " $(pyenv-version-name || true)"
51+ fi
6552 IFS=" $OLDIFS "
66- print_origin=" 1"
67- include_system=" "
6853fi
6954
70- num_versions=0
71-
7255exists () {
7356 local car=" $1 "
7457 local cdar
@@ -82,39 +65,67 @@ exists() {
8265}
8366
8467print_version () {
85- if exists " $1 " " ${current_versions[@]} " ; then
86- echo " ${hit_prefix}${1}${print_origin+$2 } "
68+ local version=" ${1:? } "
69+ if [[ -n $bare ]]; then
70+ echo " $version "
71+ return
72+ fi
73+ local path=" ${2:? } "
74+ if [[ -L " $path " ]]; then
75+ version_repr=" $version --> $( readlink " $path " ) "
76+ else
77+ version_repr=" $version (created from $( pyenv-virtualenv-prefix " $version " 2> /dev/null) )"
78+ fi
79+ if [[ ${BASH_VERSINFO[0]} -gt 3 && ${current_versions["$1"]} ]] || \
80+ { [[ ${BASH_VERSINFO[0]} -le 3 ]] && exists " $1 " " ${current_versions[@]} " ; }; then
81+ echo " ${hit_prefix}${version_repr} (set by $( pyenv-version-origin) )"
8782 else
88- echo " ${miss_prefix}${1}${print_origin+ $2 } "
83+ echo " ${miss_prefix}${version_repr } "
8984 fi
90- num_versions=$(( num_versions + 1 ))
9185}
9286
9387shopt -s dotglob
9488shopt -s nullglob
95- for path in " $versions_dir " /* ; do
96- if [ -d " $path " ]; then
97- if [ -n " $skip_aliases " ] && [ -L " $path " ]; then
98- target=" $( realpath " $path " ) "
99- [ " ${target%/*/ envs/* } " != " $versions_dir " ] || continue
100- fi
101- virtualenv_prefix=" $( pyenv-virtualenv-prefix " ${path##*/ } " 2> /dev/null || true) "
102- if [ -d " ${virtualenv_prefix} " ]; then
103- print_version " ${path##*/ } " " (created from ${virtualenv_prefix} )"
104- fi
105- for venv_path in " ${path} /envs/" * ; do
106- venv=" ${path##*/ } /envs/${venv_path##*/ } "
107- virtualenv_prefix=" $( pyenv-virtualenv-prefix " ${venv} " 2> /dev/null || true) "
108- if [ -d " ${virtualenv_prefix} " ]; then
109- print_version " ${venv} " " (created from ${virtualenv_prefix} )"
89+ version_dir_entries=(" $versions_dir " /* )
90+ venv_dir_entries=(" $versions_dir " /* /envs/* )
91+
92+ if sort --version-sort < /dev/null > /dev/null 2>&1 ; then
93+ # system sort supports version sorting
94+ OLDIFS=" $IFS "
95+ IFS=' ||'
96+
97+ read -r -a version_dir_entries <<< " $(
98+ printf " %s|| " " ${version_dir_entries[@]} " |
99+ sort --version-sort
100+ )"
101+
102+ read -r -a venv_dir_entries <<< " $(
103+ printf " %s|| " " ${venv_dir_entries[@]} " |
104+ sort --version-sort
105+ )"
106+
107+ IFS=" $OLDIFS "
108+ fi
109+
110+ for env_path in " ${venv_dir_entries[@]} " ; do
111+ if [[ -d ${env_path} ]]; then
112+ print_version " ${env_path# " ${PYENV_ROOT} " / versions/ } " " ${env_path} "
113+ fi
114+ done
115+
116+ for env_path in " ${version_dir_entries[@]} " ; do
117+ if [[ -d ${env_path} ]]; then
118+ if [[ -L ${env_path} ]]; then
119+ if [[ -z $skip_aliases ]]; then
120+ print_version " ${env_path# " ${PYENV_ROOT} " / versions/ } " " ${env_path} "
110121 fi
111- done
122+ # Mimics the test from pyenv-virtualenv-prefix
123+ # XXX: refactor itto a shared module ?
124+ elif [[ -f " ${env_path} /bin/activate" ]]; then
125+ print_version " ${env_path# " ${PYENV_ROOT} " / versions/ } " " ${env_path} "
126+ fi
112127 fi
113128done
129+
114130shopt -u dotglob
115131shopt -u nullglob
116-
117- if [ " $num_versions " -eq 0 ] && [ -n " $include_system " ]; then
118- echo " Warning: no Python virtualenv detected on the system" >&2
119- exit 1
120- fi
0 commit comments