main
sh 154 lines 4.39 KB
Raw
1 #!/usr/bin/env bash
2 # Copyright (c) Meta Platforms, Inc. and affiliates.
3 #
4 # This source code is licensed under the MIT license found in the
5 # LICENSE file in the root directory of this source tree.
6
7 set -eo pipefail
8
9 # --- Configuration ---
10 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11 REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
12 WORKTREE_CREATED=false
13 WORKTREE_PATH=""
14
15 # --- Usage ---
16 usage() {
17 echo "Usage: $0 [name] [--claude] [--compiler]"
18 echo ""
19 echo "Creates a new git worktree with dependencies installed."
20 echo ""
21 echo "Arguments:"
22 echo " [name] Name for the worktree (auto-generated if not provided)"
23 echo ""
24 echo "Options:"
25 echo " --claude Launch Claude Code after setup"
26 echo " --compiler When used with --claude, launch Claude in the compiler directory"
27 exit 1
28 }
29
30 # --- Error handling ---
31 error() {
32 echo "Error: $1" >&2
33 exit 1
34 }
35
36 # --- Cleanup on error ---
37 cleanup() {
38 if [[ "$WORKTREE_CREATED" == "true" && -n "$WORKTREE_PATH" ]]; then
39 echo "Cleaning up: removing worktree at $WORKTREE_PATH..." >&2
40 git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || true
41 fi
42 }
43
44 trap cleanup ERR
45
46 # --- Argument parsing ---
47 NAME=""
48 USE_CLAUDE=false
49 USE_COMPILER=false
50
51 while [[ $# -gt 0 ]]; do
52 case "$1" in
53 --claude)
54 USE_CLAUDE=true
55 shift
56 ;;
57 --compiler)
58 USE_COMPILER=true
59 shift
60 ;;
61 -h|--help)
62 usage
63 ;;
64 -*)
65 error "Unknown option: $1"
66 ;;
67 *)
68 if [[ -z "$NAME" ]]; then
69 NAME="$1"
70 else
71 error "Unexpected argument: $1"
72 fi
73 shift
74 ;;
75 esac
76 done
77
78 # Generate worktree name with timestamp prefix
79 TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S)
80
81 if [[ -z "$NAME" ]]; then
82 # Word lists for random name generation
83 ADJECTIVES=(
84 "quick" "bright" "calm" "dark" "eager" "fair" "gentle" "happy" "idle" "jolly"
85 "keen" "lively" "merry" "noble" "orange" "proud" "quiet" "rapid" "silent" "tall"
86 "unique" "vivid" "warm" "young" "zealous" "ancient" "bold" "clever" "daring" "elegant"
87 "fancy" "grand" "humble" "icy" "jagged" "kind" "loud" "magic" "narrow" "odd"
88 "plain" "quaint" "rough" "sharp" "tender" "ultra" "vast" "wild" "xeric" "youthful"
89 "zesty" "agile" "brave" "crisp" "deep"
90 )
91 NOUNS=(
92 "apple" "bear" "cloud" "dragon" "eagle" "flame" "garden" "hill" "island" "jungle"
93 "kettle" "lemon" "mountain" "night" "ocean" "panda" "quartz" "river" "storm" "tiger"
94 "umbrella" "valley" "whale" "xenon" "yarn" "zebra" "anchor" "bridge" "canyon" "desert"
95 "ember" "forest" "glacier" "harbor" "igloo" "jewel" "knight" "lantern" "meadow" "nebula"
96 "oasis" "phoenix" "quest" "rocket" "shadow" "thunder" "unity" "vortex" "willow" "xylophone"
97 "yonder" "zenith" "aurora" "beacon" "coral"
98 )
99
100 # Generate random name: worktree-yyyy-mm-dd-hh-mm-ss-<adjective>-<noun>
101 RANDOM_ADJ=${ADJECTIVES[$RANDOM % ${#ADJECTIVES[@]}]}
102 RANDOM_NOUN=${NOUNS[$RANDOM % ${#NOUNS[@]}]}
103 NAME="worktree-${TIMESTAMP}-${RANDOM_ADJ}-${RANDOM_NOUN}"
104 echo "Auto-generated worktree name: $NAME"
105 else
106 # Use provided name: worktree-yyyy-mm-dd-hh-mm-ss-<name>
107 NAME="worktree-${TIMESTAMP}-${NAME}"
108 echo "Worktree name: $NAME"
109 fi
110
111 # --- Check .gitignore ---
112 if ! grep -qE '^/?\.worktrees/?$' "$REPO_ROOT/.gitignore" 2>/dev/null; then
113 error "'.worktrees' is not in .gitignore. Add it before creating worktrees."
114 fi
115
116 # --- Check if worktree already exists ---
117 if git worktree list | grep -q "\[$NAME\]"; then
118 error "Worktree with branch name '$NAME' already exists"
119 fi
120
121 # --- Set up worktree path ---
122 WORKTREES_DIR="$REPO_ROOT/.worktrees"
123 WORKTREE_PATH="$WORKTREES_DIR/$NAME"
124
125 if [[ -d "$WORKTREE_PATH" ]]; then
126 error "Directory already exists at $WORKTREE_PATH"
127 fi
128
129 # --- Create worktree ---
130 mkdir -p "$WORKTREES_DIR"
131 echo "Creating worktree '$NAME' at $WORKTREE_PATH..."
132 git worktree add "$WORKTREE_PATH" -b "$NAME"
133 WORKTREE_CREATED=true
134
135 # --- Install dependencies ---
136 echo "Installing compiler dependencies..."
137 (cd "$WORKTREE_PATH/compiler" && yarn install)
138
139 echo "Installing root dependencies..."
140 (cd "$WORKTREE_PATH" && yarn install)
141
142 echo "Worktree '$NAME' created successfully at $WORKTREE_PATH"
143
144 # --- Launch Claude (optional) ---
145 if [[ "$USE_CLAUDE" == "true" ]]; then
146 if [[ "$USE_COMPILER" == "true" ]]; then
147 echo "Launching Claude in compiler directory..."
148 cd "$WORKTREE_PATH/compiler"
149 else
150 echo "Launching Claude in worktree root..."
151 cd "$WORKTREE_PATH"
152 fi
153 exec claude
154 fi