#!/usr/bin/env bash # # Summary: List all Python virtualenvs found in `$PYENV_ROOT/versions/*'. # Usage: pyenv virtualenvs [--bare] [--skip-aliases] [--only-aliases] # # List all virtualenvs found in `$PYENV_ROOT/versions/*' and its `$PYENV_ROOT/versions/envs/*'. set -e [ -n "$PYENV_DEBUG" ] && set -x if [ -z "$PYENV_ROOT" ]; then PYENV_ROOT="${HOME}/.pyenv" fi unset bare unset skip_aliases # Provide pyenv completions for arg; do case "$arg" in --complete ) echo --bare echo --skip-aliases echo --only-aliases exit ;; --bare ) bare=1 ;; --skip-aliases ) skip_aliases=1 ;; --only-aliases ) only_aliases=1 ;; * ) pyenv-help --usage virtualenvs >&2 exit 1 ;; esac done versions_dir="${PYENV_ROOT}/versions" if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then declare -A current_versions else current_versions=() fi if [ -n "$bare" ]; then include_system="" else hit_prefix="* " miss_prefix=" " OLDIFS="$IFS" IFS=: if [[ ${BASH_VERSINFO[0]} -gt 3 ]]; then for i in $(pyenv-version-name || true); do current_versions["$i"]="1" done else read -r -a current_versions <<< "$(pyenv-version-name || true)" fi IFS="$OLDIFS" include_system="1" fi num_versions=0 exists() { local car="$1" local cdar shift for cdar in "$@"; do if [ "${car}" == "${cdar}" ]; then return 0 fi done return 1 } print_version() { local version="${1:?}" if [[ -n $bare ]]; then echo "$version" return fi local path="${2:?}" if [[ -L "$path" ]]; then # Only resolve the link itself for printing, do not resolve further. # Doing otherwise would misinform the user of what the link contains. version_repr="$version --> $(readlink "$path")" else version_repr="$version" fi if [[ ${BASH_VERSINFO[0]} -ge 4 && ${current_versions["$1"]} ]]; then echo "${hit_prefix}${version_repr} (set by $(pyenv-version-origin))" elif [[ ${BASH_VERSINFO[0]} -le 3 ]] && exists "$1" "${current_versions[@]}"; then echo "${hit_prefix}${version_repr} (set by $(pyenv-version-origin))" else echo "${miss_prefix}${version_repr}" fi num_versions=$((num_versions + 1)) } shopt -s dotglob shopt -s nullglob version_dir_entries=("$versions_dir"/*) venv_dir_entries=("$versions_dir"/*/envs/*) if sort --version-sort /dev/null 2>&1; then # system sort supports version sorting OLDIFS="$IFS" IFS='||' read -r -a version_dir_entries <<< "$( printf "%s||" "${version_dir_entries[@]}" | sort --version-sort )" read -r -a venv_dir_entries <<< "$( printf "%s||" "${venv_dir_entries[@]}" | sort --version-sort )" IFS="$OLDIFS" fi if [ -z "$only_aliases" ]; then for env_path in "${venv_dir_entries[@]}"; do if [ -d "${env_path}" ]; then print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}" fi done fi if [ -z "$skip_aliases" ]; then for env_path in "${version_dir_entries[@]}"; do if [ -d "${env_path}" ] && [ -L "${env_path}" ]; then print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}" fi done fi shopt -u dotglob shopt -u nullglob if [ "$num_versions" -eq 0 ] && [ -n "$include_system" ]; then echo "Warning: no Python virtualenv detected on the system" >&2 exit 1 fi