#!/usr/bin/env bash # Validate required config files and optional env vars before deployment/scripts # Recommendation: docs/10-best-practices/IMPLEMENTATION_CHECKLIST.md (Configuration validation) # Usage: ./scripts/validation/validate-config-files.sh [--dry-run] # --dry-run Print what would be validated and exit 0 (no file checks). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" DRY_RUN=false for a in "$@"; do [[ "$a" == "--dry-run" ]] && DRY_RUN=true && break; done log_info() { echo "[INFO] $1"; } log_ok() { echo "[OK] $1"; } log_warn() { echo "[WARN] $1"; } log_err() { echo "[ERROR] $1"; } ERRORS=0 # Required config paths (adjust per project) REQUIRED_FILES="${VALIDATE_REQUIRED_FILES:-}" # Example: REQUIRED_FILES="/path/to/config.toml /path/to/.env" # Optional env vars to warn if missing (default empty = no warnings; set VALIDATE_OPTIONAL_ENV for Proxmox API checks) OPTIONAL_ENV="${VALIDATE_OPTIONAL_ENV:-}" check_file() { local f="$1" if [[ -f "$f" ]]; then log_ok "Found: $f" return 0 else log_err "Missing required file: $f" ERRORS=$((ERRORS + 1)) return 1 fi } check_env() { local name="$1" if [[ -z "${!name:-}" ]]; then log_warn "Optional env not set: $name" return 1 else log_ok "Env set: $name" return 0 fi } if $DRY_RUN; then echo "=== Validation (--dry-run: would check) ===" echo " REQUIRED_FILES: ${REQUIRED_FILES:-}" echo " OPTIONAL_ENV: ${OPTIONAL_ENV:-}" exit 0 fi if [[ -n "$REQUIRED_FILES" ]]; then for f in $REQUIRED_FILES; do check_file "$f" done else # Default: check common locations [[ -d "$PROJECT_ROOT/config" ]] && check_file "$PROJECT_ROOT/config/ip-addresses.conf" || true [[ -f "$PROJECT_ROOT/.env.example" ]] && log_ok ".env.example present (copy to .env and fill)" || true # Token mapping (Chain 138 ↔ Mainnet): optional but validate structure if present if [[ -f "$PROJECT_ROOT/config/token-mapping.json" ]]; then log_ok "Found: config/token-mapping.json" if command -v jq &>/dev/null; then if jq -e '.tokens | type == "array"' "$PROJECT_ROOT/config/token-mapping.json" &>/dev/null; then log_ok "token-mapping.json: valid JSON with .tokens array" else log_err "token-mapping.json: invalid or missing .tokens array" ERRORS=$((ERRORS + 1)) fi fi elif [[ -f "$PROJECT_ROOT/config/token-mapping-multichain.json" ]] && command -v jq &>/dev/null && jq -e '.pairs | type == "array"' "$PROJECT_ROOT/config/token-mapping-multichain.json" &>/dev/null; then log_ok "Token mapping: using config/token-mapping-multichain.json (relay fallback)" else log_warn "Optional config/token-mapping.json not found (relay uses fallback mapping)" fi if [[ -f "$PROJECT_ROOT/config/token-mapping-multichain.json" ]]; then log_ok "Found: config/token-mapping-multichain.json" if command -v jq &>/dev/null; then if jq -e '.pairs | type == "array"' "$PROJECT_ROOT/config/token-mapping-multichain.json" &>/dev/null; then log_ok "token-mapping-multichain.json: valid JSON with .pairs array" else log_err "token-mapping-multichain.json: invalid or missing .pairs array" ERRORS=$((ERRORS + 1)) fi fi fi [[ -f "$PROJECT_ROOT/config/smart-contracts-master.json" ]] && log_ok "Found: config/smart-contracts-master.json" || true # Token lists (Uniswap format): validate structure if present for list in token-lists/lists/dbis-138.tokenlist.json token-lists/lists/cronos.tokenlist.json token-lists/lists/all-mainnet.tokenlist.json; do if [[ -f "$PROJECT_ROOT/$list" ]] && command -v jq &>/dev/null; then if jq -e '(.tokens | type == "array") and (.tokens | length > 0)' "$PROJECT_ROOT/$list" &>/dev/null; then log_ok "Token list valid: $list" else log_err "Token list invalid or empty: $list" ERRORS=$((ERRORS + 1)) fi fi done # DUAL_CHAIN config (explorer deploy source) if [[ -f "$PROJECT_ROOT/explorer-monorepo/backend/api/rest/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json" ]] && command -v jq &>/dev/null; then if jq -e '(.tokens | type == "array") and (.tokens | length > 0)' "$PROJECT_ROOT/explorer-monorepo/backend/api/rest/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json" &>/dev/null; then log_ok "DUAL_CHAIN_TOKEN_LIST valid" else log_err "DUAL_CHAIN_TOKEN_LIST invalid or empty" ERRORS=$((ERRORS + 1)) fi fi fi if [[ -n "$OPTIONAL_ENV" ]]; then for v in $OPTIONAL_ENV; do check_env "$v" || true done fi if [[ $ERRORS -gt 0 ]]; then log_err "Validation failed with $ERRORS error(s). Set VALIDATE_REQUIRED_FILES='path1 path2' to require specific files." exit 1 fi log_ok "Validation passed." exit 0