framework tools/git: pr-edit R1/R4 conversion (P1)

usage() default exit 2; semantic invocation checks (mutual exclusion,
integer/format validation, missing edit option, --login-only-for-Gitea)
exit 2; value guards on all value-taking options; existing pr-edit
suite still green; usage-contract suite enrolled (population 80);
mirrored to the brain tree.
This commit is contained in:
2026-08-28 18:03:29 -05:00
parent c43b1a1293
commit b8b396d9f5
3 changed files with 156 additions and 16 deletions
+22 -15
View File
@@ -50,38 +50,45 @@ Options:
-H, --host HOST Explicit Gitea host (required with --repo off-host)
-h, --help Show this help message
EOF
exit "${1:-1}"
exit "${1:-2}"
}
# Usage-error contract (R4, 2026-08-28): usage errors print to STDERR and exit 2,
# distinct from provider, credential, and verification failures (exit 1).
usage_error() {
echo "Error: $*" >&2
usage
}
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--number) PR_NUMBER="${2:-}"; shift 2 ;;
-t|--title) TITLE="${2:-}"; shift 2 ;;
-b|--body) BODY="${2:-}"; shift 2 ;;
-B|--base) BASE_BRANCH="${2:-}"; shift 2 ;;
-n|--number) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; PR_NUMBER="${2:-}"; shift 2 ;;
-t|--title) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; TITLE="${2:-}"; shift 2 ;;
-b|--body) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; BODY="${2:-}"; shift 2 ;;
-B|--base) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; BASE_BRANCH="${2:-}"; shift 2 ;;
--draft)
[[ "$DRAFT_MODE" != "ready" ]] || { echo "Error: --draft and --ready are mutually exclusive" >&2; exit 1; }
[[ "$DRAFT_MODE" != "ready" ]] || { echo "Error: --draft and --ready are mutually exclusive" >&2; exit 2; }
DRAFT_MODE="draft"; shift ;;
--ready)
[[ "$DRAFT_MODE" != "draft" ]] || { echo "Error: --draft and --ready are mutually exclusive" >&2; exit 1; }
[[ "$DRAFT_MODE" != "draft" ]] || { echo "Error: --draft and --ready are mutually exclusive" >&2; exit 2; }
DRAFT_MODE="ready"; shift ;;
-l|--login) LOGIN_OVERRIDE="${2:-}"; shift 2 ;;
-r|--repo) REPO_OVERRIDE="${2:-}"; shift 2 ;;
-H|--host) HOST_OVERRIDE="${2:-}"; shift 2 ;;
-l|--login) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; LOGIN_OVERRIDE="${2:-}"; shift 2 ;;
-r|--repo) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; REPO_OVERRIDE="${2:-}"; shift 2 ;;
-H|--host) [[ $# -ge 2 ]] || usage_error "option $1 requires a value"; HOST_OVERRIDE="${2:-}"; shift 2 ;;
-h|--help) usage 0 ;;
*) echo "Unknown option: $1" >&2; usage ;;
esac
done
[[ -n "$PR_NUMBER" ]] || { echo "Error: Pull request number is required (-n)" >&2; exit 1; }
[[ "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]] || { echo "Error: Pull request number must be a positive integer" >&2; exit 1; }
[[ -n "$PR_NUMBER" ]] || { echo "Error: Pull request number is required (-n)" >&2; exit 2; }
[[ "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]] || { echo "Error: Pull request number must be a positive integer" >&2; exit 2; }
if [[ -z "$TITLE" && -z "$BODY" && -z "$BASE_BRANCH" && -z "$DRAFT_MODE" ]]; then
echo "Error: At least one edit option is required" >&2
exit 1
exit 2
fi
[[ -z "$REPO_OVERRIDE" || "$REPO_OVERRIDE" =~ ^[^/[:space:]]+/[^/[:space:]]+$ ]] || {
echo "Error: --repo must be OWNER/REPO" >&2
exit 1
exit 2
}
if [[ -n "$HOST_OVERRIDE" || -n "$REPO_OVERRIDE" ]]; then
@@ -92,7 +99,7 @@ fi
case "$PLATFORM" in
github)
[[ -z "$LOGIN_OVERRIDE" ]] || { echo "Error: --login is only valid for Gitea" >&2; exit 1; }
[[ -z "$LOGIN_OVERRIDE" ]] || { echo "Error: --login is only valid for Gitea" >&2; exit 2; }
if [[ -n "$TITLE" || -n "$BODY" || -n "$BASE_BRANCH" ]]; then
CMD=(gh pr edit "$PR_NUMBER")
[[ -n "$TITLE" ]] && CMD+=(--title "$TITLE")