#!/bin/bash
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
echo "Usage: nop-batch-worktree.sh <input-file>"
echo "Usage (validate only): nop-batch-worktree.sh -c <input-file>"
echo ""
echo "Options:"
echo " -c, --check Validate input file format only (no execution)"
echo " --help, -h Show this help message"
echo ""
echo "Input file format:"
echo " >>> feature-name [base-branch] <<<"
echo " argument-1"
echo " argument-2"
echo ""
echo " >>> another-feature <<<"
echo " argument-1"
echo ""
echo "Examples:"
echo " nop-batch-worktree.sh tasks.txt"
echo " nop-batch-worktree.sh -c tasks.txt"
exit 0
fi
find_project_root() {
local current_dir="$(pwd)"
local max_depth=5
local depth=0
while [ $depth -lt $max_depth ]; do
if [ -d "$current_dir/.git" ]; then
echo "$current_dir"
return 0
fi
current_dir="$(dirname "$current_dir")"
if [ "$current_dir" = "/" ]; then
break
fi
((depth++))
done
return 1
}
PROJECT_ROOT=$(find_project_root)
if [ $? -ne 0 ]; then
echo "Error: Could not find project root directory"
echo "Please run this script from within a git repository"
exit 1
fi
MAIN_REPO="$PROJECT_ROOT"
WORKTREES_DIR="$(dirname "$MAIN_REPO")/worktrees"
log_info() {
echo "[INFO] $1"
}
log_warn() {
echo "[WARN] $1"
}
log_error() {
echo "[ERROR] $1"
}
log_success() {
echo "[SUCCESS] $1"
}
if ! command -v nop-ai >/dev/null 2>&1; then
log_error "nop-ai command not found in PATH"
exit 1
fi
if [ "$1" == "-c" ] || [ "$1" == "--check" ]; then
VALIDATE_ONLY=true
INPUT_FILE="$2"
else
VALIDATE_ONLY=false
INPUT_FILE="$1"
fi
if [ -z "$INPUT_FILE" ]; then
echo "Usage: $0 <input-file>"
echo " or: $0 -c <input-file> (validate only)"
exit 1
fi
if [ ! -f "$INPUT_FILE" ]; then
log_error "Input file not found: $INPUT_FILE"
exit 1
fi
validate_input_file() {
local file="$1"
local section_count=0
local in_section=false
local has_args=false
while IFS= read -r line; do
if [[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then
continue
fi
if [[ "$line" =~ ^\>\>\>\>[[:space:]]+([^[:space:]]+)[[:space:]]*\<\<\< ]]; then
in_section=true
has_args=false
((section_count++))
elif [[ "$in_section" == true ]]; then
if [[ ! -z "$line" ]] && [[ ! "$line" =~ ^[[:space:]]*$ ]]; then
has_args=true
fi
fi
done < "$file"
if [ $section_count -eq 0 ]; then
log_error "No valid sections found in input file"
return 1
fi
log_info "Format validation passed. Found $section_count section(s)."
return 0
}
validate_input_file "$INPUT_FILE"
if [ $? -ne 0 ]; then
exit 1
fi
if [ "$VALIDATE_ONLY" = true ]; then
log_info "Validation complete. File format is valid."
exit 0
fi
process_input_file() {
local file="$1"
local section_count=0
local failed_sections=0
local current_section=""
local current_feature=""
local current_base_branch=""
local current_args=""
local current_timestamp=""
local in_section=false
while IFS= read -r line; do
if [[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then
continue
fi
if [[ "$line" =~ ^\>\>\>\>[[:space:]]+([^[:space:]]+)([[:space:]]+([^[:space:]]+))?[[:space:]]*\<\<\< ]]; then
if [ ! -z "$current_section" ]; then
process_section "$current_section" "$current_feature" "$current_base_branch" "$current_args" "$current_timestamp"
if [ $? -ne 0 ]; then
((failed_sections++))
fi
fi
current_section="${BASH_REMATCH[1]}"
current_base_branch="${BASH_REMATCH[3]:-}"
current_timestamp=$(date +%Y%m%d-%H%M%S)
current_feature="$current_section"
current_args=""
in_section=true
((section_count++))
echo ""
echo "[FOUND] Found new section: $current_section"
echo " Base branch: ${current_base_branch:-<default>}"
elif [[ "$in_section" == true ]]; then
current_args="${current_args}${line}"$'\n'
fi
done < "$file"
if [ ! -z "$current_section" ]; then
process_section "$current_section" "$current_feature" "$current_base_branch" "$current_args" "$current_timestamp"
if [ $? -ne 0 ]; then
((failed_sections++))
fi
fi
echo ""
echo "========================================"
echo "[SUMMARY] BATCH WORKTREE SUMMARY"
echo "========================================"
echo "Total sections: $section_count"
echo "Successful: $((section_count - failed_sections))"
echo "Failed: $failed_sections"
echo "========================================"
return $failed_sections
}
process_section() {
local section_name="$1"
local feature_name="$2"
local base_branch="$3"
local args="$4"
local timestamp="$5"
echo ""
echo "========================================"
echo "[$section_count/$TOTAL_SECTIONS] Processing feature: $feature_name"
echo "========================================"
echo "Timestamp: $timestamp"
echo "Base branch: ${base_branch:-<default>}"
echo "Arguments count: $(echo "$args" | grep -c '[^[:space:]]' 2>/dev/null || echo 0)"
echo ""
if ! command -v nop-create-worktree >/dev/null 2>&1; then
log_error "nop-create-worktree command not found in PATH"
((failed_sections++))
else
feature_with_timestamp="TMP-${timestamp}-${feature_name}"
echo "[DIR] Creating worktree: $feature_with_timestamp"
echo "[DIR] Worktree directory: ../worktrees/$feature_with_timestamp"
WORKTREE_START=$(date +%s)
if [ -n "$base_branch" ]; then
nop-create-worktree "$feature_with_timestamp" "$base_branch" 2>&1 | tee -a worktree-creation.log
WORKTREE_EXIT_CODE=${PIPESTATUS[0]}
else
nop-create-worktree "$feature_with_timestamp" 2>&1 | tee -a worktree-creation.log
WORKTREE_EXIT_CODE=${PIPESTATUS[0]}
fi
WORKTREE_END=$(date +%s)
WORKTREE_ELAPSED=$((WORKTREE_END - WORKTREE_START))
if [ $WORKTREE_EXIT_CODE -ne 0 ]; then
echo ""
echo "[ERROR] ERROR: Failed to create worktree for $feature_name"
echo "[ERROR] Exit code: $WORKTREE_EXIT_CODE"
echo "[ERROR] Time elapsed: ${WORKTREE_ELAPSED}s"
echo "[ERROR] Check worktree-creation.log for detailed error information"
echo "[ERROR] Attempted command: nop-create-worktree $feature_with_timestamp ${base_branch:+$base_branch}"
((failed_sections++))
else
echo "[OK] Worktree created successfully (took ${WORKTREE_ELAPSED}s)"
MAIN_REPO="$PROJECT_ROOT"
WORKTREES_DIR="$(dirname "$MAIN_REPO")/worktrees"
worktree_dir="${WORKTREES_DIR}/TMP-${timestamp}-${feature_name}"
if [ ! -d "$worktree_dir" ]; then
echo "[ERROR] CRITICAL ERROR: Worktree directory does not exist: $worktree_dir"
echo "[ERROR] This should not happen - worktree script returned success but directory was not created"
((failed_sections++))
continue
fi
if [ -d "$worktree_dir" ]; then
echo ""
echo "[CHANGE] Changing to worktree directory: $worktree_dir"
cd "$worktree_dir" || { echo "[ERROR] ERROR: Failed to cd to $worktree_dir"; ((failed_sections++)); continue; }
echo "[LOCATION] Current directory: $(pwd)"
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "<unknown>")
echo "[BRANCH] Current branch: $CURRENT_BRANCH"
ARG_LINES_COUNT=$(echo "$args" | grep -c '[^[:space:]]' 2>/dev/null || echo 0)
echo "[EXEC] Executing $ARG_LINES_COUNT argument line(s)..."
echo ""
arg_line_number=0
while IFS= read -r arg_line; do
if [[ -z "$arg_line" ]] || [[ "$arg_line" =~ ^[[:space:]]*# ]]; then
continue
fi
((arg_line_number++))
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "[${section_count}.${arg_line_number}] Executing nop-ai run"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Command: nop-ai run $arg_line"
echo "[TIME] Started: $(date)" | tee -a opencode-debug-${timestamp}.txt
echo "[CMD] Command: nop-ai run $arg_line" | tee -a opencode-debug-${timestamp}.txt
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | tee -a opencode-debug-${timestamp}.txt
START_TIME=$(date +%s)
nop-ai run $arg_line
EXIT_CODE=$?
END_TIME=$(date +%s)
ELAPSED=$((END_TIME - START_TIME))
MINUTES=$((ELAPSED / 60))
SECONDS_REMAINDER=$((ELAPSED % 60))
echo ""
if [ $EXIT_CODE -eq 0 ]; then
echo "[OK] Command completed successfully (took ${MINUTES}m ${SECONDS_REMAINDER}s)"
else
echo "[ERROR] Command failed with exit code: $EXIT_CODE (took ${MINUTES}m ${SECONDS_REMAINDER}s)"
fi
echo ""
done <<< "$args"
cd "$MAIN_REPO"
fi
fi
fi
}
TOTAL_SECTIONS=$(grep -c "^>>>" "$INPUT_FILE" 2>/dev/null || echo 0)
section_count=0
echo ""
echo "========================================"
echo "[SUMMARY] BATCH WORKTREE EXECUTION"
echo "========================================"
echo "Input file: $INPUT_FILE"
echo "Total sections to process: $TOTAL_SECTIONS"
echo "Validation mode: $VALIDATE_ONLY"
echo "========================================"
process_input_file "$INPUT_FILE"
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
echo ""
log_error "Batch worktree processing completed with errors"
exit 1
else
echo ""
log_success "Batch worktree processing completed successfully!"
exit 0
fi