diff --git a/bin/bats b/bin/bats index dea44d32..63846b20 100755 --- a/bin/bats +++ b/bin/bats @@ -3,42 +3,71 @@ set -e BATS_READLINK='true' +BATS_REALPATH='' if command -v 'greadlink' >/dev/null; then BATS_READLINK='greadlink' elif command -v 'readlink' >/dev/null; then BATS_READLINK='readlink' fi -bats_resolve_absolute_root_dir() { - local cwd="$PWD" - local path="$1" - local result="$2" - local target_dir - local target_name - local original_shell_options="$-" - - # Resolve the parent directory, e.g. /bin => /usr/bin on CentOS (#113). - set -P +set +e +if ! $BATS_READLINK -m $0 &>/dev/null; then + BATS_REALPATH='realpath' +fi +set -e - while true; do - target_dir="${path%/*}" - target_name="${path##*/}" +resolve_path() { + local path_to_bats=$1 + local target_path; - if [[ "$target_dir" != "$path" ]]; then - cd "$target_dir" + if [[ -L "$path_to_bats" ]]; then + # Busybox has no readlink from coreutils + if [[ ! -z "$BATS_REALPATH" ]]; then + target_path="$("$BATS_REALPATH" "$path_to_bats")" + # we need to traverse the paths + target_path="$(dirname "$target_path")" # strip bats + target_path="$(dirname "$target_path")" # strip bin + else + target_path="$("$BATS_READLINK" -m "$path_to_bats/../../")" fi - - if [[ -L "$target_name" ]]; then - path="$("$BATS_READLINK" "$target_name")" + elif [[ -f "$path_to_bats" ]]; then + target_path=$(dirname "$path_to_bats"); + if [[ ! -z "$BATS_REALPATH" ]]; then + target_path="$("$BATS_REALPATH" "$target_path")" + else + target_path="$("$BATS_READLINK" -m "$target_path")" + fi + target_path="$(dirname "$target_path")" # strip bin + elif [[ -d $path_to_bats ]]; then + if [[ ! -z "$BATS_REALPATH" ]]; then + target_path="$("$BATS_REALPATH" "$path_to_bats")" + target_path="$(dirname "$target_path")" else - printf -v "$result" -- '%s' "${PWD%/*}" - set +P "-$original_shell_options" - cd "$cwd" - return + target_path="$("$BATS_READLINK" -m "$path_to_bats/../")" fi - done + fi + + echo "$target_path"; +} + +bats_resolve_absolute_root_dir() { + local cwd="$PWD" + local path_to_bats="$1" + local result="$2" + local target_path + + if [[ "$path_to_bats" = $(basename $1) ]] ; then + path_to_bats=$(type -p "$path_to_bats") + fi + + target_path="$(resolve_path $path_to_bats)" + if [[ "$target_path" == '.' ]]; + then + target_path="$(resolve_path "$target_path")" + fi + printf -v "$result" -- '%s' "$target_path" } export BATS_ROOT bats_resolve_absolute_root_dir "$0" 'BATS_ROOT' -exec "$BATS_ROOT/libexec/bats-core/bats" "$@" +exec env BATS_ROOT="$BATS_ROOT" "$BATS_ROOT/libexec/bats-core/bats" "$@" diff --git a/test/root.bats b/test/root.bats index 574e0056..de73db58 100644 --- a/test/root.bats +++ b/test/root.bats @@ -40,24 +40,25 @@ setup() { # The resolution scheme here is: # +# Set in setup # - /bin => /usr/bin (relative directory) -# - /usr/bin/foo => /usr/bin/bar (relative executable) -# - /usr/bin/bar => /opt/bats/bin0/bar (absolute executable) -# - /opt/bats/bin0 => /opt/bats/bin1 (relative directory) -# - /opt/bats/bin1 => /opt/bats/bin2 (absolute directory) -# - /opt/bats/bin2/bar => /opt/bats-core/bin/bar (absolute executable) -# - /opt/bats-core/bin/bar => /opt/bats-core/bin/baz (relative executable) -# - /opt/bats-core/bin/baz => /opt/bats-core/bin/bats (relative executable) @test "set BATS_ROOT with extreme symlink resolution" { cd "$BATS_TEST_SUITE_TMPDIR" mkdir -p "opt/bats/bin2" +# - /usr/bin/foo => /usr/bin/bar (relative executable) ln -s bar usr/bin/foo +# - /usr/bin/bar => /opt/bats/bin0/bar (absolute executable) ln -s "$BATS_TEST_SUITE_TMPDIR/opt/bats/bin0/bar" usr/bin/bar +# - /opt/bats/bin0 => /opt/bats/bin1 (relative directory) ln -s bin1 opt/bats/bin0 +# - /opt/bats/bin1 => /opt/bats/bin2 (absolute directory) ln -s "$BATS_TEST_SUITE_TMPDIR/opt/bats/bin2" opt/bats/bin1 +# - /opt/bats/bin2/bar => /opt/bats-core/bin/bar (absolute executable) ln -s "$BATS_TEST_SUITE_TMPDIR/opt/bats-core/bin/bar" opt/bats/bin2/bar +# - /opt/bats-core/bin/bar => /opt/bats-core/bin/baz (relative executable) ln -s baz opt/bats-core/bin/bar +# - /opt/bats-core/bin/baz => /opt/bats-core/bin/bats (relative executable) ln -s bats opt/bats-core/bin/baz cd - >/dev/null @@ -65,3 +66,26 @@ setup() { [ "$status" -eq 0 ] [ "${output%% *}" == 'Bats' ] } + +@test "set BATS_ROOT when calling from same dir" { + cd "$BATS_TEST_SUITE_TMPDIR" + run ./bin/bats -v + [ "$status" -eq 0 ] + [ "${output%% *}" == 'Bats' ] +} + +@test "set BATS_ROOT from PATH" { + cd /tmp + PATH="$PATH:$BATS_TEST_SUITE_TMPDIR/bin" + run bats -v + [ "$status" -eq 0 ] + [ "${output%% *}" == 'Bats' ] +} + +@test "#182 and probably #184 as well" { + cd /tmp + PATH="$PATH:$BATS_TEST_SUITE_TMPDIR/bin" + run bash bats -v + [ "$status" -eq 0 ] + [ "${output%% *}" == 'Bats' ] +}