1111
1212set -e
1313
14- function collect_links () {
15- # Collect all symlinks named python that point into $PYENV_ROOT
16- DIR=" $1 "
17- local -n _links=$2
18- cmd=" readlink -f '{}' | grep -q ${PYENV_ROOT} "
19- unset i
20- while IFS= read -r -d $' \0' file; do
21- _links[i++]=" $file "
22- done < <( find -H " $DIR " -name " python" -type l -exec sh -c " $cmd " \; -print0)
23- }
24-
25- function collect_pairs () {
26- # Turn each link into a (version, venv) string pair
27- local -n _links=$1 _versions=$2 _venvs=$3
28-
29- # Regex to extract the pyenv version from the target string. The
30- # second group consumes the actual binary (`python`, `pypy3`, etc)
31- regex=" ${PYENV_ROOT} /versions/(.+)/bin/(.+)"
32-
33- unset i
34- for link in " ${_links[@]} " ; do
35- # `$link` is the `python` symlink, and `$target` is its target.
36- linkpath=$( realpath -s " $link " )
37- target=$( readlink -f " $link " )
38- [[ " $target " =~ $regex ]]
39- version=" ${BASH_REMATCH[1]} "
40- # Only capture links outside PYENV_ROOT or inside pyenv-virtualenv venvs
41- if grep -v -q " $PYENV_ROOT " <<< " $linkpath" || \
42- grep -q " $PYENV_ROOT /versions/$version /envs" <<< " $linkpath"
43- then
44- _versions[i]=" $version "
45- _venvs[i++]=" ${link%/ bin/ python} "
46- fi
47- done
48- }
49-
50- function print_pairs () {
51- # Print each (version, venv) pair
52- local -n _versions=$1 _venvs=$2
53- local -i K=${# _versions[@]} width=0 maxwidth=0
54-
55- # Use the longest $version to setup the columns
56- for (( k= 0 ; k < K; k++ )) ; do
57- width=${# _versions[k]}
58- if (( width > maxwidth )) ; then maxwidth=$width ; fi
59- done
60-
61- for (( k= 0 ; k < K; k++ )) ; do
62- if [ -z " $RAW " ]; then
63- printf " %-*s %s\n" " $maxwidth " " ${_versions[$k]} " " ${_venvs[k]} "
64- else
65- echo " ${_versions[$k]} " :" ${_venvs[$k]} "
66- fi
67- done | sort
68- }
69-
7014parse_options () {
7115 # Parse the command line options. Taken from `pyenv-virtualenv`
7216 OPTIONS=()
@@ -91,10 +35,6 @@ parse_options() {
9135 done
9236}
9337
94- if [ -z " $PYENV_ROOT " ]; then
95- PYENV_ROOT=$( pyenv root)
96- fi
97-
9838unset RAW
9939parse_options " $@ "
10040for option in " ${OPTIONS[@]} " ; do
@@ -114,14 +54,57 @@ if [[ "${#ARGUMENTS[@]}" == 0 ]]; then
11454elif [[ " ${# ARGUMENTS[@]} " == 1 ]]; then
11555 DIR=" ${ARGUMENTS[0]} "
11656else
57+ echo -e " \nToo many directory arguments.\n"
11758 pyenv help users
11859 exit 1
11960fi
12061
62+ # ----------------------------------------------------------------------------
63+ # Finished parsing the arguments. Begin the actual functionality.
64+
12165# The `links` are the symlink pathnames, `versions` are pyenv version strings,
12266# and `venvs` are venv pathnames. Using parallel arrays since arrays-of-arrays
12367# are a pain in bash. Keeping versions and venvs separate avoids needing awk.
12468declare -a links versions venvs
125- collect_links " $DIR " links
126- collect_pairs links versions venvs
127- print_pairs versions venvs
69+
70+ if [ -z " $PYENV_ROOT " ]; then
71+ PYENV_ROOT=$( pyenv root)
72+ fi
73+
74+ # Collect all symlinks named `python` that point into $PYENV_ROOT
75+ cmd=" readlink -f '{}' | grep -q ${PYENV_ROOT} "
76+ unset i
77+ while IFS= read -r -d $' \0' file; do
78+ links[i++]=" $file "
79+ done < <( find -H " $DIR " -name " python" -type l -exec sh -c " $cmd " \; -print0)
80+
81+ # Turn each link into a (version, venv) string pair
82+ regex=" ${PYENV_ROOT} /versions/(.+)/bin/(.+)"
83+ unset i
84+ for link in " ${links[@]} " ; do
85+ linkpath=$( realpath -s " $link " )
86+ target=$( readlink -f " $link " )
87+ [[ " $target " =~ $regex ]]
88+ version=" ${BASH_REMATCH[1]} "
89+ # Only capture links outside PYENV_ROOT or inside pyenv-virtualenv venvs
90+ if grep -v -q " $PYENV_ROOT " <<< " $linkpath" || \
91+ grep -q " $PYENV_ROOT /versions/$version /envs" <<< " $linkpath"
92+ then
93+ versions[i]=" $version "
94+ venvs[i++]=" ${link%/ bin/ python} "
95+ fi
96+ done
97+
98+ # Print each (version, venv) pair
99+ declare -i K=${# versions[@]} width=0 maxwidth=0
100+ for (( k= 0 ; k < K; k++ )) ; do
101+ width=${# versions[k]}
102+ if (( width > maxwidth )) ; then maxwidth=$width ; fi
103+ done
104+ for (( k= 0 ; k < K; k++ )) ; do
105+ if [ -z " $RAW " ]; then
106+ printf " %-*s %s\n" " $maxwidth " " ${versions[$k]} " " ${venvs[k]} "
107+ else
108+ echo " ${versions[$k]} " :" ${venvs[$k]} "
109+ fi
110+ done | sort
0 commit comments