2026-02-12 15:46:57 -08:00
#!/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)
2026-02-21 15:46:06 -08:00
# Usage: ./scripts/validation/validate-config-files.sh [--dry-run]
# --dry-run Print what would be validated and exit 0 (no file checks).
2026-02-12 15:46:57 -08:00
set -euo pipefail
SCRIPT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " && pwd ) "
PROJECT_ROOT = " $( cd " $SCRIPT_DIR /../.. " && pwd ) "
2026-02-21 15:46:06 -08:00
DRY_RUN = false
for a in " $@ " ; do [ [ " $a " = = "--dry-run" ] ] && DRY_RUN = true && break; done
2026-02-12 15:46:57 -08:00
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"
2026-03-02 11:37:34 -08:00
# Optional env vars to warn if missing (default empty = no warnings; set VALIDATE_OPTIONAL_ENV for Proxmox API checks)
OPTIONAL_ENV = " ${ VALIDATE_OPTIONAL_ENV :- } "
2026-02-12 15:46:57 -08:00
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
}
2026-02-21 15:46:06 -08:00
if $DRY_RUN ; then
echo "=== Validation (--dry-run: would check) ==="
2026-03-02 11:37:34 -08:00
echo " REQUIRED_FILES: ${ REQUIRED_FILES :- <default : config/ip-addresses.conf, .env.example, token-mapping*.json> } "
echo " OPTIONAL_ENV: ${ OPTIONAL_ENV :- <empty; set VALIDATE_OPTIONAL_ENV for Proxmox API vars> } "
2026-02-21 15:46:06 -08:00
exit 0
fi
2026-02-12 15:46:57 -08:00
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
2026-02-21 15:46:06 -08:00
# 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
2026-03-02 11:37:34 -08:00
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)"
2026-02-21 15:46:06 -08:00
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
2026-03-02 11:37:34 -08:00
# 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
2026-02-12 15:46:57 -08:00
fi
2026-03-02 11:37:34 -08:00
if [ [ -n " $OPTIONAL_ENV " ] ] ; then
for v in $OPTIONAL_ENV ; do
check_env " $v " || true
done
fi
2026-02-12 15:46:57 -08:00
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