Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/commands/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ __FUNC___run_post_cd_hooks() {
[ -z "$_gtr_hook" ] && continue
case "$_gtr_seen" in *"|$_gtr_hook|"*) continue ;; esac
_gtr_seen="$_gtr_seen|$_gtr_hook|"
eval "$_gtr_hook" || echo "__FUNC__: postCd hook failed: $_gtr_hook" >&2
eval "$_gtr_hook" </dev/null || echo "__FUNC__: postCd hook failed: $_gtr_hook" >&2
done <<< "$_gtr_hooks"
unset WORKTREE_PATH REPO_ROOT BRANCH
fi
Expand Down Expand Up @@ -303,7 +303,7 @@ __FUNC___run_post_cd_hooks() {
[ -z "$_gtr_hook" ] && continue
case "$_gtr_seen" in *"|$_gtr_hook|"*) continue ;; esac
_gtr_seen="$_gtr_seen|$_gtr_hook|"
eval "$_gtr_hook" || echo "__FUNC__: postCd hook failed: $_gtr_hook" >&2
eval "$_gtr_hook" </dev/null || echo "__FUNC__: postCd hook failed: $_gtr_hook" >&2
done <<< "$_gtr_hooks"
unset WORKTREE_PATH REPO_ROOT BRANCH
fi
Expand Down
4 changes: 2 additions & 2 deletions lib/hooks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ run_hooks() {
done
# Execute the hook
eval "$hook"
); then
) </dev/null; then
log_info "Hook $hook_count completed successfully"
else
local rc=$?
Expand Down Expand Up @@ -118,7 +118,7 @@ run_hooks_export() {
log_info "Hook $hook_count: $hook"

# eval directly (no subshell) so exports persist
eval "$hook" || log_warn "Hook $hook_count failed (continuing)"
eval "$hook" </dev/null || log_warn "Hook $hook_count failed (continuing)"
done <<EOF
$hooks
EOF
Expand Down
36 changes: 36 additions & 0 deletions tests/hooks.bats
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ teardown() {
[ "$status" -eq 1 ]
}

@test "run_hooks continues after hook that reads stdin (postCreate)" {
git config --add gtr.hook.postCreate 'echo first >> "$REPO_ROOT/order"'
git config --add gtr.hook.postCreate 'cat'
git config --add gtr.hook.postCreate 'echo third >> "$REPO_ROOT/order"'
run_hooks postCreate REPO_ROOT="$TEST_REPO"
[ "$(head -1 "$TEST_REPO/order")" = "first" ]
[ "$(tail -1 "$TEST_REPO/order")" = "third" ]
}

@test "run_hooks continues after hook that reads stdin (preRemove)" {
git config --add gtr.hook.preRemove 'echo first >> "$REPO_ROOT/order"'
git config --add gtr.hook.preRemove 'cat'
git config --add gtr.hook.preRemove 'echo third >> "$REPO_ROOT/order"'
run_hooks preRemove REPO_ROOT="$TEST_REPO"
[ "$(head -1 "$TEST_REPO/order")" = "first" ]
[ "$(tail -1 "$TEST_REPO/order")" = "third" ]
}

@test "run_hooks continues after hook that reads stdin (postRemove)" {
git config --add gtr.hook.postRemove 'echo first >> "$REPO_ROOT/order"'
git config --add gtr.hook.postRemove 'cat'
git config --add gtr.hook.postRemove 'echo third >> "$REPO_ROOT/order"'
run_hooks postRemove REPO_ROOT="$TEST_REPO"
[ "$(head -1 "$TEST_REPO/order")" = "first" ]
[ "$(tail -1 "$TEST_REPO/order")" = "third" ]
}

@test "run_hooks REPO_ROOT and BRANCH env vars available" {
git config --add gtr.hook.postCreate 'echo "$REPO_ROOT|$BRANCH" > "$REPO_ROOT/vars"'
run_hooks postCreate REPO_ROOT="$TEST_REPO" BRANCH="test-branch"
Expand Down Expand Up @@ -134,3 +161,12 @@ teardown() {
(cd "$TEST_REPO" && run_hooks_export postCd REPO_ROOT="$TEST_REPO")
[ -z "${LEAK_TEST:-}" ]
}

@test "run_hooks_export continues after hook that reads stdin (postCd)" {
git config --add gtr.hook.postCd 'echo first >> "$REPO_ROOT/order"'
git config --add gtr.hook.postCd 'cat'
git config --add gtr.hook.postCd 'echo third >> "$REPO_ROOT/order"'
(cd "$TEST_REPO" && run_hooks_export postCd REPO_ROOT="$TEST_REPO")
[ "$(head -1 "$TEST_REPO/order")" = "first" ]
[ "$(tail -1 "$TEST_REPO/order")" = "third" ]
}
62 changes: 62 additions & 0 deletions tests/init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,52 @@ printf 'REPLY=%s\n' "${COMPREPLY[*]}"
BASH
}

run_generated_post_cd_hooks() {
local shell_name="$1"

"$shell_name" -s -- "$PROJECT_ROOT" "$shell_name" <<'SCRIPT'
PROJECT_ROOT="$1"
shell_name="$2"

log_info() { :; }
log_warn() { :; }
log_error() { :; }
show_command_help() { :; }
compdef() { :; }

# shellcheck disable=SC1090
. "$PROJECT_ROOT/lib/commands/init.sh"

repo=$(mktemp -d)
cleanup() {
rm -rf "$repo"
}
trap cleanup EXIT

git -C "$repo" init --quiet
git -C "$repo" config user.name "Test User"
git -C "$repo" config user.email "test@example.com"
git -C "$repo" commit --allow-empty -m "init" --quiet

git -C "$repo" config --add gtr.hook.postCd 'echo first >> "$REPO_ROOT/order"'
git -C "$repo" config --add gtr.hook.postCd 'cat'
git -C "$repo" config --add gtr.hook.postCd 'echo third >> "$REPO_ROOT/order"'

eval "$(cmd_init "$shell_name")"
gtr_run_post_cd_hooks "$repo"

printf 'ORDER='
paste -sd, "$repo/order"
printf '\n'
SCRIPT
}

require_runtime_shell() {
local shell_name="$1"

command -v "$shell_name" >/dev/null 2>&1 || skip "$shell_name is not installed"
}

# ── Default function name ────────────────────────────────────────────────────

@test "bash output defines gtr() function by default" {
Expand Down Expand Up @@ -253,6 +299,22 @@ BASH
[[ "$output" == *'could not determine new directory for --cd'* ]]
}

@test "bash generated postCd hooks continue after stdin read" {
require_runtime_shell bash
run run_generated_post_cd_hooks bash

[ "$status" -eq 0 ]
[ "$output" = "ORDER=first,third" ]
}

@test "zsh generated postCd hooks continue after stdin read" {
require_runtime_shell zsh
run run_generated_post_cd_hooks zsh

[ "$status" -eq 0 ]
[ "$output" = "ORDER=first,third" ]
}

@test "fish output uses worktree diff to locate the new directory for --cd" {
run cmd_init fish
[ "$status" -eq 0 ]
Expand Down
Loading