Adds interpreter, JS compilation, and C compilation checks for all examples, showcase programs, standard examples, and projects (113 total checks). Skip lists exclude programs requiring unsupported effects or interactive I/O. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
212 lines
7.5 KiB
Bash
Executable File
212 lines
7.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Lux Full Validation Script
|
|
# Runs all checks: Rust tests, package tests, type checking, example compilation.
|
|
# Run after every committable change to ensure no regressions.
|
|
|
|
# cd to repo root (directory containing this script's parent)
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
cd "$SCRIPT_DIR/.."
|
|
|
|
LUX="$(pwd)/target/release/lux"
|
|
PACKAGES_DIR="$(pwd)/../packages"
|
|
PROJECTS_DIR="$(pwd)/projects"
|
|
EXAMPLES_DIR="$(pwd)/examples"
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
CYAN='\033[0;36m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m'
|
|
|
|
FAILED=0
|
|
TOTAL=0
|
|
|
|
step() {
|
|
TOTAL=$((TOTAL + 1))
|
|
printf "${CYAN}[%d]${NC} %s... " "$TOTAL" "$1"
|
|
}
|
|
|
|
ok() { printf "${GREEN}ok${NC} %s\n" "${1:-}"; }
|
|
fail() { printf "${RED}FAIL${NC} %s\n" "${1:-}"; FAILED=$((FAILED + 1)); }
|
|
|
|
# --- Rust checks ---
|
|
step "cargo check"
|
|
if nix develop --command cargo check 2>/dev/null; then ok; else fail; fi
|
|
|
|
step "cargo test"
|
|
OUTPUT=$(nix develop --command cargo test 2>&1 || true)
|
|
RESULT=$(echo "$OUTPUT" | grep "test result:" || echo "no result")
|
|
if echo "$RESULT" | grep -q "0 failed"; then ok "$RESULT"; else fail "$RESULT"; fi
|
|
|
|
# --- Build release binary ---
|
|
step "cargo build --release"
|
|
if nix develop --command cargo build --release 2>/dev/null; then ok; else fail; fi
|
|
|
|
# --- Package tests ---
|
|
for pkg in path frontmatter xml rss markdown; do
|
|
PKG_DIR="$PACKAGES_DIR/$pkg"
|
|
if [ -d "$PKG_DIR" ]; then
|
|
step "lux test ($pkg)"
|
|
OUTPUT=$(cd "$PKG_DIR" && "$LUX" test 2>&1 || true)
|
|
RESULT=$(echo "$OUTPUT" | grep "passed" | tail -1 || echo "no result")
|
|
if echo "$RESULT" | grep -q "passed"; then ok "$RESULT"; else fail "$RESULT"; fi
|
|
fi
|
|
done
|
|
|
|
# --- Lux check on packages ---
|
|
for pkg in path frontmatter xml rss markdown; do
|
|
PKG_DIR="$PACKAGES_DIR/$pkg"
|
|
if [ -d "$PKG_DIR" ]; then
|
|
step "lux check ($pkg)"
|
|
OUTPUT=$(cd "$PKG_DIR" && "$LUX" check 2>&1 || true)
|
|
RESULT=$(echo "$OUTPUT" | grep "passed" | tail -1 || echo "no result")
|
|
if echo "$RESULT" | grep -q "passed"; then ok; else fail "$RESULT"; fi
|
|
fi
|
|
done
|
|
|
|
# --- Project checks ---
|
|
for proj_dir in "$PROJECTS_DIR"/*/; do
|
|
proj=$(basename "$proj_dir")
|
|
if [ -f "$proj_dir/main.lux" ]; then
|
|
step "lux check (project: $proj)"
|
|
OUTPUT=$("$LUX" check "$proj_dir/main.lux" 2>&1 || true)
|
|
if echo "$OUTPUT" | grep -qi "error"; then fail; else ok; fi
|
|
fi
|
|
# Check any standalone .lux files in the project
|
|
for lux_file in "$proj_dir"/*.lux; do
|
|
[ -f "$lux_file" ] || continue
|
|
fname=$(basename "$lux_file")
|
|
[ "$fname" = "main.lux" ] && continue
|
|
step "lux check (project: $proj/$fname)"
|
|
OUTPUT=$("$LUX" check "$lux_file" 2>&1 || true)
|
|
if echo "$OUTPUT" | grep -qi "error"; then fail; else ok; fi
|
|
done
|
|
done
|
|
|
|
# === Compilation & Interpreter Checks ===
|
|
|
|
# --- Interpreter: examples ---
|
|
# Skip: http_api, http, http_router, http_server (network), postgres_demo (db),
|
|
# random, property_testing (Random effect), shell (Process), json (File I/O),
|
|
# file_io (File I/O), test_math, test_lists (Test effect), stress_shared_rc,
|
|
# test_rc_comparison (internal tests), modules/* (need cwd)
|
|
INTERP_SKIP="http_api http http_router http_server postgres_demo random property_testing shell json file_io test_math test_lists stress_shared_rc test_rc_comparison"
|
|
for f in "$EXAMPLES_DIR"/*.lux; do
|
|
name=$(basename "$f" .lux)
|
|
skip=false
|
|
for s in $INTERP_SKIP; do [ "$name" = "$s" ] && skip=true; done
|
|
$skip && continue
|
|
step "interpreter (examples/$name)"
|
|
if timeout 10 "$LUX" "$f" >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- Interpreter: examples/standard ---
|
|
# Skip: guessing_game (reads stdin)
|
|
for f in "$EXAMPLES_DIR"/standard/*.lux; do
|
|
[ -f "$f" ] || continue
|
|
name=$(basename "$f" .lux)
|
|
[ "$name" = "guessing_game" ] && continue
|
|
step "interpreter (standard/$name)"
|
|
if timeout 10 "$LUX" "$f" >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- Interpreter: examples/showcase ---
|
|
# Skip: task_manager (parse error in current version)
|
|
for f in "$EXAMPLES_DIR"/showcase/*.lux; do
|
|
[ -f "$f" ] || continue
|
|
name=$(basename "$f" .lux)
|
|
[ "$name" = "task_manager" ] && continue
|
|
step "interpreter (showcase/$name)"
|
|
if timeout 10 "$LUX" "$f" >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- Interpreter: projects ---
|
|
# Skip: guessing-game (Random), rest-api (HttpServer)
|
|
PROJ_INTERP_SKIP="guessing-game rest-api"
|
|
for proj_dir in "$PROJECTS_DIR"/*/; do
|
|
proj=$(basename "$proj_dir")
|
|
[ -f "$proj_dir/main.lux" ] || continue
|
|
skip=false
|
|
for s in $PROJ_INTERP_SKIP; do [ "$proj" = "$s" ] && skip=true; done
|
|
$skip && continue
|
|
step "interpreter (project: $proj)"
|
|
if timeout 10 "$LUX" "$proj_dir/main.lux" >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- JS compilation: examples ---
|
|
# Skip files that fail JS compilation (unsupported features)
|
|
JS_SKIP="http_api http http_router postgres_demo property_testing json test_lists test_rc_comparison"
|
|
for f in "$EXAMPLES_DIR"/*.lux; do
|
|
name=$(basename "$f" .lux)
|
|
skip=false
|
|
for s in $JS_SKIP; do [ "$name" = "$s" ] && skip=true; done
|
|
$skip && continue
|
|
step "compile JS (examples/$name)"
|
|
if "$LUX" compile "$f" --target js -o /tmp/lux_validate.js >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- JS compilation: examples/standard ---
|
|
# Skip: stdlib_demo (uses String.toUpper not in JS backend)
|
|
for f in "$EXAMPLES_DIR"/standard/*.lux; do
|
|
[ -f "$f" ] || continue
|
|
name=$(basename "$f" .lux)
|
|
[ "$name" = "stdlib_demo" ] && continue
|
|
step "compile JS (standard/$name)"
|
|
if "$LUX" compile "$f" --target js -o /tmp/lux_validate.js >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- JS compilation: examples/showcase ---
|
|
# Skip: task_manager (unsupported features)
|
|
for f in "$EXAMPLES_DIR"/showcase/*.lux; do
|
|
[ -f "$f" ] || continue
|
|
name=$(basename "$f" .lux)
|
|
[ "$name" = "task_manager" ] && continue
|
|
step "compile JS (showcase/$name)"
|
|
if "$LUX" compile "$f" --target js -o /tmp/lux_validate.js >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- JS compilation: projects ---
|
|
# Skip: json-parser, rest-api (unsupported features)
|
|
JS_PROJ_SKIP="json-parser rest-api"
|
|
for proj_dir in "$PROJECTS_DIR"/*/; do
|
|
proj=$(basename "$proj_dir")
|
|
[ -f "$proj_dir/main.lux" ] || continue
|
|
skip=false
|
|
for s in $JS_PROJ_SKIP; do [ "$proj" = "$s" ] && skip=true; done
|
|
$skip && continue
|
|
step "compile JS (project: $proj)"
|
|
if "$LUX" compile "$proj_dir/main.lux" --target js -o /tmp/lux_validate.js >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- C compilation: examples ---
|
|
# Only compile examples known to work with C backend
|
|
C_EXAMPLES="hello factorial pipelines tailcall jit_test"
|
|
for name in $C_EXAMPLES; do
|
|
f="$EXAMPLES_DIR/$name.lux"
|
|
[ -f "$f" ] || continue
|
|
step "compile C (examples/$name)"
|
|
if "$LUX" compile "$f" -o /tmp/lux_validate_bin >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- C compilation: examples/standard ---
|
|
C_STD_EXAMPLES="hello_world factorial fizzbuzz primes guessing_game"
|
|
for name in $C_STD_EXAMPLES; do
|
|
f="$EXAMPLES_DIR/standard/$name.lux"
|
|
[ -f "$f" ] || continue
|
|
step "compile C (standard/$name)"
|
|
if "$LUX" compile "$f" -o /tmp/lux_validate_bin >/dev/null 2>&1; then ok; else fail; fi
|
|
done
|
|
|
|
# --- Cleanup ---
|
|
rm -f /tmp/lux_validate.js /tmp/lux_validate_bin
|
|
|
|
# --- Summary ---
|
|
printf "\n${BOLD}═══ Validation Summary ═══${NC}\n"
|
|
if [ $FAILED -eq 0 ]; then
|
|
printf "${GREEN}All %d checks passed.${NC}\n" "$TOTAL"
|
|
else
|
|
printf "${RED}%d/%d checks failed.${NC}\n" "$FAILED" "$TOTAL"
|
|
exit 1
|
|
fi
|