Skip to content

Commit cbdd0b8

Browse files
authored
Merge pull request #8 from ORESoftware/hardening/ores-lint-effective-hooks
fix: honor Git effective hook paths for ores-lint
2 parents 988e857 + 86dc5a2 commit cbdd0b8

3 files changed

Lines changed: 85 additions & 9 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: ores-lint hook contract
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '.ores-lint/install-git-hooks.sh'
7+
- '.ores-lint/test-install-git-hooks.sh'
8+
- '.github/workflows/ores-lint-hook-contract.yml'
9+
push:
10+
branches: [master]
11+
paths:
12+
- '.ores-lint/install-git-hooks.sh'
13+
- '.ores-lint/test-install-git-hooks.sh'
14+
- '.github/workflows/ores-lint-hook-contract.yml'
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
19+
20+
concurrency:
21+
group: ores-lint-hook-contract-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
contract:
26+
runs-on: ubuntu-24.04
27+
timeout-minutes: 5
28+
steps:
29+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
30+
with:
31+
persist-credentials: false
32+
- name: Syntax
33+
run: |
34+
sh -n .ores-lint/install-git-hooks.sh
35+
sh -n .ores-lint/test-install-git-hooks.sh
36+
- name: Installer contract
37+
run: sh .ores-lint/test-install-git-hooks.sh

‎.ores-lint/install-git-hooks.sh‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
#!/bin/sh
22
# Optional: install a pre-push hook that runs ores-lint.
3-
# Not installed automatically by the rollout - run this yourself per repo.
4-
set -u
5-
ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || { echo "not a git repo"; exit 1; }
6-
HOOK="$ROOT/.git/hooks/pre-push"
7-
if [ -e "$HOOK" ] && ! grep -q 'ores-lint' "$HOOK"; then
8-
echo "refusing to clobber an existing pre-push hook: $HOOK"
3+
set -eu
4+
ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || { echo "not a git repo" >&2; exit 1; }
5+
HOOKS_PATH=$(git -C "$ROOT" config --get core.hooksPath 2>/dev/null || true)
6+
case "$HOOKS_PATH" in
7+
"") GIT_DIR=$(git -C "$ROOT" rev-parse --absolute-git-dir); HOOK_DIR="$GIT_DIR/hooks" ;;
8+
/*) HOOK_DIR="$HOOKS_PATH" ;;
9+
'~/'*) HOOK_DIR="$HOME/${HOOKS_PATH#??}" ;;
10+
*) HOOK_DIR="$ROOT/$HOOKS_PATH" ;;
11+
esac
12+
mkdir -p "$HOOK_DIR"
13+
HOOK="$HOOK_DIR/pre-push"
14+
if [ -e "$HOOK" ] && ! grep -Fq 'installed by .ores-lint/install-git-hooks.sh' "$HOOK"; then
15+
echo "refusing to clobber an existing pre-push hook: $HOOK" >&2
916
exit 1
1017
fi
1118
cat > "$HOOK" <<'INNER'
1219
#!/bin/sh
1320
# installed by .ores-lint/install-git-hooks.sh
14-
[ -x "$(git rev-parse --show-toplevel)/.ores-lint/lint.sh" ] && \
15-
sh "$(git rev-parse --show-toplevel)/.ores-lint/lint.sh"
16-
exit 0
21+
set -eu
22+
ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 1
23+
LINT="$ROOT/.ores-lint/lint.sh"
24+
if [ ! -x "$LINT" ]; then
25+
echo "ores-lint pre-push: missing executable $LINT" >&2
26+
exit 1
27+
fi
28+
exec sh "$LINT"
1729
INNER
1830
chmod +x "$HOOK"
1931
echo "installed $HOOK"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
set -eu
3+
SOURCE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
4+
TMP_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/ores-lint-hooks.XXXXXX")
5+
trap 'rm -rf "$TMP_ROOT"' EXIT HUP INT TERM
6+
new_repo() {
7+
repo="$TMP_ROOT/$1"
8+
mkdir -p "$repo/.ores-lint"
9+
git -C "$repo" init -q
10+
cp "$SOURCE_DIR/install-git-hooks.sh" "$repo/.ores-lint/install-git-hooks.sh"
11+
printf '%s\n' '#!/bin/sh' ': > "$(git rev-parse --show-toplevel)/lint-ran"' > "$repo/.ores-lint/lint.sh"
12+
chmod +x "$repo/.ores-lint/lint.sh"
13+
printf '%s\n' "$repo"
14+
}
15+
repo=$(new_repo default)
16+
(cd "$repo" && sh .ores-lint/install-git-hooks.sh && hook="$(git rev-parse --absolute-git-dir)/hooks/pre-push" && test -x "$hook" && "$hook" && test -f lint-ran)
17+
repo=$(new_repo relative)
18+
(cd "$repo" && git config core.hooksPath .githooks && sh .ores-lint/install-git-hooks.sh && test -x .githooks/pre-push && .githooks/pre-push && test -f lint-ran && test ! -e "$(git rev-parse --absolute-git-dir)/hooks/pre-push")
19+
repo=$(new_repo absolute)
20+
absolute_hooks="$TMP_ROOT/absolute-hooks"
21+
(cd "$repo" && git config core.hooksPath "$absolute_hooks" && sh .ores-lint/install-git-hooks.sh && test -x "$absolute_hooks/pre-push")
22+
repo=$(new_repo tilde)
23+
mkdir -p "$TMP_ROOT/home"
24+
(cd "$repo" && HOME="$TMP_ROOT/home" git config core.hooksPath '~/custom-hooks' && HOME="$TMP_ROOT/home" sh .ores-lint/install-git-hooks.sh && test -x "$TMP_ROOT/home/custom-hooks/pre-push")
25+
repo=$(new_repo conflict)
26+
(cd "$repo" && git config core.hooksPath .githooks && mkdir -p .githooks && printf '%s\n' '#!/bin/sh' 'echo existing' > .githooks/pre-push && chmod +x .githooks/pre-push && before=$(cat .githooks/pre-push) && if sh .ores-lint/install-git-hooks.sh; then exit 1; fi && test "$(cat .githooks/pre-push)" = "$before")
27+
printf '%s\n' 'ores-lint Git hook installer contract: PASS'

0 commit comments

Comments
 (0)