diablo2-web/scripts/worktree.sh

165 lines
4.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# ==============================================================================
# Diablo 2 Web - Git Worktree Helper for Multi-Session Parallel Issue Fixing
#
# Usage:
# ./scripts/worktree.sh create <issue_id_or_name> [base_branch]
# ./scripts/worktree.sh list
# ./scripts/worktree.sh remove <issue_id_or_name>
#
# Examples:
# ./scripts/worktree.sh create 42
# ./scripts/worktree.sh create 43 main
# ./scripts/worktree.sh list
# ./scripts/worktree.sh remove 42
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)"
PARENT_DIR="$(dirname "$REPO_ROOT")"
PRIMARY_SOURCE="/usr/local/google/home/taodao/d2w-wg1-main"
if [[ ! -d "$PRIMARY_SOURCE" ]]; then
PRIMARY_SOURCE="$REPO_ROOT"
fi
parse_target() {
local input="$1"
if [[ "$input" =~ ^[0-9]+$ ]]; then
BRANCH="fix/issue-${input}"
DIR_NAME="d2w-issue-${input}"
elif [[ "$input" =~ ^fix/issue-([0-9]+)$ ]]; then
BRANCH="$input"
DIR_NAME="d2w-issue-${BASH_REMATCH[1]}"
else
BRANCH="$input"
local sanitized
sanitized="$(echo "$input" | tr '/' '-')"
DIR_NAME="d2w-${sanitized}"
fi
TARGET_DIR="${PARENT_DIR}/${DIR_NAME}"
}
cmd_create() {
local input="${1:-}"
local base_branch="${2:-main}"
if [[ -z "$input" ]]; then
echo "Error: Issue ID or branch name is required."
echo "Example: $0 create 42"
exit 1
fi
parse_target "$input"
echo "============================================================"
echo ">>> Creating Worktree for Issue/Task: $input"
echo " Target Directory: $TARGET_DIR"
echo " Branch Name: $BRANCH"
echo " Base Branch: $base_branch"
echo "============================================================"
if [[ -d "$TARGET_DIR" ]]; then
echo "Error: Directory '$TARGET_DIR' already exists!"
exit 1
fi
# Check if branch exists
if git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/$BRANCH"; then
echo "--> Branch '$BRANCH' already exists. Attaching to existing branch..."
git -C "$REPO_ROOT" worktree add "$TARGET_DIR" "$BRANCH"
else
echo "--> Creating new branch '$BRANCH' from '$base_branch'..."
git -C "$REPO_ROOT" worktree add "$TARGET_DIR" -b "$BRANCH" "$base_branch"
fi
echo "--> Symlinking node_modules from $PRIMARY_SOURCE..."
if [[ -d "$PRIMARY_SOURCE/node_modules" ]]; then
ln -s "$PRIMARY_SOURCE/node_modules" "$TARGET_DIR/node_modules"
else
echo "Warning: $PRIMARY_SOURCE/node_modules not found. You may need to run 'npm install'."
fi
echo "--> Symlinking samples/ assets..."
mkdir -p "$TARGET_DIR/samples"
if [[ -d "$PRIMARY_SOURCE/samples/d2-packs" ]]; then
ln -s "$PRIMARY_SOURCE/samples/d2-packs" "$TARGET_DIR/samples/d2-packs"
fi
if [[ -L "$PRIMARY_SOURCE/samples/d2" ]]; then
cp -P "$PRIMARY_SOURCE/samples/d2" "$TARGET_DIR/samples/d2" 2>/dev/null || true
fi
echo "--> Running smoke verification test in new worktree..."
(
cd "$TARGET_DIR"
npx vitest run tests/save-schema.test.ts --reporter=basic
)
echo ""
echo "============================================================"
echo " Worktree created successfully!"
echo "============================================================"
echo "To start working in this session:"
echo " cd $TARGET_DIR"
echo ""
echo "To run tests in this worktree:"
echo " npm test"
echo ""
echo "To run Vite dev server (use a separate port):"
echo " npm run dev -- --port 5174"
echo ""
echo "When finished with this issue, you can clean it up via:"
echo " $0 remove $input"
echo "============================================================"
}
cmd_list() {
echo "Current active worktrees:"
git -C "$REPO_ROOT" worktree list
}
cmd_remove() {
local input="${1:-}"
if [[ -z "$input" ]]; then
echo "Error: Issue ID or branch name is required."
echo "Example: $0 remove 42"
exit 1
fi
parse_target "$input"
if [[ ! -d "$TARGET_DIR" ]]; then
echo "Warning: Directory '$TARGET_DIR' does not exist."
git -C "$REPO_ROOT" worktree list
return
fi
echo "Removing worktree at '$TARGET_DIR'..."
# Remove symlinks first to be clean
rm -f "$TARGET_DIR/node_modules" "$TARGET_DIR/samples/d2-packs" "$TARGET_DIR/samples/d2" 2>/dev/null || true
git -C "$REPO_ROOT" worktree remove "$TARGET_DIR"
echo "Worktree removed. Note: Git branch '$BRANCH' is preserved."
echo "To delete the branch as well (if merged), run:"
echo " git branch -d $BRANCH"
}
case "${1:-}" in
create)
shift
cmd_create "$@"
;;
list)
cmd_list
;;
remove)
shift
cmd_remove "$@"
;;
*)
echo "Usage: $0 {create <id>|list|remove <id>}"
exit 1
;;
esac