Skip to content

Commit b7cc484

Browse files
committed
test(trace): add golden files for the generated git hook scripts
Assisted-by: Claude Code Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev> Chainloop-Trace-Sessions: a5941a7b-7e2e-46b4-b95d-cd9fadb00b3b
1 parent e5328d2 commit b7cc484

7 files changed

Lines changed: 91 additions & 0 deletions

File tree

‎app/cli/internal/trace/hooks/hooks_test.go‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"os"
2121
"os/exec"
2222
"path/filepath"
23+
"strings"
2324
"testing"
2425

2526
"github.com/stretchr/testify/assert"
@@ -219,6 +220,58 @@ func TestInstallRefusesToClobberBackup(t *testing.T) {
219220
assert.Equal(t, original, string(content))
220221
}
221222

223+
// TestHookGoldenFiles compares the hook scripts Install writes against the
224+
// committed golden files in testdata/. The temporary hooks directory is
225+
// replaced by a placeholder so the files stay stable. Run with
226+
// UPDATE_GOLDEN=1 to regenerate them after an intentional change:
227+
//
228+
// UPDATE_GOLDEN=1 go test ./app/cli/internal/trace/hooks/ -run TestHookGoldenFiles
229+
func TestHookGoldenFiles(t *testing.T) {
230+
const hooksDirPlaceholder = "<hooks-dir>"
231+
232+
testCases := []struct {
233+
hook string
234+
foreignHook bool
235+
golden string
236+
}{
237+
{hook: "commit-msg", golden: "testdata/commit-msg.sh"},
238+
{hook: "post-commit", golden: "testdata/post-commit.sh"},
239+
{hook: "post-rewrite", golden: "testdata/post-rewrite.sh"},
240+
{hook: "pre-push", golden: "testdata/pre-push.sh"},
241+
{hook: "pre-push", foreignHook: true, golden: "testdata/pre-push-chained.sh"},
242+
{hook: "post-commit", foreignHook: true, golden: "testdata/post-commit-chained.sh"},
243+
}
244+
245+
for _, tc := range testCases {
246+
t.Run(filepath.Base(tc.golden), func(t *testing.T) {
247+
gitDir := t.TempDir()
248+
hooksDir := filepath.Join(gitDir, "hooks")
249+
require.NoError(t, os.MkdirAll(hooksDir, 0755))
250+
if tc.foreignHook {
251+
require.NoError(t, os.WriteFile(filepath.Join(hooksDir, tc.hook), []byte("#!/bin/sh\n"), 0600))
252+
}
253+
254+
_, err := Install(gitDir, false)
255+
require.NoError(t, err)
256+
257+
content, err := os.ReadFile(filepath.Join(hooksDir, tc.hook))
258+
require.NoError(t, err)
259+
generated := strings.ReplaceAll(string(content), hooksDir, hooksDirPlaceholder)
260+
261+
if os.Getenv("UPDATE_GOLDEN") == "1" {
262+
//nolint:gosec // golden paths are fixed testdata paths from the table above
263+
require.NoError(t, os.WriteFile(tc.golden, []byte(generated), 0600))
264+
return
265+
}
266+
267+
expected, err := os.ReadFile(tc.golden)
268+
require.NoError(t, err, "golden file missing; run UPDATE_GOLDEN=1 to generate")
269+
assert.Equal(t, string(expected), generated,
270+
"generated hook does not match golden file %s; run UPDATE_GOLDEN=1 to update", tc.golden)
271+
})
272+
}
273+
}
274+
222275
// TestHookScriptsExitStatus runs each generated hook against a fake chainloop
223276
// binary, or none at all (as in GUI git clients). Only pre-push propagates a
224277
// chainloop failure, so requireTrace can block the push; every other hook must
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git commit-msg "$@"
5+
fi
6+
exit 0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git post-commit
5+
fi
6+
[ -x "<hooks-dir>/post-commit.chainloop-backup" ] && exec "<hooks-dir>/post-commit.chainloop-backup" "$@"
7+
exit 0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git post-commit
5+
fi
6+
exit 0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git post-rewrite
5+
fi
6+
exit 0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git pre-push || exit $?
5+
fi
6+
[ -x "<hooks-dir>/pre-push.chainloop-backup" ] && exec "<hooks-dir>/pre-push.chainloop-backup" "$@"
7+
exit 0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
# chainloop-trace-managed
3+
if command -v chainloop >/dev/null 2>&1; then
4+
chainloop trace hook git pre-push || exit $?
5+
fi
6+
exit 0

0 commit comments

Comments
 (0)