#!/usr/bin/env bash # Consolidated prerequisite checking script # # This script provides unified prerequisite checking for Spec-Driven Development workflow. # It replaces the functionality previously spread across multiple scripts. # # Usage: ./check-prerequisites.sh [OPTIONS] # # OPTIONS: # --json Output in JSON format # --require-tasks Require tasks-arch.md and tasks-dev.md to exist (for implementation phase) # --include-tasks Include task files in AVAILABLE_DOCS list # --paths-only Only output path variables (no validation) # --help, -h Show help message # # OUTPUTS: # JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]} # Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md # Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc. set -e # Parse command line arguments JSON_MODE=false REQUIRE_TASKS=false INCLUDE_TASKS=false PATHS_ONLY=false for arg in "$@"; do case "$arg" in --json) JSON_MODE=true ;; --require-tasks) REQUIRE_TASKS=true ;; --include-tasks) INCLUDE_TASKS=true ;; --paths-only) PATHS_ONLY=true ;; --help|-h) cat << 'EOF' Usage: check-prerequisites.sh [OPTIONS] Consolidated prerequisite checking for Spec-Driven Development workflow. OPTIONS: --json Output in JSON format --require-tasks Require tasks-arch.md and tasks-dev.md to exist (for implementation phase) --include-tasks Include task files in AVAILABLE_DOCS list --paths-only Only output path variables (no prerequisite validation) --help, -h Show this help message EXAMPLES: # Check task prerequisites (plan.md required) ./check-prerequisites.sh --json # Check implementation prerequisites (plan.md + task files required) ./check-prerequisites.sh --json --require-tasks --include-tasks # Get feature paths only (no validation) ./check-prerequisites.sh --paths-only EOF exit 0 ;; *) echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2 exit 1 ;; esac done # Source common functions SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" # Get feature paths and validate branch eval $(get_feature_paths) check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1 # If paths-only mode, output paths and exit (support JSON + paths-only combined) if $PATHS_ONLY; then if $JSON_MODE; then # Minimal JSON paths payload (no validation performed) printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS_ARCH":"%s","TASKS_DEV":"%s"}\n' \ "$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS_ARCH" "$TASKS_DEV" else echo "REPO_ROOT: $REPO_ROOT" echo "BRANCH: $CURRENT_BRANCH" echo "FEATURE_DIR: $FEATURE_DIR" echo "FEATURE_SPEC: $FEATURE_SPEC" echo "IMPL_PLAN: $IMPL_PLAN" echo "TASKS_ARCH: $TASKS_ARCH" echo "TASKS_DEV: $TASKS_DEV" fi exit 0 fi # Validate required directories and files if [[ ! -d "$FEATURE_DIR" ]]; then echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2 echo "Run /speckit.specify first to create the feature structure." >&2 exit 1 fi if [[ ! -f "$IMPL_PLAN" ]]; then echo "ERROR: plan.md not found in $FEATURE_DIR" >&2 echo "Run /speckit.plan first to create the implementation plan." >&2 exit 1 fi # Check for task files if required if $REQUIRE_TASKS; then # Check for split tasks first if [[ -f "$TASKS_ARCH" ]] && [[ -f "$TASKS_DEV" ]]; then : # Split tasks exist, proceed # Fallback to unified tasks.md elif [[ -f "$TASKS" ]]; then : # Unified tasks exist, proceed else echo "ERROR: No valid task files found in $FEATURE_DIR" >&2 echo "Expected 'tasks-arch.md' AND 'tasks-dev.md' (split) OR 'tasks.md' (unified)" >&2 echo "Run /speckit.tasks first to create the task lists." >&2 exit 1 fi fi # Build list of available documents docs=() # Always check these optional docs [[ -f "$RESEARCH" ]] && docs+=("research.md") [[ -f "$DATA_MODEL" ]] && docs+=("data-model.md") # Check contracts directory (only if it exists and has files) if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then docs+=("contracts/") fi [[ -f "$QUICKSTART" ]] && docs+=("quickstart.md") # Include task files if requested and they exist if $INCLUDE_TASKS; then if [[ -f "$TASKS_ARCH" ]] || [[ -f "$TASKS_DEV" ]]; then [[ -f "$TASKS_ARCH" ]] && docs+=("tasks-arch.md") [[ -f "$TASKS_DEV" ]] && docs+=("tasks-dev.md") elif [[ -f "$TASKS" ]]; then docs+=("tasks.md") fi fi # Output results if $JSON_MODE; then # Build JSON array of documents if [[ ${#docs[@]} -eq 0 ]]; then json_docs="[]" else json_docs=$(printf '"%s",' "${docs[@]}") json_docs="[${json_docs%,}]" fi printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs" else # Text output echo "FEATURE_DIR:$FEATURE_DIR" echo "AVAILABLE_DOCS:" # Show status of each potential document check_file "$RESEARCH" "research.md" check_file "$DATA_MODEL" "data-model.md" check_dir "$CONTRACTS_DIR" "contracts/" check_file "$QUICKSTART" "quickstart.md" if $INCLUDE_TASKS; then if [[ -f "$TASKS_ARCH" ]] || [[ -f "$TASKS_DEV" ]]; then check_file "$TASKS_ARCH" "tasks-arch.md" check_file "$TASKS_DEV" "tasks-dev.md" else check_file "$TASKS" "tasks.md" fi fi fi