windowmaker-wl/tools/wm-port/wm-review

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