framework tools/git: strict value guards + provider-failure normalization family-wide (codex blockers on PR #1464)
ci/woodpecker/pr/ci Pipeline is pending

- Value guards now reject option-like values: --anything always, and
  single-dash flag shapes (-h, -i). Previously -b --help consumed
  --help as the body and performed the write (codex example:
  issue-close -i --help proceeding to 'Closed GitHub issue #--help').
  Multi-char dash-leading text (-start of a list) stays a legal value.
- Every remaining direct provider exec (gh/tea/CMD arrays across
  issue-create/edit/assign/list/view, milestone-*, pr-create/edit,
  pr-close, issue-close/reopen) wrapped with rc capture and normalized
  to exit 1 with a stderr message — provider exit 2 no longer collides
  with the reserved usage-error status.
- All 16 usage-contract suites gained option-like and short-flag arms
  (16/16 green). Existing suites re-verified; test-pr-edit and
  test-issue-create-interactive-auth fail identically with these
  changes stashed (environment-coupled, not regressions; documented).
This commit is contained in:
2026-08-28 18:26:10 -05:00
parent ca91586222
commit d326e6572a
32 changed files with 264 additions and 90 deletions
@@ -55,34 +55,34 @@ usage_error() {
while [[ $# -gt 0 ]]; do
case $1 in
-n|--number)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
PR_NUMBER="$2"
shift 2
;;
-a|--action)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
ACTION="$2"
shift 2
;;
-b|--body|-c|--comment)
# R1 (2026-08-28): --body is the canonical flag; -c/--comment stays
# a backward-compatible alias.
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
COMMENT="$2"
shift 2
;;
-l|--login)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
LOGIN_OVERRIDE="$2"
shift 2
;;
-r|--repo)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
REPO_OVERRIDE="$2"
shift 2
;;
-H|--host)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
[[ $# -ge 2 && "$2" != --* && ! "$2" =~ ^-[a-zA-Z]$ ]] || usage_error "option $1 requires a value (option-like values are rejected)"
HOST_OVERRIDE="$2"
shift 2
;;
@@ -711,14 +711,18 @@ PY
if [[ "$PLATFORM" == "github" ]]; then
case $ACTION in
approve)
gh pr review "$PR_NUMBER" --approve ${COMMENT:+--body "$COMMENT"}
gh_rc=0
gh pr review "$PR_NUMBER" --approve ${COMMENT:+--body "$COMMENT"} || gh_rc=$?
[[ "$gh_rc" -eq 0 ]] || { echo "Error: GitHub approve failed (gh exit $gh_rc; provider failure, not a usage error)" >&2; exit 1; }
echo "Approved GitHub PR #$PR_NUMBER"
;;
request-changes)
if [[ -z "$COMMENT" ]]; then
usage_error "comment required for request-changes (-b/--body)"
fi
gh pr review "$PR_NUMBER" --request-changes --body "$COMMENT"
gh_rc=0
gh pr review "$PR_NUMBER" --request-changes --body "$COMMENT" || gh_rc=$?
[[ "$gh_rc" -eq 0 ]] || { echo "Error: GitHub request-changes failed (gh exit $gh_rc; provider failure, not a usage error)" >&2; exit 1; }
echo "Requested changes on GitHub PR #$PR_NUMBER"
;;
comment)
@@ -726,7 +730,9 @@ if [[ "$PLATFORM" == "github" ]]; then
echo "Error: Comment required"
exit 1
fi
gh pr review "$PR_NUMBER" --comment --body "$COMMENT"
gh_rc=0
gh pr review "$PR_NUMBER" --comment --body "$COMMENT" || gh_rc=$?
[[ "$gh_rc" -eq 0 ]] || { echo "Error: GitHub review comment failed (gh exit $gh_rc; provider failure, not a usage error)" >&2; exit 1; }
echo "Added review comment to GitHub PR #$PR_NUMBER"
;;
*)