From a80488730710eeec85e20e1e054a8efe9052df4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sat, 5 Dec 2020 14:36:52 +0200 Subject: [PATCH 1/2] rehash: use associative array to hold registered shims MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "hyperfine pyenv-rehash" before on my bash 4.4: Time (mean ± σ): 172.8 ms ± 8.2 ms [User: 185.0 ms, System: 24.8 ms] Range (min … max): 164.2 ms … 198.4 ms 15 runs After: Time (mean ± σ): 113.8 ms ± 2.8 ms [User: 127.1 ms, System: 26.1 ms] Range (min … max): 108.0 ms … 117.6 ms 25 runs --- libexec/pyenv-rehash | 78 ++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/libexec/pyenv-rehash b/libexec/pyenv-rehash index 4e31994e..0ca0f276 100755 --- a/libexec/pyenv-rehash +++ b/libexec/pyenv-rehash @@ -123,34 +123,62 @@ make_shims() { done } -registered_shims=" " +if ((${BASH_VERSINFO[0]} > 3)); then -# Registers the name of a shim to be generated. -register_shim() { - registered_shims="${registered_shims}${1} " -} + declare -A registered_shims -# Install all the shims registered via `make_shims` or `register_shim` directly. -install_registered_shims() { - local shim file - for shim in $registered_shims; do - file="${SHIM_PATH}/${shim}" - [ -e "$file" ] || cp "$PROTOTYPE_SHIM_PATH" "$file" - done -} + # Registers the name of a shim to be generated. + register_shim() { + registered_shims["$1"]=1 + } -# Once the registered shims have been installed, we make a second pass -# over the contents of the shims directory. Any file that is present -# in the directory but has not been registered as a shim should be -# removed. -remove_stale_shims() { - local shim - for shim in "$SHIM_PATH"/*; do - if [[ "$registered_shims" != *" ${shim##*/} "* ]]; then - rm -f "$shim" - fi - done -} + # Install all shims registered via `make_shims` or `register_shim` directly. + install_registered_shims() { + local shim file + for shim in "${!registered_shims[@]}"; do + file="${SHIM_PATH}/${shim}" + [ -e "$file" ] || cp "$PROTOTYPE_SHIM_PATH" "$file" + done + } + + # Once the registered shims have been installed, we make a second pass + # over the contents of the shims directory. Any file that is present + # in the directory but has not been registered as a shim should be + # removed. + remove_stale_shims() { + local shim + for shim in "$SHIM_PATH"/*; do + if [[ ! ${registered_shims["${shim##*/}"]} ]]; then + rm -f "$shim" + fi + done + } + +else # Same for bash < 4. + + registered_shims=" " + + register_shim() { + registered_shims="${registered_shims}${1} " + } + + install_registered_shims() { + local shim file + for shim in $registered_shims; do + file="${SHIM_PATH}/${shim}" + [ -e "$file" ] || cp "$PROTOTYPE_SHIM_PATH" "$file" + done + } + + remove_stale_shims() { + local shim + for shim in "$SHIM_PATH"/*; do + if [[ "$registered_shims" != *" ${shim##*/} "* ]]; then + rm -f "$shim" + fi + done + } +fi shopt -s nullglob From c4e556ededaff1110ced3e0a091caf83c88174f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sat, 5 Dec 2020 15:09:46 +0200 Subject: [PATCH 2/2] versions: use associative array to hold current versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "hyperfine pyenv-versions" before with my bash 4.4: Time (mean ± σ): 81.7 ms ± 2.2 ms [User: 67.8 ms, System: 15.7 ms] Range (min … max): 78.3 ms … 87.2 ms 34 runs After: Time (mean ± σ): 70.6 ms ± 2.4 ms [User: 55.6 ms, System: 16.9 ms] Range (min … max): 67.9 ms … 78.9 ms 41 runs --- libexec/pyenv-versions | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libexec/pyenv-versions b/libexec/pyenv-versions index 019c0e90..91c99512 100755 --- a/libexec/pyenv-versions +++ b/libexec/pyenv-versions @@ -64,16 +64,27 @@ if [ -d "$versions_dir" ]; then versions_dir="$(realpath "$versions_dir")" fi +if ((${BASH_VERSINFO[0]} > 3)); then + declare -A current_versions +else + current_versions=() +fi if [ -n "$bare" ]; then hit_prefix="" miss_prefix="" - current_versions=() include_system="" else hit_prefix="* " miss_prefix=" " OLDIFS="$IFS" - IFS=: current_versions=($(pyenv-version-name || true)) + IFS=: + if ((${BASH_VERSINFO[0]} > 3)); then + for i in $(pyenv-version-name || true); do + current_versions["$i"]="1" + done + else + current_versions=($(pyenv-version-name || true)) + fi IFS="$OLDIFS" include_system="1" fi @@ -93,7 +104,9 @@ exists() { } print_version() { - if exists "$1" "${current_versions[@]}"; then + if [[ ${BASH_VERSINFO[0]} -ge 4 && ${current_versions["$1"]} ]]; then + echo "${hit_prefix}$1 (set by $(pyenv-version-origin))" + elif (( ${BASH_VERSINFO[0]} < 3 )) && exists "$1" "${current_versions[@]}"; then echo "${hit_prefix}$1 (set by $(pyenv-version-origin))" else echo "${miss_prefix}$1"