mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
184 lines
5.8 KiB
Bash
Executable File
184 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Shared helpers for scripts/shortcuts/review/*.sh
|
|
# Source this file; do not execute directly.
|
|
|
|
set -euo pipefail
|
|
|
|
# Repo that hosts the PR. Override with REVIEW_REPO=owner/name if needed;
|
|
# otherwise we derive it from the `upstream` remote, falling back to `origin`.
|
|
resolve_repo() {
|
|
if [ -n "${REVIEW_REPO:-}" ]; then
|
|
echo "$REVIEW_REPO"
|
|
return
|
|
fi
|
|
local url
|
|
url=$(git remote get-url upstream 2>/dev/null || git remote get-url origin)
|
|
# Accept git@github.com:owner/name(.git) and https://github.com/owner/name(.git)
|
|
echo "$url" \
|
|
| sed -E 's#^git@github\.com:##; s#^https?://github\.com/##; s#\.git$##'
|
|
}
|
|
|
|
require() {
|
|
local bin
|
|
for bin in "$@"; do
|
|
command -v "$bin" >/dev/null 2>&1 || {
|
|
echo "[review] missing required tool: $bin" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
}
|
|
|
|
gh_assign_self_issue() {
|
|
local issue="$1"
|
|
local repo="$2"
|
|
if gh issue edit "$issue" -R "$repo" --add-assignee "@me" >/dev/null 2>&1; then
|
|
info "assigned issue #$issue to @me"
|
|
else
|
|
warn "could not assign issue #$issue to @me; continuing"
|
|
fi
|
|
}
|
|
|
|
gh_assign_self_pr() {
|
|
local pr="$1"
|
|
local repo="$2"
|
|
if gh pr edit "$pr" -R "$repo" --add-assignee "@me" >/dev/null 2>&1; then
|
|
info "assigned PR #$pr to @me"
|
|
else
|
|
warn "could not assign PR #$pr to @me; continuing"
|
|
fi
|
|
}
|
|
|
|
# Summarize free-form text via a local LLM CLI (expects `-p <prompt>`).
|
|
# Usage: summarize_text <tool> <input>
|
|
# Tools used here: gemini (default for summaries), claude, or any CLI that
|
|
# accepts `-p "<prompt>"` and prints the response to stdout.
|
|
# Special value `none` echoes input unchanged.
|
|
summarize_text() {
|
|
local tool="$1"
|
|
local input="$2"
|
|
if [ "$tool" = "none" ] || [ "$tool" = "raw" ]; then
|
|
printf '%s' "$input"
|
|
return
|
|
fi
|
|
require "$tool"
|
|
local prompt
|
|
prompt=$(cat <<'EOF'
|
|
You are writing the body of a squash-merge commit.
|
|
Summarize the PR changes below into 3-6 short bullet points.
|
|
Rules:
|
|
- Start each bullet with "- " and use imperative mood ("Add…", "Fix…", "Rename…").
|
|
- One line per bullet, under ~100 chars.
|
|
- No headers, no code fences, no sign-offs, no Co-authored-by lines.
|
|
- Do not include the PR number or title.
|
|
- Output only the bullets, nothing else.
|
|
|
|
PR content:
|
|
---
|
|
EOF
|
|
)
|
|
"$tool" -p "${prompt}
|
|
${input}
|
|
---"
|
|
}
|
|
|
|
require_pr_number() {
|
|
if [ -z "${1:-}" ]; then
|
|
echo "Usage: $(basename "$0") <pr-number>" >&2
|
|
exit 1
|
|
fi
|
|
case "$1" in
|
|
''|*[!0-9]*)
|
|
echo "[review] pr-number must be numeric, got: $1" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ── Coloured output ────────────────────────────────────────────────
|
|
# Disable colour when stdout is not a terminal (piped / CI).
|
|
if [ -t 1 ]; then
|
|
_R=$'\033[0;31m' _G=$'\033[0;32m' _Y=$'\033[0;33m' _B=$'\033[1m' _0=$'\033[0m'
|
|
else
|
|
_R="" _G="" _Y="" _B="" _0=""
|
|
fi
|
|
|
|
pass() { printf '%s[PASS]%s %s\n' "$_G" "$_0" "$*"; }
|
|
fail() { printf '%s[FAIL]%s %s\n' "$_R" "$_0" "$*" >&2; }
|
|
warn() { printf '%s[WARN]%s %s\n' "$_Y" "$_0" "$*" >&2; }
|
|
info() { printf '%s[INFO]%s %s\n' "$_B" "$_0" "$*"; }
|
|
|
|
# Fetch PR head into local branch pr/<num>, merge main in, wire upstream +
|
|
# pushRemote so `git push` lands on the contributor's fork.
|
|
sync_pr() {
|
|
local pr="$1"
|
|
local repo
|
|
repo=$(resolve_repo)
|
|
|
|
echo "[review] syncing main from upstream..."
|
|
git checkout main
|
|
git pull origin main
|
|
git fetch upstream
|
|
git merge upstream/main
|
|
git submodule update --init --recursive
|
|
|
|
local info head_repo head_branch local_branch
|
|
info=$(gh pr view "$pr" -R "$repo" \
|
|
--json headRefName,headRepository,headRepositoryOwner)
|
|
head_repo=$(echo "$info" | jq -r '.headRepositoryOwner.login + "/" + .headRepository.name')
|
|
head_branch=$(echo "$info" | jq -r '.headRefName')
|
|
local_branch="pr/$pr"
|
|
|
|
echo "[review] PR #$pr -> $head_repo:$head_branch (local: $local_branch)"
|
|
|
|
git fetch "https://github.com/${head_repo}.git" \
|
|
"+${head_branch}:${local_branch}"
|
|
git checkout "$local_branch"
|
|
|
|
echo "[review] merging main into $local_branch (conflicts will not abort)..."
|
|
REVIEW_HAS_CONFLICTS=0
|
|
REVIEW_CONFLICT_FILES=""
|
|
if ! git merge --no-edit main; then
|
|
REVIEW_CONFLICT_FILES=$(git diff --name-only --diff-filter=U | sort -u)
|
|
if [ -z "$REVIEW_CONFLICT_FILES" ]; then
|
|
fail "git merge main failed for a non-conflict reason"
|
|
return 1
|
|
fi
|
|
echo "[review] ! conflicts detected in PR #$pr, continuing."
|
|
REVIEW_HAS_CONFLICTS=1
|
|
fi
|
|
|
|
# Prefer an existing SSH remote pointing at this fork to avoid https auth prompts.
|
|
local remote_name="remote-$pr"
|
|
local existing_ssh
|
|
existing_ssh=$(git remote -v \
|
|
| awk -v repo="$head_repo" '$2 ~ ("[:/]" repo "(\\.git)?$") && $3 == "(fetch)" {print $1; exit}')
|
|
if [ -n "$existing_ssh" ]; then
|
|
remote_name="$existing_ssh"
|
|
echo "[review] reusing remote '$remote_name' -> $(git remote get-url "$remote_name")"
|
|
else
|
|
local remote_url="https://github.com/${head_repo}.git"
|
|
git remote add "$remote_name" "$remote_url" 2>/dev/null \
|
|
|| git remote set-url "$remote_name" "$remote_url"
|
|
fi
|
|
|
|
git fetch "$remote_name" \
|
|
"+refs/heads/${head_branch}:refs/remotes/${remote_name}/${head_branch}"
|
|
|
|
git branch --set-upstream-to="$remote_name/$head_branch" "$local_branch"
|
|
git config "branch.${local_branch}.pushRemote" "$remote_name"
|
|
git config "branch.${local_branch}.merge" "refs/heads/${head_branch}"
|
|
|
|
echo "[review] upstream + pushRemote set to $remote_name/$head_branch"
|
|
|
|
# Export for callers.
|
|
REVIEW_PR="$pr"
|
|
REVIEW_REPO_RESOLVED="$repo"
|
|
REVIEW_LOCAL_BRANCH="$local_branch"
|
|
REVIEW_HEAD_REPO="$head_repo"
|
|
REVIEW_HEAD_BRANCH="$head_branch"
|
|
REVIEW_PUSH_REMOTE="$remote_name"
|
|
export REVIEW_PR REVIEW_REPO_RESOLVED REVIEW_LOCAL_BRANCH \
|
|
REVIEW_HEAD_REPO REVIEW_HEAD_BRANCH REVIEW_PUSH_REMOTE \
|
|
REVIEW_HAS_CONFLICTS REVIEW_CONFLICT_FILES
|
|
}
|