327 lines
8.5 KiB
Bash
Executable File
327 lines
8.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
#
|
||
# CMake Configuration Validator
|
||
#
|
||
# Validates that a set of CMake flags would result in a valid configuration.
|
||
# Catches common mistakes before running a full build.
|
||
#
|
||
# Usage:
|
||
# ./scripts/validate-cmake-config.sh [FLAGS]
|
||
#
|
||
# Examples:
|
||
# ./scripts/validate-cmake-config.sh -DYAZE_ENABLE_GRPC=ON -DYAZE_ENABLE_REMOTE_AUTOMATION=OFF
|
||
# ./scripts/validate-cmake-config.sh -DYAZE_ENABLE_HTTP_API=ON -DYAZE_ENABLE_AGENT_CLI=OFF
|
||
# ./scripts/validate-cmake-config.sh -DYAZE_BUILD_AGENT_UI=ON -DYAZE_BUILD_GUI=OFF
|
||
#
|
||
|
||
set -euo pipefail
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# Validation rules
|
||
# Format: "Flag1=Value1" "Flag2=Value2" "ERROR_MESSAGE"
|
||
declare -a INCOMPATIBLE_PAIRS=(
|
||
"YAZE_ENABLE_GRPC=OFF" "YAZE_ENABLE_REMOTE_AUTOMATION=ON" "REMOTE_AUTOMATION requires GRPC"
|
||
"YAZE_ENABLE_HTTP_API=ON" "YAZE_ENABLE_AGENT_CLI=OFF" "HTTP_API requires AGENT_CLI"
|
||
"YAZE_BUILD_AGENT_UI=ON" "YAZE_BUILD_GUI=OFF" "AGENT_UI requires BUILD_GUI"
|
||
"YAZE_ENABLE_AI_RUNTIME=ON" "YAZE_ENABLE_AI=OFF" "AI_RUNTIME requires ENABLE_AI"
|
||
)
|
||
|
||
# Single-flag rules (flag must have specific value)
|
||
declare -A SINGLE_FLAG_RULES=(
|
||
# If left side is ON, right side must also be ON
|
||
# Format handled specially below
|
||
)
|
||
|
||
# ============================================================================
|
||
# Helper Functions
|
||
# ============================================================================
|
||
|
||
log_error() {
|
||
echo -e "${RED}✗ ERROR${NC}: $*"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}! WARNING${NC}: $*"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}✓${NC} $*"
|
||
}
|
||
|
||
log_info() {
|
||
echo -e "${BLUE}ℹ${NC} $*"
|
||
}
|
||
|
||
print_usage() {
|
||
cat <<'EOF'
|
||
CMake Configuration Validator
|
||
|
||
Validates CMake flag combinations before building.
|
||
|
||
Usage:
|
||
./scripts/validate-cmake-config.sh [CMake flags]
|
||
|
||
Examples:
|
||
# Check if this combination is valid
|
||
./scripts/validate-cmake-config.sh \
|
||
-DYAZE_ENABLE_GRPC=ON \
|
||
-DYAZE_ENABLE_REMOTE_AUTOMATION=OFF
|
||
|
||
# Batch check multiple combinations
|
||
./scripts/validate-cmake-config.sh \
|
||
-DYAZE_ENABLE_HTTP_API=ON \
|
||
-DYAZE_ENABLE_AGENT_CLI=OFF
|
||
|
||
Rules Checked:
|
||
1. Dependency constraints
|
||
2. Mutual exclusivity
|
||
3. Feature prerequisites
|
||
4. Platform-specific requirements
|
||
|
||
Output:
|
||
✓ All checks passed
|
||
✗ Error: Specific problem found
|
||
! Warning: Potential issue
|
||
|
||
EOF
|
||
}
|
||
|
||
# ============================================================================
|
||
# Configuration Parsing
|
||
# ============================================================================
|
||
|
||
parse_flags() {
|
||
declare -gA FLAGS_PROVIDED
|
||
|
||
for flag in "$@"; do
|
||
if [[ "$flag" =~ ^-D([A-Z_]+)=(.*)$ ]]; then
|
||
local key="${BASH_REMATCH[1]}"
|
||
local value="${BASH_REMATCH[2]}"
|
||
FLAGS_PROVIDED["$key"]="$value"
|
||
fi
|
||
done
|
||
}
|
||
|
||
get_flag_value() {
|
||
local flag="$1"
|
||
local default="${2:-}"
|
||
|
||
# Return user-provided value if available
|
||
if [[ -n "${FLAGS_PROVIDED[$flag]:-}" ]]; then
|
||
echo "${FLAGS_PROVIDED[$flag]}"
|
||
else
|
||
echo "$default"
|
||
fi
|
||
}
|
||
|
||
# ============================================================================
|
||
# Validation Rules
|
||
# ============================================================================
|
||
|
||
check_dependency_constraint() {
|
||
local dependent="$1"
|
||
local dependency="$2"
|
||
local error_msg="$3"
|
||
|
||
local dependent_value=$(get_flag_value "$dependent" "OFF")
|
||
local dependency_value=$(get_flag_value "$dependency" "OFF")
|
||
|
||
# If dependent is ON, dependency must be ON
|
||
if [[ "$dependent_value" == "ON" ]] && [[ "$dependency_value" != "ON" ]]; then
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_remote_automation() {
|
||
# REMOTE_AUTOMATION requires GRPC
|
||
if ! check_dependency_constraint "YAZE_ENABLE_REMOTE_AUTOMATION" "YAZE_ENABLE_GRPC" \
|
||
"YAZE_ENABLE_REMOTE_AUTOMATION=ON requires YAZE_ENABLE_GRPC=ON"; then
|
||
log_error "YAZE_ENABLE_REMOTE_AUTOMATION=ON requires YAZE_ENABLE_GRPC=ON"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_http_api() {
|
||
# HTTP_API requires AGENT_CLI
|
||
if ! check_dependency_constraint "YAZE_ENABLE_HTTP_API" "YAZE_ENABLE_AGENT_CLI" \
|
||
"YAZE_ENABLE_HTTP_API=ON requires YAZE_ENABLE_AGENT_CLI=ON"; then
|
||
log_error "YAZE_ENABLE_HTTP_API=ON requires YAZE_ENABLE_AGENT_CLI=ON"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_agent_ui() {
|
||
# AGENT_UI requires BUILD_GUI
|
||
if ! check_dependency_constraint "YAZE_BUILD_AGENT_UI" "YAZE_BUILD_GUI" \
|
||
"YAZE_BUILD_AGENT_UI=ON requires YAZE_BUILD_GUI=ON"; then
|
||
log_error "YAZE_BUILD_AGENT_UI=ON requires YAZE_BUILD_GUI=ON"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_ai_runtime() {
|
||
# AI_RUNTIME requires AI
|
||
if ! check_dependency_constraint "YAZE_ENABLE_AI_RUNTIME" "YAZE_ENABLE_AI" \
|
||
"YAZE_ENABLE_AI_RUNTIME=ON requires YAZE_ENABLE_AI=ON"; then
|
||
log_error "YAZE_ENABLE_AI_RUNTIME=ON requires YAZE_ENABLE_AI=ON"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_gemini_support() {
|
||
# Gemini support needs both AI_RUNTIME and JSON
|
||
local ai_runtime=$(get_flag_value "YAZE_ENABLE_AI_RUNTIME" "OFF")
|
||
local json=$(get_flag_value "YAZE_ENABLE_JSON" "ON")
|
||
|
||
if [[ "$ai_runtime" == "ON" ]] && [[ "$json" != "ON" ]]; then
|
||
log_warning "YAZE_ENABLE_AI_RUNTIME=ON without YAZE_ENABLE_JSON=ON"
|
||
log_info " → Gemini service requires JSON parsing"
|
||
log_info " → Ollama will still work without JSON"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
validate_agent_cli_auto_enable() {
|
||
# AGENT_CLI is auto-enabled if BUILD_CLI or BUILD_Z3ED enabled
|
||
local build_cli=$(get_flag_value "YAZE_BUILD_CLI" "ON")
|
||
local build_z3ed=$(get_flag_value "YAZE_BUILD_Z3ED" "ON")
|
||
local agent_cli=$(get_flag_value "YAZE_ENABLE_AGENT_CLI" "")
|
||
|
||
if [[ "$agent_cli" == "OFF" ]] && ([[ "$build_cli" == "ON" ]] || [[ "$build_z3ed" == "ON" ]]); then
|
||
log_warning "YAZE_ENABLE_AGENT_CLI=OFF but YAZE_BUILD_CLI or BUILD_Z3ED is ON"
|
||
log_info " → AGENT_CLI will be auto-enabled by CMake"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
# ============================================================================
|
||
# Recommendations
|
||
# ============================================================================
|
||
|
||
suggest_configuration() {
|
||
local remote_auto=$(get_flag_value "YAZE_ENABLE_REMOTE_AUTOMATION" "OFF")
|
||
local http_api=$(get_flag_value "YAZE_ENABLE_HTTP_API" "OFF")
|
||
local ai_runtime=$(get_flag_value "YAZE_ENABLE_AI_RUNTIME" "OFF")
|
||
local build_gui=$(get_flag_value "YAZE_BUILD_GUI" "ON")
|
||
local build_cli=$(get_flag_value "YAZE_BUILD_CLI" "ON")
|
||
|
||
echo ""
|
||
echo "Suggested preset configurations:"
|
||
echo ""
|
||
|
||
if [[ "$build_gui" == "ON" ]] && [[ "$ai_runtime" != "ON" ]]; then
|
||
log_info "GUI-only user? Use preset: mac-dbg, lin-dbg, or win-dbg"
|
||
fi
|
||
|
||
if [[ "$remote_auto" == "ON" ]] && [[ "$ai_runtime" == "ON" ]]; then
|
||
log_info "Full-featured dev? Use preset: mac-ai, lin-ai, or win-ai"
|
||
fi
|
||
|
||
if [[ "$build_cli" == "ON" ]] && [[ "$build_gui" != "ON" ]]; then
|
||
log_info "CLI-only user? Use preset: win-z3ed or custom CLI config"
|
||
fi
|
||
}
|
||
|
||
# ============================================================================
|
||
# Main Validation
|
||
# ============================================================================
|
||
|
||
validate_configuration() {
|
||
local errors=0
|
||
local warnings=0
|
||
|
||
log_info "Validating CMake configuration..."
|
||
echo ""
|
||
|
||
# Run all validation checks
|
||
if ! validate_remote_automation; then
|
||
errors=$((errors + 1))
|
||
fi
|
||
|
||
if ! validate_http_api; then
|
||
errors=$((errors + 1))
|
||
fi
|
||
|
||
if ! validate_agent_ui; then
|
||
errors=$((errors + 1))
|
||
fi
|
||
|
||
if ! validate_ai_runtime; then
|
||
errors=$((errors + 1))
|
||
fi
|
||
|
||
if ! validate_gemini_support; then
|
||
warnings=$((warnings + 1))
|
||
fi
|
||
|
||
if ! validate_agent_cli_auto_enable; then
|
||
warnings=$((warnings + 1))
|
||
fi
|
||
|
||
echo ""
|
||
|
||
if [[ $errors -gt 0 ]]; then
|
||
log_error "$errors critical issue(s) found"
|
||
echo ""
|
||
echo "Fix these before building:"
|
||
echo " - Check documentation: docs/internal/configuration-matrix.md"
|
||
echo " - Run: ./scripts/test-config-matrix.sh --verbose"
|
||
suggest_configuration
|
||
return 1
|
||
fi
|
||
|
||
if [[ $warnings -gt 0 ]]; then
|
||
log_warning "$warnings warning(s) found"
|
||
echo ""
|
||
log_info "These may work, but might not have all features"
|
||
fi
|
||
|
||
if [[ $errors -eq 0 ]]; then
|
||
log_success "Configuration is valid!"
|
||
suggest_configuration
|
||
return 0
|
||
fi
|
||
}
|
||
|
||
# ============================================================================
|
||
# Entry Point
|
||
# ============================================================================
|
||
|
||
main() {
|
||
if [[ $# -eq 0 ]]; then
|
||
print_usage
|
||
exit 0
|
||
fi
|
||
|
||
if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
|
||
print_usage
|
||
exit 0
|
||
fi
|
||
|
||
# Parse provided flags
|
||
parse_flags "$@"
|
||
|
||
# Run validation
|
||
if validate_configuration; then
|
||
exit 0
|
||
else
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
main "$@"
|