#!/bin/sh # Checks the post-receive hooks under custom/hooks. The cache hook runs from a # copy pointed at a cache and a scan path in the trash directory, since the # shipped one names the system's own, and the hooks run inside bare # repositories the way git runs them after a push. test_description='Check the shipped post-receive hooks' CGIT_TEST_NO_CREATE_REPOS=YesPlease . ./setup.sh HOOK_DIRECTORY="$TEST_OUTPUT_DIRECTORY/../custom/hooks" # A cache that cgit itself filled, for two scanned repositories and the # index, so the hook reads the keys cgit really writes. test_expect_success 'set up a cache of two repositories and the index' ' test_create_repo pusher && test_commit -C pusher cached && mkdir scan slots && git init -q --bare scan/a.git && git init -q --bare scan/b.git && git -C pusher push -q ../scan/a.git HEAD:refs/heads/main && git -C pusher push -q ../scan/b.git HEAD:refs/heads/main && { echo "cache-root=$PWD/slots" && echo "cache-size=1000" && echo "virtual-root=/" && echo "scan-path=$PWD/scan" } >cachedrc && for page in / /a.git/ /a.git/log/ /b.git/ /b.git/log/ do CGIT_CONFIG="$PWD/cachedrc" PATH_INFO="$page" QUERY_STRING= cgit >/dev/null || return 1 done && CGIT_CONFIG="$PWD/cachedrc" QUERY_STRING="url=a.git/refs/" cgit >/dev/null && CGIT_CONFIG="$PWD/cachedrc" QUERY_STRING="url=b.git/refs/" cgit >/dev/null && echo writer >slots/0123abcd.lock && cp -R slots pristine && sed -e "s|^cache_root=.*|cache_root='\''$PWD/slots'\''|" \ -e "s|^scan_path=.*|scan_path='\''$PWD/scan'\''|" \ "$HOOK_DIRECTORY/post-receive.cgit-cache" >cache-hook ' # The request each slot answers, read off its head the way the hook reads it. cached_requests() { for slot in slots/* do dd if="$slot" bs=4096 count=1 2>/dev/null | tr "\0" "\n" | sed -n 1p done } # The hooks are POSIX sh, so each runs under every such shell that is here. shells= for shell in sh dash ksh bash do command -v $shell >/dev/null && shells="$shells $shell" done for shell in $shells do test_expect_success "a push drops its own pages and the index under $shell" " rm -rf slots && cp -R pristine slots && (cd scan/a.git && $shell ../../cache-hook) && cached_requests >left && grep '|/b.git/log/' left && grep 'url=b.git/refs/' left && ! grep 'a.git' left && ! grep '1|/0|' left && test_path_is_file slots/0123abcd.lock && ! ls slots | grep '^rc-' " done test_expect_success 'a repository named in cgitrc gives the hook its url' ' rm -rf slots && cp -R pristine slots && git -C scan/b.git config hooks.cgiturl b.git && sed "s|^scan_path=.*|scan_path=/nonexistent|" cache-hook >named-hook && (cd scan/b.git && sh ../../named-hook) && cached_requests >left && grep "|/a.git/log/" left && ! grep "b.git" left ' test_expect_success 'with no url to go on the whole cache goes' ' rm -rf slots && cp -R pristine slots && (cd scan/a.git && sh ../../named-hook) && test "$(ls slots)" = 0123abcd.lock ' test_expect_success SANITY 'the cache hook shows a pusher no error' ' rm -rf slots && cp -R pristine slots && test_when_finished "chmod 755 slots" && chmod 555 slots && (cd scan/a.git && sh ../../cache-hook 2>../../err) && cached_requests | grep "a.git" && test_must_be_empty err ' test_expect_success 'the age hook writes the newest branch date' ' test_create_repo work && test_commit -C work first && git init -q --bare plain.git && git -C work push -q ../plain.git HEAD:refs/heads/main && (cd plain.git && sh "$HOOK_DIRECTORY/post-receive.cgit-age") && git -C plain.git for-each-ref --format="%(committerdate:iso8601)" refs/heads/main >expect && test_cmp expect plain.git/info/web/last-modified ' for shell in $shells do test_expect_success "the age hook writes the same date under $shell" " rm -f plain.git/info/web/last-modified && (cd plain.git && $shell \"\$HOOK_DIRECTORY/post-receive.cgit-age\") && test_cmp expect plain.git/info/web/last-modified " done # git keeps a shared repository group writable whatever the pusher's umask, # and the next member to push has to be able to replace the file. test_expect_success SANITY 'the age hook keeps a shared directory group writable' ' git init -q --bare --shared=group shared.git && git -C work push -q ../shared.git HEAD:refs/heads/main && (cd shared.git && umask 022 && sh "$HOOK_DIRECTORY/post-receive.cgit-age") && ls -ld shared.git/info/web >mode && grep "^drwxrw[xs]" mode ' test_expect_success 'the commit-graph hook writes a graph with path filters' ' git init -q --bare graph.git && git -C work push -q ../graph.git HEAD:refs/heads/main && (cd graph.git && sh "$HOOK_DIRECTORY/post-receive.commit-graph" 2>../graph-err) && test_must_be_empty graph-err && test_path_is_file graph.git/objects/info/commit-graphs/commit-graph-chain && grep -q BDAT graph.git/objects/info/commit-graphs/*.graph && git -C graph.git commit-graph verify ' for shell in $shells do test_expect_success "a later push moves the graph on under $shell" " cat graph.git/objects/info/commit-graphs/commit-graph-chain >chain-$shell && test_commit -C work graph-$shell && git -C work push -q ../graph.git HEAD:refs/heads/main && (cd graph.git && $shell \"\$HOOK_DIRECTORY/post-receive.commit-graph\") && ! test_cmp chain-$shell graph.git/objects/info/commit-graphs/commit-graph-chain && git -C graph.git commit-graph verify " done test_done