Repository navigation
Check the repo gh pr create runs in, in the pre-PR hook #1531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
424e5d9
f220dcd
a6f61ea
a137690
58a0d0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,21 +13,52 @@ if [[ "$COMMAND" != *"gh pr create"* ]]; then | |
| exit 0 | ||
| fi | ||
|
|
||
| # Determine base branch (default: main) | ||
| BASE="main" | ||
| if echo "$COMMAND" | grep -qoP '(?<=--base\s)\S+'; then | ||
| BASE=$(echo "$COMMAND" | grep -oP '(?<=--base\s)\S+') | ||
| # Parse the command as one line, with backslash continuations joined. Quoted strings (the --title and --body | ||
| # values, including a heredoc inside "$(...)") and a bare heredoc are dropped before reading flags, so text inside | ||
| # them cannot match. --base/--head values are unquoted first so they survive. | ||
| ONE_LINE=$(printf '%s\n' "$COMMAND" | sed -e ':a' -e '/\\$/N' -e 's/\\\n//' -e 'ta' | tr '\n' ' ') | ||
| FLAGS=$(printf '%s\n' "$ONE_LINE" | sed -E "s/((--base|-B|--head|-H)[[:space:]=]+)\"([^\"]*)\"/\1\3/g; s/((--base|-B|--head|-H)[[:space:]=]+)'([^']*)'/\1\3/g; s/\"[^\"]*\"//g; s/'[^']*'//g; s/<<.*//") | ||
|
|
||
| # Only a command that runs gh pr create, not one that mentions it (a commit message, a grep) | ||
| RUNS_PR_CREATE='(^|[;&|(])[[:space:]]*gh[[:space:]]+pr[[:space:]]+create' | ||
| if ! [[ "$FLAGS" =~ $RUNS_PR_CREATE ]]; then | ||
| exit 0 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Create-command regex misses valid invocationsMedium Severity
Additional Locations (1)Reviewed by Cursor Bugbot for commit a137690. Configure here. |
||
| fi | ||
|
|
||
| # Check the repo the command runs in: the target of the last `cd` before gh pr create, else the session's cwd. | ||
| # A relative target is resolved against the session's cwd. | ||
| CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null) | ||
| BEFORE="; ${ONE_LINE%%gh pr create*}" | ||
| REPO_DIR=$(printf '%s\n' "$BEFORE" | sed -nE "s/.*[;&|][[:space:]]*cd[[:space:]]+(\"([^\"]+)\"|'([^']+)'|([^;&|[:space:]]+)).*/\2\3\4/p") | ||
| REPO_DIR="${REPO_DIR/#\~/$HOME}" | ||
|
cursor[bot] marked this conversation as resolved.
Resolved
|
||
| if [[ -n "$REPO_DIR" && "$REPO_DIR" != /* && -n "$CWD" ]]; then | ||
| REPO_DIR="$CWD/$REPO_DIR" | ||
| fi | ||
| REPO_DIR="${REPO_DIR:-${CWD:-.}}" | ||
|
|
||
| # Determine base branch (default: main) and the PR's head branch (default: the checked-out one). gh uses the last | ||
| # value of a repeated flag, and --head may be owner:branch. grep -oE rather than grep -P, which macOS grep lacks. | ||
| BASE=$(printf '%s\n' "$FLAGS" | grep -oE -- '(^|[[:space:]])(--base|-B)[[:space:]=]+[^[:space:];&|)]+' | tail -n1 | sed -E 's/^[[:space:]]*(--base|-B)[[:space:]=]+//') | ||
| BASE="${BASE:-main}" | ||
| HEAD_BRANCH=$(printf '%s\n' "$FLAGS" | grep -oE -- '(^|[[:space:]])(--head|-H)[[:space:]=]+[^[:space:];&|)]+' | tail -n1 | sed -E 's/^[[:space:]]*(--head|-H)[[:space:]=]+//') | ||
| HEAD_BRANCH="${HEAD_BRANCH#*:}" | ||
| HEAD_BRANCH="${HEAD_BRANCH:-$(git -C "$REPO_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null)}" | ||
|
|
||
| # A value that looks like an option would be passed to git as one, so skip the check instead | ||
| if [[ "$BASE" == -* || "$HEAD_BRANCH" == -* ]]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Fetch latest base and check freshness | ||
| git fetch origin "$BASE" --quiet 2>/dev/null || true | ||
| BEHIND=$(git rev-list --count HEAD.."origin/$BASE" 2>/dev/null || echo "?") | ||
| git -C "$REPO_DIR" fetch origin "$BASE" --quiet 2>/dev/null || true | ||
| BEHIND=$(git -C "$REPO_DIR" rev-list --count "$HEAD_BRANCH".."origin/$BASE" 2>/dev/null || echo "?") | ||
|
|
||
| if [[ "$BEHIND" != "0" && "$BEHIND" != "?" ]]; then | ||
| cat >&2 << EOF | ||
|
|
||
| =================================================================== | ||
| PR BLOCKED: Branch is $BEHIND commit(s) behind $BASE | ||
| PR BLOCKED: Branch $HEAD_BRANCH is $BEHIND commit(s) behind $BASE | ||
| (checked in $REPO_DIR) | ||
| =================================================================== | ||
|
|
||
| Your PR will show "out of date with base branch" on GitHub. | ||
|
|
@@ -45,13 +76,12 @@ EOF | |
| exit 2 | ||
| fi | ||
|
|
||
| # Check we're not on main/master | ||
| BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) | ||
| if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then | ||
| # Check we're not opening a PR from main/master | ||
| if [[ "$HEAD_BRANCH" == "main" || "$HEAD_BRANCH" == "master" ]]; then | ||
| cat >&2 << EOF | ||
|
|
||
| =================================================================== | ||
| PR BLOCKED: Cannot create PR from $BRANCH | ||
| PR BLOCKED: Cannot create PR from $HEAD_BRANCH | ||
| =================================================================== | ||
|
|
||
| Create a feature branch first: | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heredoc erases later create command
Medium Severity
Flattening the full command and then cutting
FLAGSat<<also deletes a latergh pr create.RUNS_PR_CREATEthen fails and the hook exits 0, so a heredoc-then-create sequence never gets a freshness check.Reviewed by Cursor Bugbot for commit a137690. Configure here.