Created
February 27, 2026 21:17
-
-
Save kmosher/2e8a2c6bf19b0dcd4df769f0f6665e2b to your computer and use it in GitHub Desktop.
pulumi-service-worktree CLI tool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # pulumi-service-worktree - Standardized worktree setup for ~/pulumi/service | |
| # | |
| # Usage: | |
| # pulumi-service-worktree <branch-name> [base-branch] | |
| # | |
| # Creates a new worktree with all necessary setup: | |
| # - CLAUDE.md symlink | |
| # - Submodule initialization | |
| # - Dependencies (make ensure) | |
| # - Optional: shared node_modules linking | |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| SERVICE_DIR="$HOME/pulumi/service" | |
| usage() { | |
| cat <<EOF | |
| Usage: $(basename "$0") <branch-name> [base-branch] | |
| Creates a standardized git worktree for pulumi-service with: | |
| - CLAUDE.md symlink to parent directory | |
| - Initialized submodules | |
| - Installed dependencies (make ensure) | |
| Arguments: | |
| branch-name Name of the new branch (will be created) | |
| Git branch will be prefixed with kmosher/ | |
| Directory name will use the unprefixed version | |
| You can specify with or without the kmosher/ prefix | |
| base-branch Branch to base off (default: master) | |
| Options: | |
| --fast-node-modules Hard-link node_modules from main, then let yarn update | |
| (recommended - much faster, no extra disk space) | |
| --help Show this help | |
| Examples: | |
| $(basename "$0") fix-auth-bug # → kmosher/fix-auth-bug (dir: fix-auth-bug) | |
| $(basename "$0") kmosher/feature-webhooks # → kmosher/feature-webhooks (dir: feature-webhooks) | |
| $(basename "$0") --fast-node-modules quick-fix # Recommended for speed | |
| EOF | |
| exit "${1:-0}" | |
| } | |
| # Parse arguments | |
| FAST_NODE_MODULES=false | |
| BRANCH_NAME="" | |
| BASE_BRANCH="master" | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --help|-h) | |
| usage 0 | |
| ;; | |
| --fast-node-modules) | |
| FAST_NODE_MODULES=true | |
| shift | |
| ;; | |
| -*) | |
| echo "Error: Unknown option: $1" >&2 | |
| usage 1 | |
| ;; | |
| *) | |
| if [[ -z "$BRANCH_NAME" ]]; then | |
| BRANCH_NAME="$1" | |
| elif [[ "$BASE_BRANCH" == "master" ]]; then | |
| BASE_BRANCH="$1" | |
| else | |
| echo "Error: Too many arguments" >&2 | |
| usage 1 | |
| fi | |
| shift | |
| ;; | |
| esac | |
| done | |
| if [[ -z "$BRANCH_NAME" ]]; then | |
| echo "Error: branch-name is required" >&2 | |
| usage 1 | |
| fi | |
| # Normalize branch name: strip kmosher/ prefix if present | |
| BRANCH_NAME_NORMALIZED="${BRANCH_NAME#kmosher/}" | |
| # Set names: git branch gets kmosher/ prefix, directory uses normalized name | |
| GIT_BRANCH_NAME="kmosher/$BRANCH_NAME_NORMALIZED" | |
| WORKTREE_DIR="$SERVICE_DIR/$BRANCH_NAME_NORMALIZED" | |
| # Validate we're in the right place | |
| if [[ ! -d "$SERVICE_DIR/main/.git" ]] && [[ ! -f "$SERVICE_DIR/main/.git" ]]; then | |
| echo "Error: $SERVICE_DIR/main doesn't appear to be a git worktree" >&2 | |
| exit 1 | |
| fi | |
| # Check if worktree already exists | |
| if [[ -d "$WORKTREE_DIR" ]]; then | |
| echo "Error: Worktree directory already exists: $WORKTREE_DIR" >&2 | |
| exit 1 | |
| fi | |
| echo "Creating worktree: $BRANCH_NAME_NORMALIZED (git branch: $GIT_BRANCH_NAME, based on $BASE_BRANCH)" | |
| # Navigate to main worktree | |
| cd "$SERVICE_DIR/main" | |
| # Fetch latest from origin | |
| echo " → Fetching from origin" | |
| git fetch origin | |
| # Update local base branch to match origin | |
| echo " → Updating local $BASE_BRANCH from origin/$BASE_BRANCH" | |
| git branch -f "$BASE_BRANCH" "origin/$BASE_BRANCH" | |
| # Create worktree | |
| echo " → Creating worktree" | |
| git worktree add "$WORKTREE_DIR" -b "$GIT_BRANCH_NAME" "$BASE_BRANCH" | |
| echo "Setting up worktree environment..." | |
| # Navigate to new worktree | |
| cd "$WORKTREE_DIR" | |
| # 1. Create CLAUDE.md symlink | |
| if [[ ! -L "CLAUDE.md" ]]; then | |
| echo " → Creating CLAUDE.md symlink" | |
| ln -s ../CLAUDE.md CLAUDE.md | |
| fi | |
| # 2. Initialize submodules | |
| if [[ -f .gitmodules ]]; then | |
| echo " → Initializing submodules" | |
| git submodule update --init --recursive | |
| fi | |
| # 3. Install dependencies | |
| if [[ "$FAST_NODE_MODULES" == "true" ]]; then | |
| echo " → Hard-linking node_modules from main worktree" | |
| # Hard link copy from main worktree's node_modules | |
| MAIN_NODE_MODULES="$SERVICE_DIR/main/cmd/console2/node_modules" | |
| if [[ -d "$MAIN_NODE_MODULES" ]]; then | |
| mkdir -p cmd/console2 | |
| echo " Copying with hard links (instant, no disk space)..." | |
| cp -al "$MAIN_NODE_MODULES" cmd/console2/ | |
| echo " → Running make ensure (will update branch-specific packages)" | |
| make ensure | |
| else | |
| echo " Warning: main node_modules not found, running full make ensure" | |
| FAST_NODE_MODULES=false | |
| fi | |
| fi | |
| if [[ "$FAST_NODE_MODULES" == "false" ]]; then | |
| echo " → Running make ensure (this may take a few minutes)" | |
| make ensure | |
| fi | |
| # 4. Verify setup with a basic check | |
| if ! make lint_prereqs >/dev/null 2>&1; then | |
| echo " ⚠ Warning: make lint_prereqs failed, some tools may be missing" | |
| fi | |
| echo "" | |
| echo "✓ Worktree ready at: $WORKTREE_DIR" | |
| echo "" | |
| echo "Next steps:" | |
| echo " cd $WORKTREE_DIR" | |
| echo " # Make your changes" | |
| echo " make test_fast" | |
| echo "" | |
| echo "When done:" | |
| echo " git worktree remove $WORKTREE_DIR" | |
| echo " # or: rm -rf $WORKTREE_DIR && git worktree prune" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment