142 lines
4.3 KiB
Bash
Executable File
142 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# wm-review: Review completed task, approve or reject.
|
|
#
|
|
# Usage:
|
|
# wm-review <task-id> # review a specific task
|
|
# wm-review --pending # list tasks with branches ready for review
|
|
#
|
|
# Actions (interactive):
|
|
# a/approve - commit on branch, mark task done
|
|
# r/reject - reset branch, discard changes
|
|
# d/diff - show full diff again
|
|
# l/log - show agent log
|
|
# s/skip - leave for later
|
|
# e/edit - open changed files in $EDITOR
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
TOOLS="$ROOT/tools/wm-port"
|
|
DONE_FILE="$TOOLS/done.txt"
|
|
LOG_DIR="$TOOLS/logs"
|
|
|
|
source "$TOOLS/task-map.sh"
|
|
touch "$DONE_FILE"
|
|
|
|
die() { printf 'wm-review: %s\n' "$*" >&2; exit 1; }
|
|
|
|
# List pending reviews
|
|
if [ "${1:-}" = "--pending" ]; then
|
|
cd "$ROOT"
|
|
found=0
|
|
for branch in $(git branch --list 'port/*' --format='%(refname:short)' 2>/dev/null); do
|
|
tid="${branch#port/}"
|
|
if ! task_is_done "$tid" "$DONE_FILE" 2>/dev/null; then
|
|
# Count changes
|
|
changes=$(git diff main..."$branch" --stat 2>/dev/null | tail -1)
|
|
printf ' %-10s %s\n' "$tid" "$changes"
|
|
found=1
|
|
fi
|
|
done
|
|
[ "$found" -eq 0 ] && echo "No branches pending review."
|
|
exit 0
|
|
fi
|
|
|
|
[ $# -lt 1 ] && die "usage: wm-review <task-id> | --pending"
|
|
|
|
tid="$1"
|
|
[ -n "${TASK_TEMPLATE[$tid]:-}" ] || die "unknown task ID: $tid"
|
|
|
|
cd "$ROOT"
|
|
branch="port/$tid"
|
|
|
|
# Check branch exists
|
|
git rev-parse --verify "$branch" &>/dev/null || die "branch '$branch' does not exist"
|
|
|
|
# Show summary
|
|
printf '\033[1m=== Review: Task %s ===\033[0m\n' "$tid"
|
|
printf 'Template: %s (%s)\n' "${TASK_TEMPLATE[$tid]}" "${TEMPLATE_NAME[${TASK_TEMPLATE[$tid]}]}"
|
|
printf 'Branch: %s\n\n' "$branch"
|
|
|
|
# Determine base branch
|
|
base="HEAD"
|
|
if git rev-parse --verify main &>/dev/null; then
|
|
base="main"
|
|
elif git rev-parse --verify master &>/dev/null; then
|
|
base="master"
|
|
fi
|
|
|
|
# Show diff stat
|
|
printf '\033[1;4mChanges:\033[0m\n'
|
|
git diff "$base"..."$branch" --stat
|
|
echo
|
|
|
|
# Show the actual diff
|
|
printf '\033[1;4mDiff:\033[0m\n'
|
|
git diff "$base"..."$branch" --color=always | head -200
|
|
echo
|
|
|
|
if [ -f "$LOG_DIR/${tid}.log" ]; then
|
|
# Show agent's final status from log
|
|
printf '\033[1;4mAgent status:\033[0m\n'
|
|
grep -E '^(DONE|STOP|FAIL|\*\*DONE|\*\*STOP|\*\*FAIL|Status:)' "$LOG_DIR/${tid}.log" | tail -5
|
|
echo
|
|
fi
|
|
|
|
# Interactive review loop
|
|
while true; do
|
|
printf '\033[1;36m[a]pprove [r]eject [d]iff [l]og [e]dit [s]kip > \033[0m'
|
|
read -r action < /dev/tty
|
|
|
|
case "$action" in
|
|
a|approve)
|
|
# Merge branch into current
|
|
current=$(git branch --show-current)
|
|
git merge --no-ff -m "port($tid): ${TEMPLATE_NAME[${TASK_TEMPLATE[$tid]}]}" "$branch" || {
|
|
echo "Merge conflict. Resolve manually, then run: echo '$tid' >> $DONE_FILE"
|
|
exit 1
|
|
}
|
|
echo "$tid" >> "$DONE_FILE"
|
|
printf '\033[1;32m✓ Task %s approved and merged.\033[0m\n' "$tid"
|
|
|
|
# Optionally delete the branch
|
|
printf 'Delete branch %s? [y/N] ' "$branch"
|
|
read -r del < /dev/tty
|
|
[ "$del" = "y" ] || [ "$del" = "Y" ] && git branch -d "$branch" 2>/dev/null
|
|
break
|
|
;;
|
|
r|reject)
|
|
printf 'Delete branch %s? [y/N] ' "$branch"
|
|
read -r del < /dev/tty
|
|
if [ "$del" = "y" ] || [ "$del" = "Y" ]; then
|
|
git branch -D "$branch" 2>/dev/null
|
|
printf '\033[1;31m✗ Task %s rejected, branch deleted.\033[0m\n' "$tid"
|
|
else
|
|
printf '\033[1;31m✗ Task %s rejected, branch kept.\033[0m\n' "$tid"
|
|
fi
|
|
break
|
|
;;
|
|
d|diff)
|
|
git diff "$base"..."$branch" --color=always | ${PAGER:-less -R}
|
|
;;
|
|
l|log)
|
|
if [ -f "$LOG_DIR/${tid}.log" ]; then
|
|
${PAGER:-less -R} "$LOG_DIR/${tid}.log"
|
|
else
|
|
echo "No log file for $tid"
|
|
fi
|
|
;;
|
|
e|edit)
|
|
files=$(git diff "$base"..."$branch" --name-only)
|
|
${EDITOR:-vi} $files
|
|
;;
|
|
s|skip)
|
|
printf 'Skipping %s.\n' "$tid"
|
|
break
|
|
;;
|
|
*)
|
|
echo "Unknown action: $action"
|
|
;;
|
|
esac
|
|
done
|