ci/woodpecker/pr/ci Pipeline was successful
Round-two remediation of the four blockers gate-ultron-01 raised onf8d04d1b. All four were confirmed by my own measurement before being touched; none is taken on the reviewer's word. 1. The --config/-K refusal never ran. It sat nested inside `if API_SHAPED`, and API_SHAPED is a test for a provider URL in the command text — which is exactly what a config file removes. The check was guarded by the condition that the capability it guards against defeats, so `curl --config /tmp/write.cfg` walked past it. It now keys on curl itself, ahead of the URL gate, and covers the attached (`-K/tmp/f`) and bundled (`-sK`) spellings a space-separated test cannot see. 2. Percent-encoded endpoints are a live route, not a theoretical one. Measured against the provider: `…/issues/1174` and `…/iss%75es/1174` both return HTTP 200 for the same object. A write carrying any percent-escape is now refused rather than decoded — a decoder has to be exactly right about depth (%2569 -> %69 -> i) and about the provider's own normalisation, and being approximately right there is indistinguishable from not checking. Scoped to writes: a read is never this hook's business and a query string carrying %20 is an ordinary URL. 3. HOME was still expanded unguarded at the `W=` fallback, which runs before any of the new HOME adjudication — so a guard deployed without its siblings still died on an unset HOME, upstream of the fix that was supposed to survive it. Moving a fail-open earlier in the file is not closing it. HOME is now resolved once, above every use, and every later site reads the resolved value. The existing harness could not have caught this: it runs the guard beside its siblings, so `[ -x "$W/pr-review.sh" ]` always succeeded and the fallback was never reached. A test's blind spot can be a property of the harness rather than of the code. The new lone_case() block copies the guard alone into an empty directory and re-asserts the four behaviours there. 4. test-mosaic-worktree-large-repo.sh shipped at mode 100644 and appeared in no CI step, so the enumeration guard (#1017) redded pipeline 2386 — correctly. Committed mode is now 100755 and the test is enumerated in the sanitization step. My own process miss: I verified the CI queue before pushing and never verified terminal CI after. Controls: the 25 fixtures added here all FAIL against029af418(rc 0 or 1 where 2 is required) and all pass at this head, 143/143.
96 lines
4.1 KiB
Bash
Executable File
96 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# test-mosaic-worktree-large-repo.sh — the helper must work on the repos it exists for.
|
|
#
|
|
# resolve_repo() took the first line of `git worktree list --porcelain` with
|
|
# `awk '/^worktree /{print substr($0,10); exit}'`. The `exit` closes the read end
|
|
# of the pipe while git is still writing, git takes SIGPIPE, and under
|
|
# `set -euo pipefail` the command substitution returns 141 — so the assignment
|
|
# fails, `set -e` aborts the function, and the script dies printing NOTHING. No
|
|
# message, no path, no worktree, exit 141.
|
|
#
|
|
# What makes it worth a dedicated test rather than a fixture line is WHEN it
|
|
# fires. If git finishes writing before awk leaves, there is no SIGPIPE and
|
|
# everything works. So the failure is a function of how much porcelain the repo
|
|
# produces: invisible on a three-worktree repo, reliable on a seventy-worktree
|
|
# one. It was measured on a repo with 73 worktrees (10 KB of porcelain) — rc=141,
|
|
# no output — and it had passed every hand-check before that, on small repos.
|
|
#
|
|
# A test that ran `git worktree list` against whatever repo it happens to sit in
|
|
# would inherit that same size dependence and would have PASSED on the tree that
|
|
# was broken. So git is stubbed on PATH and made to emit a large porcelain
|
|
# stream, which turns "depends on the repo you are standing in" into "always".
|
|
#
|
|
# Exit: 0 = the helper resolved the repo · 1 = it did not
|
|
|
|
set -uo pipefail
|
|
|
|
HERE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
TOOL="${1:-$HERE/mosaic-worktree.sh}"
|
|
[ -x "$TOOL" ] || { printf 'test-mosaic-worktree-large-repo: not executable: %s\n' "$TOOL" >&2; exit 2; }
|
|
|
|
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
|
|
mkdir -p "$TMP/bin"
|
|
|
|
# The stub answers exactly the two calls resolve_repo makes, and answers the
|
|
# porcelain one with ~450 KB — comfortably past a 64 KB pipe buffer, so the
|
|
# writer is still writing when a reader that quits early goes away. Anything
|
|
# else exits non-zero rather than pretending to be git.
|
|
cat > "$TMP/bin/git" <<'STUB'
|
|
#!/bin/sh
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in -C) shift 2 ;; *) break ;; esac
|
|
done
|
|
case "$*" in
|
|
"rev-parse --git-dir")
|
|
echo .git; exit 0 ;;
|
|
"worktree list --porcelain")
|
|
# The first entry is the main worktree. That single line is all the helper
|
|
# needs, and it is exactly what it stopped receiving.
|
|
printf 'worktree /src/fakerepo\nHEAD %040d\nbranch refs/heads/main\n\n' 0
|
|
awk 'BEGIN{ for (i = 0; i < 4000; i++)
|
|
printf "worktree /src/fakerepo-worktrees/w%d\nHEAD %040d\nbranch refs/heads/topic-%d\n\n", i, 0, i }'
|
|
# NOT `exit 0`. Real git dies of SIGPIPE here and reports 141, and pipefail
|
|
# in the caller is what turns that into the silent abort. A stub that exits 0
|
|
# regardless hands the caller a clean status and the probe passes on the
|
|
# broken tree — which is how this test failed to be a test on its first run.
|
|
exit $? ;;
|
|
esac
|
|
exit 1
|
|
STUB
|
|
chmod +x "$TMP/bin/git"
|
|
|
|
fail=0
|
|
check() {
|
|
local why="$1" want="$2" got="$3"
|
|
if [ "$want" = "$got" ]; then
|
|
printf 'ok %s\n' "$why"
|
|
else
|
|
printf 'FAIL %s\n want: %s\n got: %s\n' "$why" "$want" "$got"
|
|
fail=1
|
|
fi
|
|
}
|
|
|
|
out="$(PATH="$TMP/bin:$PATH" "$TOOL" path feat/workspace-hygiene 2>&1)"
|
|
rc=$?
|
|
|
|
# Both halves are asserted. rc alone would pass if the helper started printing a
|
|
# usage error, and output alone would miss a non-zero exit — and the defect's
|
|
# signature is precisely a non-zero exit with no output, which only the pair
|
|
# distinguishes from every other way this could go wrong.
|
|
check 'resolving a repo with a large worktree list exits 0' 0 "$rc"
|
|
check 'and derives the path from the main worktree' /src/fakerepo-worktrees/feat-workspace-hygiene "$out"
|
|
|
|
printf '\n'
|
|
if [ "$fail" -eq 0 ]; then
|
|
printf 'mosaic-worktree: resolves against a large porcelain stream.\n'
|
|
else
|
|
cat <<'EOF'
|
|
mosaic-worktree could not resolve the repository.
|
|
|
|
An empty output with a non-zero exit is the SIGPIPE signature: a reader that
|
|
quits early (`awk ... exit`, `head -n`) kills the producer, and pipefail turns
|
|
that into a silent abort. Nothing in this script may close a git pipe early.
|
|
EOF
|
|
fi
|
|
exit "$fail"
|