From 6bb7f07d2d74aee3bb02421265bd28767e94dcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 13 Oct 2014 03:11:12 +0200 Subject: [PATCH 1/3] Avoid `rbenv-exec` calling out to `rbenv-version-name` twice Running any shim (and thus `rbenv-exec`) would always execute `rbenv-version-name` twice: once in `rbenv-exec` and another time in `rbenv-which`, even though RBENV_VERSION variable would have already been populated at this point. Now RBENV_VERSION is respected within `rbenv-which`. --- libexec/rbenv-which | 6 +++++- test/which.bats | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libexec/rbenv-which b/libexec/rbenv-which index 5d73673c..49906df6 100755 --- a/libexec/rbenv-which +++ b/libexec/rbenv-which @@ -48,7 +48,6 @@ remove_from_path() { echo "${result%:}" } -RBENV_VERSION="$(rbenv-version-name)" RBENV_COMMAND="$1" if [ -z "$RBENV_COMMAND" ]; then @@ -56,6 +55,8 @@ if [ -z "$RBENV_COMMAND" ]; then exit 1 fi +RBENV_VERSION="${RBENV_VERSION:-$(rbenv-version-name)}" + if [ "$RBENV_VERSION" = "system" ]; then PATH="$(remove_from_path "${RBENV_ROOT}/shims")" RBENV_COMMAND_PATH="$(command -v "$RBENV_COMMAND" || true)" @@ -72,6 +73,9 @@ done if [ -x "$RBENV_COMMAND_PATH" ]; then echo "$RBENV_COMMAND_PATH" +elif ! [ -d "${RBENV_ROOT}/versions/${RBENV_VERSION}" ]; then + echo "rbenv: version \`$RBENV_VERSION' is not installed" >&2 + exit 1 else echo "rbenv: $RBENV_COMMAND: command not found" >&2 diff --git a/test/which.bats b/test/which.bats index a9d9f82a..e52d5005 100644 --- a/test/which.bats +++ b/test/which.bats @@ -72,3 +72,12 @@ SH assert_success assert_output "HELLO=:hello:ugly:world:again" } + +@test "discovers version from rbenv-version-name" { + mkdir -p "$RBENV_ROOT" + cat > "${RBENV_ROOT}/version" <<<"1.8" + create_executable "1.8" "ruby" + + RBENV_VERSION= run rbenv-which ruby + assert_success "${RBENV_ROOT}/versions/1.8/bin/ruby" +} From e4cbf04592cfcd9d244fb83284e14524c8ba0377 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 13 Mar 2014 19:45:11 +0100 Subject: [PATCH 2/3] Improve performance of rbenv-which when RBENV_VERSION=system This implements removing of the shims path element via bash substitution, instead of jumping around in all the `$PATH` elements. --- libexec/rbenv-which | 46 ++++++++++++--------------------------------- test/which.bats | 25 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/libexec/rbenv-which b/libexec/rbenv-which index 49906df6..6b0d93a2 100755 --- a/libexec/rbenv-which +++ b/libexec/rbenv-which @@ -15,38 +15,6 @@ if [ "$1" = "--complete" ]; then exec rbenv shims --short fi -expand_path() { - if [ ! -d "$1" ]; then - return 1 - fi - - local cwd="$(pwd)" - cd "$1" - pwd - cd "$cwd" -} - -remove_from_path() { - local path_to_remove="$(expand_path "$1")" - local result="" - - if [ -z "$path_to_remove" ]; then - echo "${PATH}" - return - fi - - local paths - IFS=: paths=($PATH) - - for path in "${paths[@]}"; do - path="$(expand_path "$path" || true)" - if [ -n "$path" ] && [ "$path" != "$path_to_remove" ]; then - result="${result}${path}:" - fi - done - - echo "${result%:}" -} RBENV_COMMAND="$1" @@ -58,8 +26,18 @@ fi RBENV_VERSION="${RBENV_VERSION:-$(rbenv-version-name)}" if [ "$RBENV_VERSION" = "system" ]; then - PATH="$(remove_from_path "${RBENV_ROOT}/shims")" - RBENV_COMMAND_PATH="$(command -v "$RBENV_COMMAND" || true)" + # Remove shims from PATH. Use a loop, because Bash won't remove all ":foo:" + # in ":foo:foo:" in one go. + path=":$PATH:" + remove="${RBENV_ROOT}/shims" + while true; do + path_before="$path" + path="${path//:$remove:/:}" + if [[ "$path_before" = "$path" ]]; then + break + fi + done + RBENV_COMMAND_PATH="$(PATH=$path command -v "$RBENV_COMMAND" || true)" else RBENV_COMMAND_PATH="${RBENV_ROOT}/versions/${RBENV_VERSION}/bin/${RBENV_COMMAND}" fi diff --git a/test/which.bats b/test/which.bats index e52d5005..6e68a0e6 100644 --- a/test/which.bats +++ b/test/which.bats @@ -31,6 +31,31 @@ create_executable() { assert_success "${RBENV_TEST_DIR}/bin/kill-all-humans" } +@test "searches PATH for system version (shims prepended)" { + create_executable "${RBENV_TEST_DIR}/bin" "kill-all-humans" + create_executable "${RBENV_ROOT}/shims" "kill-all-humans" + + PATH="${RBENV_ROOT}/shims:$PATH" RBENV_VERSION=system run rbenv-which kill-all-humans + assert_success "${RBENV_TEST_DIR}/bin/kill-all-humans" +} + +@test "searches PATH for system version (shims appended)" { + create_executable "${RBENV_TEST_DIR}/bin" "kill-all-humans" + create_executable "${RBENV_ROOT}/shims" "kill-all-humans" + + PATH="$PATH:${RBENV_ROOT}/shims" RBENV_VERSION=system run rbenv-which kill-all-humans + assert_success "${RBENV_TEST_DIR}/bin/kill-all-humans" +} + +@test "searches PATH for system version (shims spread)" { + create_executable "${RBENV_TEST_DIR}/bin" "kill-all-humans" + create_executable "${RBENV_ROOT}/shims" "kill-all-humans" + + PATH="${RBENV_ROOT}/shims:${RBENV_ROOT}/shims:/tmp/non-existent:$PATH:${RBENV_ROOT}/shims" \ + RBENV_VERSION=system run rbenv-which kill-all-humans + assert_success "${RBENV_TEST_DIR}/bin/kill-all-humans" +} + @test "version not installed" { create_executable "2.0" "rspec" RBENV_VERSION=1.9 run rbenv-which rspec From 3ee395f9b576e4111650cef67328f4ffe3687b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 13 Oct 2014 12:24:45 +0200 Subject: [PATCH 3/3] Clean up PATH sanitization in rbenv-which --- libexec/rbenv-which | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libexec/rbenv-which b/libexec/rbenv-which index 6b0d93a2..f656537d 100755 --- a/libexec/rbenv-which +++ b/libexec/rbenv-which @@ -15,6 +15,16 @@ if [ "$1" = "--complete" ]; then exec rbenv shims --short fi +remove_from_path() { + local path_to_remove="$1" + local path_before + local result=":$PATH:" + while [ "$path_before" != "$result" ]; do + path_before="$result" + result="${result//:$path_to_remove:/:}" + done + echo "${result%:}" +} RBENV_COMMAND="$1" @@ -26,18 +36,8 @@ fi RBENV_VERSION="${RBENV_VERSION:-$(rbenv-version-name)}" if [ "$RBENV_VERSION" = "system" ]; then - # Remove shims from PATH. Use a loop, because Bash won't remove all ":foo:" - # in ":foo:foo:" in one go. - path=":$PATH:" - remove="${RBENV_ROOT}/shims" - while true; do - path_before="$path" - path="${path//:$remove:/:}" - if [[ "$path_before" = "$path" ]]; then - break - fi - done - RBENV_COMMAND_PATH="$(PATH=$path command -v "$RBENV_COMMAND" || true)" + PATH="$(remove_from_path "${RBENV_ROOT}/shims")" + RBENV_COMMAND_PATH="$(command -v "$RBENV_COMMAND" || true)" else RBENV_COMMAND_PATH="${RBENV_ROOT}/versions/${RBENV_VERSION}/bin/${RBENV_COMMAND}" fi