pr-reviews: hand jq its JSON on stdin, not argv (improvise-5jxt)

On #210 the review and comment JSON outgrew ARG_MAX, and
`jq -n --argjson ...` failed to exec with exit 126 before printing
anything. A `combine` helper now pipes the three documents to `jq -s`
through the printf builtin, on both the fixture path and the live path.

The new suite cases put about 2 MB on each surface, so a fix that moves
only one document off argv still fails. Both rivals fail 5 of 30: the
pre-fix script, and a partial fix that keeps the issue comments on argv.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Edward Langley
2026-09-24 15:22:00 -07:00
parent c1772ca9b4
commit c6b53eaa77
3 changed files with 79 additions and 8 deletions
+12 -8
View File
@@ -87,28 +87,32 @@ fixture_file() {
}
# `gh api --paginate` emits one JSON array PER PAGE, so a comment thread past
# the page size arrives as several concatenated documents that --argjson
# rejects. Both paths flatten through here, so a fixture can carry two pages.
# the page size arrives as several concatenated documents that combine
# would misnumber. Both paths flatten through here, so a fixture can carry two pages.
pages_to_array() { jq -s 'add // []'; }
# The three documents reach jq on STDIN, never as --argjson: a thread past
# ARG_MAX is exit 126 before jq runs (improvise-5jxt). printf is a builtin.
combine() {
printf '%s\n%s\n%s\n' "$1" "$2" "$3" | jq -s \
'{head: (.[0].headRefOid // ""), reviews: (.[0].reviews // []),
inline: .[1], issue: .[2]}'
}
fetch() {
if [ -n "${PR_REVIEWS_FIXTURE_DIR:-}" ]; then
local n; n=$(fixture_poll)
local pr; pr=$(fixture_file "$n" pr)
local inline; inline=$(fixture_file "$n" inline | pages_to_array)
local issue; issue=$(fixture_file "$n" issue | pages_to_array)
jq -n --argjson pr "$pr" --argjson inline "$inline" --argjson issue "$issue" \
'{head: ($pr.headRefOid // ""), reviews: ($pr.reviews // []),
inline: $inline, issue: $issue}'
combine "$pr" "$inline" "$issue"
return
fi
local repo; repo=$(gh_ repo view --json nameWithOwner -q .nameWithOwner)
local pr; pr=$(gh_ pr view "$PR" --json headRefOid,reviews)
local inline; inline=$(gh_ api "repos/$repo/pulls/$PR/comments" --paginate | pages_to_array)
local issue; issue=$(gh_ api "repos/$repo/issues/$PR/comments" --paginate | pages_to_array)
jq -n --argjson pr "$pr" --argjson inline "$inline" --argjson issue "$issue" \
'{head: ($pr.headRefOid // ""), reviews: ($pr.reviews // []),
inline: $inline, issue: $issue}'
combine "$pr" "$inline" "$issue"
}
# `line` is null once the line has moved under the comment; `original_line` is
+26
View File
@@ -291,6 +291,32 @@ prints "a comment on the first page survives pagination" "$d" 'page1\.rs:1'
prints "a comment on the second page survives pagination" "$d" 'page2\.rs:2'
run_case "a paginated thread still satisfies --wait" 0 "$d" --wait 1 --interval 1
# ---------------------------------------------------------------------------
# A thread past ARG_MAX (improvise-5jxt). PR #210's comments outgrew the argv
# limit, and a fetch that hands the JSON to jq as an argument dies with exit
# 126 before printing anything. 2MB per surface clears every platform's limit,
# and EACH surface is large, so a fix that moves only one of them off argv fails.
d="$work/huge"
mkdir -p "$d"
big=$(head -c 2000000 /dev/zero | tr '\0' x)
{ printf '{"headRefOid":"%s","reviews":[{"state":"COMMENTED",' "$HEAD"
printf '"submittedAt":"2026-09-22T09:00:00Z","author":{"login":"owner"},'
printf '"commit":{"oid":"%s"},"body":"BIGREVIEW %s"}]}\n' "$OLD" "$big"
} > "$d/last.pr.json"
{ printf '[{"created_at":"2026-09-22T10:00:00Z","user":{"login":"owner"},"commit_id":"%s",' "$HEAD"
printf '"path":"big.rs","line":1,"body":"%s"},\n' "$big"
printf '{"created_at":"2026-09-22T10:00:01Z","user":{"login":"owner"},"commit_id":"%s",' "$HEAD"
printf '"path":"after.rs","line":9,"body":"AFTERTHEBIGONE"}]\n'
} > "$d/last.inline.json"
printf '[{"created_at":"2026-09-22T11:00:00Z","user":{"login":"owner"},"body":"BIGISSUE %s"}]\n' \
"$big" > "$d/last.issue.json"
unset big
run_case "a thread larger than ARG_MAX is still read" 0 "$d"
prints "a comment after a multi-MB one is printed" "$d" 'after\.rs:9 commit=aaaaaaaa <- CURRENT HEAD'
prints "a multi-MB review body is printed" "$d" 'BIGREVIEW x'
prints "a multi-MB issue comment is printed" "$d" 'BIGISSUE x'
run_case "a thread larger than ARG_MAX still satisfies --wait" 0 "$d" --wait 1 --interval 1
# ---------------------------------------------------------------------------
# Usage is exit 4 and must stay there: briefs distinguish it from 1.
rm -f "$work/empty/.poll"