set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
readonly ONTOLOGY_DIR="${PROJECT_ROOT}/ontologies"
readonly GENERATED_DIR="${PROJECT_ROOT}/generated"
readonly LOG_DIR="${PROJECT_ROOT}/logs"
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly CYAN='\033[0;36m'
readonly NC='\033[0m'
DRY_RUN=false
AUDIT=true
VERBOSE=false
mkdir -p "${LOG_DIR}"
print_pass() { echo -e "${GREEN}✅ PASS${NC}: $*"; }
print_fail() { echo -e "${RED}❌ FAIL${NC}: $*"; }
print_info() { echo -e "${BLUE}ℹ️ INFO${NC}: $*"; }
print_warn() { echo -e "${YELLOW}⚠️ WARN${NC}: $*"; }
print_step() { echo -e "${CYAN}▶${NC} $*"; }
usage() {
cat << 'EOF'
ln_ctrl Run Script - Full Sync and Verification
Executes the complete ggen sync pipeline (μ₁-μ₅) followed by verification.
Usage: ./run.sh [options]
Options:
--dry-run Preview changes without executing
--no-audit Skip audit trail generation
-v, --verbose Enable verbose output
-h, --help Show this help message
Examples:
./run.sh # Full sync with audit
./run.sh --dry-run # Preview changes
./run.sh --verbose # Detailed output
Exit codes:
0 - Success (sync + verification passed)
1 - Failure (sync or verification failed)
2 - Error (invalid input, missing dependencies)
EOF
}
check_dependencies() {
print_step "Checking dependencies..."
local missing=0
if ! command -v ggen &> /dev/null; then
print_fail "ggen not found in PATH"
((missing++))
fi
if ! command -v cargo &> /dev/null; then
print_fail "cargo not found in PATH"
((missing++))
fi
if [[ $missing -gt 0 ]]; then
print_fail "Missing ${missing} required dependencies"
return 1
fi
print_pass "All dependencies available"
return 0
}
validate_ontology() {
print_step "Validating ontology files..."
if [[ ! -d "${ONTOLOGY_DIR}" ]]; then
print_fail "Ontology directory not found: ${ONTOLOGY_DIR}"
return 1
fi
local ttl_files
ttl_files=$(find "${ONTOLOGY_DIR}" -name "*.ttl" 2>/dev/null | wc -l)
if [[ $ttl_files -eq 0 ]]; then
print_fail "No .ttl files found in ${ONTOLOGY_DIR}"
return 1
fi
print_pass "Found ${ttl_files} ontology files"
if ggen validate --help &> /dev/null; then
for ttl_file in "${ONTOLOGY_DIR}"/*.ttl; do
if [[ -f "$ttl_file" ]]; then
if [[ "$VERBOSE" == "true" ]]; then
print_info "Validating $(basename "$ttl_file")..."
fi
if ! ggen validate "$ttl_file" > /dev/null 2>&1; then
print_warn "SHACL validation failed for $(basename "$ttl_file")"
fi
fi
done
fi
return 0
}
run_sync() {
print_step "Running ggen sync (μ₁-μ₅ pipeline)..."
local sync_args=()
if [[ "$DRY_RUN" == "true" ]]; then
sync_args+=("--dry_run" "true")
fi
if [[ "$AUDIT" == "true" ]]; then
sync_args+=("--audit" "true")
fi
local log_file="${LOG_DIR}/sync-$(date +%Y%m%d-%H%M%S).log"
print_info "Command: ggen sync ${sync_args[*]}"
print_info "Log: ${log_file}"
if [[ "$VERBOSE" == "true" ]]; then
if ggen sync "${sync_args[@]}" 2>&1 | tee "$log_file"; then
print_pass "Sync completed successfully"
return 0
else
print_fail "Sync failed (see ${log_file})"
return 1
fi
else
if ggen sync "${sync_args[@]}" > "$log_file" 2>&1; then
print_pass "Sync completed successfully"
return 0
else
print_fail "Sync failed (see ${log_file})"
cat "$log_file"
return 1
fi
fi
}
run_verification() {
print_step "Running verification..."
local verify_script="${SCRIPT_DIR}/verify.sh"
if [[ ! -f "$verify_script" ]]; then
print_warn "Verification script not found: ${verify_script}"
return 0
fi
if [[ ! -x "$verify_script" ]]; then
chmod +x "$verify_script"
fi
if bash "$verify_script"; then
print_pass "Verification completed successfully"
return 0
else
print_fail "Verification failed"
return 1
fi
}
print_summary() {
local sync_status="$1"
local verify_status="$2"
echo ""
echo "=============================================="
echo "ln_ctrl Run Summary"
echo "=============================================="
echo "Project: ${PROJECT_ROOT}"
echo "Timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "Dry Run: ${DRY_RUN}"
echo "Audit: ${AUDIT}"
echo "----------------------------------------------"
if [[ "$sync_status" -eq 0 ]]; then
echo -e "Sync: ${GREEN}✅ PASS${NC}"
else
echo -e "Sync: ${RED}❌ FAIL${NC}"
fi
if [[ "$verify_status" -eq 0 ]]; then
echo -e "Verification: ${GREEN}✅ PASS${NC}"
else
echo -e "Verification: ${RED}❌ FAIL${NC}"
fi
echo "=============================================="
if [[ "$sync_status" -eq 0 ]] && [[ "$verify_status" -eq 0 ]]; then
echo -e "${GREEN}RESULT: SUCCESS${NC}"
echo ""
return 0
else
echo -e "${RED}RESULT: FAILURE${NC}"
echo ""
return 1
fi
}
main() {
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run)
DRY_RUN=true
shift
;;
--no-audit)
AUDIT=false
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 2
;;
esac
done
echo ""
echo "=============================================="
echo "ln_ctrl Run - Full Sync and Verification"
echo "=============================================="
echo "Formula: A = μ(O)"
echo "Pipeline: μ₁ → μ₂ → μ₃ → μ₄ → μ₅"
echo "----------------------------------------------"
echo ""
local sync_status=0
local verify_status=0
if ! check_dependencies; then
exit 2
fi
if ! validate_ontology; then
exit 2
fi
if ! run_sync; then
sync_status=1
fi
if [[ "$sync_status" -eq 0 ]] && [[ "$DRY_RUN" == "false" ]]; then
if ! run_verification; then
verify_status=1
fi
else
if [[ "$DRY_RUN" == "true" ]]; then
print_info "Skipping verification (dry-run mode)"
else
print_warn "Skipping verification (sync failed)"
fi
verify_status=0 fi
print_summary "$sync_status" "$verify_status"
}
main "$@"