feat(@projects/@magic-civilization): ✨ update objective completion statuses
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
251008327c
commit
38c5305787
10 changed files with 479 additions and 13 deletions
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
| Status | Count |
|
||||
|---|---|
|
||||
| ✅ done | 7 |
|
||||
| 🟡 partial | 26 |
|
||||
| ✅ done | 4 |
|
||||
| 🟡 partial | 29 |
|
||||
| 🔴 stub | 0 |
|
||||
| ❌ missing | 7 |
|
||||
| ⚫ oos | 4 |
|
||||
|
|
@ -25,20 +25,20 @@
|
|||
| [p0-02](p0-02-clan-personalities.md) | 🟡 partial | Five AI clan personalities drive distinct playstyles | 2026-04-17 |
|
||||
| [p0-03](p0-03-pvp-in-turn.md) | 🟡 partial | PvP combat resolved inside the authoritative turn processor | 2026-04-17 |
|
||||
| [p0-04](p0-04-wonder-tracking.md) | 🟡 partial | World wonder tracking in PlayerState and score victory | 2026-04-17 |
|
||||
| [p0-05](p0-05-culture-and-borders.md) | ✅ done | Culture generation and border expansion | 2026-04-17 |
|
||||
| [p0-05](p0-05-culture-and-borders.md) | 🟡 partial | Culture generation and border expansion | 2026-04-17 |
|
||||
| [p0-06](p0-06-economy-integration.md) | 🟡 partial | Fold gold income / upkeep / improvement yields into turn loop | 2026-04-17 |
|
||||
| [p0-07](p0-07-tech-research-costs.md) | 🟡 partial | Tech research costs and science pool pacing | 2026-04-17 |
|
||||
| [p0-08](p0-08-domination-victory.md) | 🟡 partial | Domination victory path in mc-turn::victory | 2026-04-17 |
|
||||
| [p0-09](p0-09-ui-completeness.md) | 🟡 partial | City-screen UI completeness (citizen assign, queue controls, promotion picker) | 2026-04-17 |
|
||||
| [p0-09](p0-09-ui-completeness.md) | ✅ done | City-screen UI completeness (citizen assign, queue controls, promotion picker) | 2026-04-16 |
|
||||
| [p0-10](p0-10-completion-stability.md) | 🟡 partial | Game-completion stability — ≥7/10 seeds declare a winner | 2026-04-17 |
|
||||
| [p0-11](p0-11-mystery-item-authoring.md) | ✅ done | Author the four T8–T10 mystery item drops | 2026-04-16 |
|
||||
| [p0-12](p0-12-save-load-autosave.md) | ✅ done | Save / load + autosave on quit | 2026-04-16 |
|
||||
| [p0-12](p0-12-save-load-autosave.md) | 🟡 partial | Save / load + autosave on quit | 2026-04-16 |
|
||||
| [p0-13](p0-13-fog-of-war-exploration.md) | ✅ done | Fog of war and exploration / scout loop | 2026-04-16 |
|
||||
| [p0-14](p0-14-map-generation-balanced-starts.md) | ✅ done | Map generation, resource placement, and balanced fair starts | 2026-04-17 |
|
||||
| [p0-14](p0-14-map-generation-balanced-starts.md) | 🟡 partial | Map generation, resource placement, and balanced fair starts | 2026-04-17 |
|
||||
| [p0-15](p0-15-happiness-golden-age.md) | 🟡 partial | Happiness pool and Golden Age mechanics end-to-end | 2026-04-17 |
|
||||
| [p0-16](p0-16-worker-improvement-loop.md) | 🟡 partial | Worker / tile-improvement build loop | 2026-04-17 |
|
||||
| [p0-17](p0-17-wild-creature-lair-loop.md) | 🟡 partial | Wild creature and lair clearing loop | 2026-04-17 |
|
||||
| [p0-18](p0-18-strategic-resource-gate.md) | ✅ done | Strategic resources gate unit production (empire ledger) | 2026-04-16 |
|
||||
| [p0-18](p0-18-strategic-resource-gate.md) | 🟡 partial | Strategic resources gate unit production (empire ledger) | 2026-04-16 |
|
||||
| [p0-19](p0-19-biome-economy-integration.md) | ✅ done | Biome-driven collectibles → tile yields → happiness end-to-end | 2026-04-17 |
|
||||
|
||||
## P1 — Ship-readiness
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
id: p0-05
|
||||
title: Culture generation and border expansion
|
||||
priority: p0
|
||||
status: done
|
||||
status: partial
|
||||
scope: game1
|
||||
updated_at: 2026-04-17
|
||||
evidence:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
id: p0-12
|
||||
title: Save / load + autosave on quit
|
||||
priority: p0
|
||||
status: done
|
||||
status: partial
|
||||
scope: game1
|
||||
updated_at: 2026-04-16
|
||||
evidence:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
id: p0-14
|
||||
title: Map generation, resource placement, and balanced fair starts
|
||||
priority: p0
|
||||
status: done
|
||||
status: partial
|
||||
scope: game1
|
||||
updated_at: 2026-04-17
|
||||
evidence:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
id: p0-18
|
||||
title: Strategic resources gate unit production (empire ledger)
|
||||
priority: p0
|
||||
status: done
|
||||
status: partial
|
||||
scope: game1
|
||||
updated_at: 2026-04-16
|
||||
evidence:
|
||||
|
|
|
|||
23
CLAUDE.md
23
CLAUDE.md
|
|
@ -403,6 +403,29 @@ A phase is NOT done until:
|
|||
|
||||
Code exists ≠ code works. Tests pass ≠ features render. Lint clean ≠ visually correct.
|
||||
|
||||
## Objective Status Integrity (MANDATORY)
|
||||
|
||||
`.project/objectives/*.md` frontmatter `status` MUST match what the prose says and what the acceptance bullets verify. This rule exists because the dashboard has previously carried ✅ done items whose own `## Summary` admitted the feature was a 1-line TODO stub, or whose acceptance criteria cited failing tests. That makes the dashboard an unreliable instrument and sends the team chasing shore-up work for items already marked complete.
|
||||
|
||||
Never set `status: done` if ANY of:
|
||||
- The file's own `## Summary` admits open gaps, missing wiring, or remaining work.
|
||||
- Any bullet in `## Acceptance` is not demonstrably true (test green, feature visible in a reviewed proof screenshot, data populated, build queue path invoked, etc.).
|
||||
- Any test listed under `evidence:` is failing, skipped, or does not exist on disk.
|
||||
- The underlying Rust crate is a stub (e.g. `mc-culture/src/lib.rs` = `// TODO`).
|
||||
|
||||
Allowed transitions:
|
||||
- 🔴 stub → 🟡 partial → ✅ done. Never skip 🟡 partial. If you aren't sure every acceptance bullet passes, mark 🟡 partial.
|
||||
- Downgrade freely: flip ✅ done back to 🟡 partial the moment a regression or audit exposes a gap. Don't protect the status.
|
||||
- `❌ missing` only when no code has been written yet AND no evidence file exists.
|
||||
|
||||
Ritual when closing an objective to ✅ done:
|
||||
1. Read the file's own `## Acceptance` list. For each bullet, cite the exact file path / test name / passing command that proves it, in the commit message or PR body.
|
||||
2. If a bullet can't be cited, stay at 🟡 partial and edit the Summary to list the specific remaining blocker.
|
||||
3. Run `tools/objectives-report.py` to regenerate `README.md`; verify the totals changed as expected.
|
||||
4. If a Phase Gate proof scene is required for the feature (see above), link the screenshot in the evidence list.
|
||||
|
||||
> "Done" means every acceptance bullet has been verified in this repo, today. Not "code exists." Not "lint passes." Not "a test file exists" — the test has to pass, and the acceptance has to match.
|
||||
|
||||
## Atomic Porting Protocol
|
||||
|
||||
This project is rebuilt milestone-by-milestone from a reference implementation. **Only port what the current milestone requires.**
|
||||
|
|
|
|||
409
scripts/dev-setup/linux.sh
Executable file
409
scripts/dev-setup/linux.sh
Executable file
|
|
@ -0,0 +1,409 @@
|
|||
#!/usr/bin/env bash
|
||||
# Linux dev environment setup for Magic Civilization
|
||||
# Tuned for Bluefin / Silverblue / Fedora-atomic (no system dnf on immutable base)
|
||||
# Fallbacks for traditional Fedora (dnf) and Debian/Ubuntu (apt)
|
||||
# Usage: ./scripts/dev-setup/linux.sh [--skip-godot] [--skip-rust]
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
DIM='\033[2m'
|
||||
NC='\033[0m'
|
||||
|
||||
SKIP_GODOT=false
|
||||
SKIP_RUST=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--skip-godot) SKIP_GODOT=true ;;
|
||||
--skip-rust) SKIP_RUST=true ;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--skip-godot] [--skip-rust]"
|
||||
echo " --skip-godot Skip Flatpak Godot installation"
|
||||
echo " --skip-rust Skip Rust toolchain installation"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
ok() { echo -e " ${GREEN}OK${NC} $1"; }
|
||||
skip() { echo -e " ${DIM}SKIP${NC} $1"; }
|
||||
info() { echo -e " ${BLUE}...${NC} $1"; }
|
||||
warn() { echo -e " ${YELLOW}WARN${NC} $1"; }
|
||||
fail() { echo -e " ${RED}FAIL${NC} $1"; }
|
||||
|
||||
INSTALLED=()
|
||||
ALREADY=()
|
||||
SKIPPED=()
|
||||
FAILED=()
|
||||
|
||||
# ── Distro detection ─────────────────────────────────────────────────
|
||||
# DISTRO_FAMILY: one of {atomic, fedora, debian, other}
|
||||
# PKG_MGR: package manager command (or "" on atomic)
|
||||
# IS_ATOMIC: true/false — immutable base (Bluefin/Silverblue/Kinoite)
|
||||
DISTRO_FAMILY="other"
|
||||
PKG_MGR=""
|
||||
IS_ATOMIC=false
|
||||
|
||||
if [ -r /etc/os-release ]; then
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
case "${ID:-}${ID_LIKE:-}" in
|
||||
*bluefin*|*silverblue*|*kinoite*|*ublue*|*coreos*)
|
||||
DISTRO_FAMILY="atomic"; IS_ATOMIC=true ;;
|
||||
esac
|
||||
# rpm-ostree presence is a stronger signal for atomic systems
|
||||
if command -v rpm-ostree &>/dev/null && [ "$IS_ATOMIC" != "true" ]; then
|
||||
if rpm-ostree status --json 2>/dev/null | grep -q '"booted"'; then
|
||||
DISTRO_FAMILY="atomic"; IS_ATOMIC=true
|
||||
fi
|
||||
fi
|
||||
if [ "$IS_ATOMIC" != "true" ]; then
|
||||
case "${ID:-}${ID_LIKE:-}" in
|
||||
*fedora*|*rhel*|*centos*) DISTRO_FAMILY="fedora"; PKG_MGR="dnf" ;;
|
||||
*debian*|*ubuntu*) DISTRO_FAMILY="debian"; PKG_MGR="apt-get" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
check_or_install() {
|
||||
local name="$1"
|
||||
local check_cmd="$2"
|
||||
local install_cmd="$3"
|
||||
local skip_flag="${4:-false}"
|
||||
|
||||
if [ "$skip_flag" = "true" ]; then
|
||||
skip "$name (--skip flag)"
|
||||
SKIPPED+=("$name")
|
||||
return 0
|
||||
fi
|
||||
|
||||
if eval "$check_cmd" &>/dev/null; then
|
||||
ok "$name (already installed)"
|
||||
ALREADY+=("$name")
|
||||
return 0
|
||||
fi
|
||||
|
||||
info "Installing $name..."
|
||||
if eval "$install_cmd"; then
|
||||
ok "$name"
|
||||
INSTALLED+=("$name")
|
||||
else
|
||||
fail "$name"
|
||||
FAILED+=("$name")
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Wrapper that chooses the right system install command for the current distro.
|
||||
# Usage: sys_install <fedora-pkg> <debian-pkg>
|
||||
# On atomic systems, prints a warn+skip (system packages require reboot layering).
|
||||
sys_install() {
|
||||
local fedora_pkg="$1"
|
||||
local debian_pkg="$2"
|
||||
if [ "$IS_ATOMIC" = "true" ]; then
|
||||
warn "system package install skipped on atomic distro (would require rpm-ostree + reboot): $fedora_pkg"
|
||||
return 1
|
||||
fi
|
||||
case "$DISTRO_FAMILY" in
|
||||
fedora) sudo dnf install -y "$fedora_pkg" ;;
|
||||
debian) sudo apt-get update && sudo apt-get install -y "$debian_pkg" ;;
|
||||
*) warn "unknown distro — cannot auto-install $fedora_pkg"; return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Magic Civilization — Linux Dev Setup${NC}"
|
||||
echo -e "${DIM}distro: ${ID:-unknown} ${VERSION:-}${NC}"
|
||||
echo -e "${DIM}family: $DISTRO_FAMILY atomic: $IS_ATOMIC pkg-mgr: ${PKG_MGR:-n/a}${NC}"
|
||||
echo -e "${DIM}Flatpak Godot + Rust + wasm-pack + gdtoolkit + pnpm + cargo extras${NC}"
|
||||
echo ""
|
||||
|
||||
# ── Flatpak (and Flathub remote) ─────────────────────────────────────
|
||||
echo -e "${BLUE}[1/7] Flatpak${NC}"
|
||||
if command -v flatpak &>/dev/null; then
|
||||
ok "flatpak ($(flatpak --version | awk '{print $NF}'))"
|
||||
ALREADY+=("flatpak")
|
||||
else
|
||||
info "Installing flatpak..."
|
||||
if sys_install flatpak flatpak; then
|
||||
ok "flatpak"
|
||||
INSTALLED+=("flatpak")
|
||||
else
|
||||
fail "flatpak — install manually per your distro, then re-run"
|
||||
FAILED+=("flatpak")
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v flatpak &>/dev/null; then
|
||||
if flatpak remotes --user 2>/dev/null | grep -q flathub; then
|
||||
ok "flathub remote (user)"
|
||||
else
|
||||
info "Adding flathub user remote..."
|
||||
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
ok "flathub remote"
|
||||
INSTALLED+=("flathub-remote")
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Godot 4 (flatpak) ────────────────────────────────────────────────
|
||||
echo -e "${BLUE}[2/7] Godot 4 (flatpak)${NC}"
|
||||
if [ "$SKIP_GODOT" = "true" ]; then
|
||||
skip "Godot 4 (--skip-godot flag)"
|
||||
SKIPPED+=("godot")
|
||||
elif ! command -v flatpak &>/dev/null; then
|
||||
skip "Godot 4 (flatpak missing)"
|
||||
SKIPPED+=("godot")
|
||||
else
|
||||
if flatpak info --user org.godotengine.Godot &>/dev/null \
|
||||
|| flatpak info org.godotengine.Godot &>/dev/null; then
|
||||
ok "Godot 4 (flatpak, already installed)"
|
||||
ALREADY+=("godot")
|
||||
else
|
||||
info "Installing Godot flatpak (user scope)..."
|
||||
if flatpak install --user -y flathub org.godotengine.Godot; then
|
||||
ok "Godot 4 (flatpak)"
|
||||
INSTALLED+=("godot")
|
||||
else
|
||||
fail "Godot flatpak install"
|
||||
FAILED+=("godot")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── System build prereqs (only on mutable distros) ───────────────────
|
||||
echo -e "${BLUE}[2b] build prerequisites${NC}"
|
||||
if [ "$IS_ATOMIC" = "true" ]; then
|
||||
skip "build prereqs (atomic distro — install via toolbox/distrobox or ujust if missing)"
|
||||
SKIPPED+=("build-prereqs")
|
||||
else
|
||||
# pkg-config + openssl headers are needed for some cargo crates (cargo-deny, etc.)
|
||||
for pkg_pair in "pkg-config pkg-config" "openssl-devel libssl-dev" "gcc gcc"; do
|
||||
read -r fed deb <<<"$pkg_pair"
|
||||
bin="${fed%%-*}"
|
||||
if command -v "$bin" &>/dev/null || pkg-config --exists "$fed" 2>/dev/null; then
|
||||
ok "$fed"
|
||||
ALREADY+=("$fed")
|
||||
else
|
||||
info "Installing $fed..."
|
||||
if sys_install "$fed" "$deb"; then
|
||||
ok "$fed"
|
||||
INSTALLED+=("$fed")
|
||||
else
|
||||
warn "$fed — install manually if cargo builds fail"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ── Rust toolchain ───────────────────────────────────────────────────
|
||||
echo -e "${BLUE}[3/7] Rust toolchain${NC}"
|
||||
if [ "$SKIP_RUST" = "true" ]; then
|
||||
skip "Rust (--skip-rust flag)"
|
||||
SKIPPED+=("rust")
|
||||
else
|
||||
if command -v rustc &>/dev/null; then
|
||||
ok "Rust $(rustc --version | awk '{print $2}')"
|
||||
ALREADY+=("rust")
|
||||
else
|
||||
info "Installing Rust via rustup..."
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
||||
# shellcheck disable=SC1090
|
||||
source "$HOME/.cargo/env"
|
||||
ok "Rust $(rustc --version | awk '{print $2}')"
|
||||
INSTALLED+=("rust")
|
||||
fi
|
||||
|
||||
# Ensure rustup's shims are on PATH for the rest of this script
|
||||
if [ -f "$HOME/.cargo/env" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[3b] wasm32-unknown-unknown target${NC}"
|
||||
if rustup target list --installed | grep -q wasm32-unknown-unknown; then
|
||||
ok "wasm32 target"
|
||||
ALREADY+=("wasm32-target")
|
||||
else
|
||||
info "Adding wasm32-unknown-unknown target..."
|
||||
rustup target add wasm32-unknown-unknown
|
||||
ok "wasm32 target"
|
||||
INSTALLED+=("wasm32-target")
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[3c] x86_64-unknown-linux-gnu target${NC}"
|
||||
if rustup target list --installed | grep -q x86_64-unknown-linux-gnu; then
|
||||
ok "linux-gnu target"
|
||||
ALREADY+=("linux-gnu-target")
|
||||
else
|
||||
info "Adding x86_64-unknown-linux-gnu target..."
|
||||
rustup target add x86_64-unknown-linux-gnu
|
||||
ok "linux-gnu target"
|
||||
INSTALLED+=("linux-gnu-target")
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── wasm-pack ────────────────────────────────────────────────────────
|
||||
echo -e "${BLUE}[4/7] wasm-pack${NC}"
|
||||
if [ "$SKIP_RUST" = "true" ]; then
|
||||
skip "wasm-pack (--skip-rust flag)"
|
||||
SKIPPED+=("wasm-pack")
|
||||
else
|
||||
check_or_install "wasm-pack" \
|
||||
"command -v wasm-pack" \
|
||||
"cargo install wasm-pack"
|
||||
fi
|
||||
|
||||
# ── Python + gdtoolkit ───────────────────────────────────────────────
|
||||
echo -e "${BLUE}[5/7] gdtoolkit (gdlint + gdformat)${NC}"
|
||||
# On atomic, pip --user is the only writable path; regular distros same
|
||||
check_or_install "gdtoolkit" \
|
||||
"command -v gdlint" \
|
||||
"pip3 install --user gdtoolkit || pip3 install --break-system-packages --user gdtoolkit"
|
||||
|
||||
# Ensure ~/.local/bin is on PATH so gdlint is reachable
|
||||
if ! echo ":$PATH:" | grep -q ":$HOME/.local/bin:"; then
|
||||
warn "~/.local/bin not on PATH — gdlint may not be callable. Add: export PATH=\"\$HOME/.local/bin:\$PATH\""
|
||||
fi
|
||||
|
||||
# ── Node.js + pnpm ──────────────────────────────────────────────────
|
||||
echo -e "${BLUE}[6/7] Node.js${NC}"
|
||||
if command -v node &>/dev/null; then
|
||||
ok "Node $(node --version)"
|
||||
ALREADY+=("node")
|
||||
else
|
||||
if command -v fnm &>/dev/null; then
|
||||
info "Installing Node via fnm..."
|
||||
fnm install --lts
|
||||
# shellcheck disable=SC1090
|
||||
eval "$(fnm env --use-on-cd)"
|
||||
ok "Node $(node --version)"
|
||||
INSTALLED+=("node")
|
||||
elif [ "$IS_ATOMIC" = "true" ]; then
|
||||
info "Installing fnm (node version manager) first..."
|
||||
curl -fsSL https://fnm.vercel.app/install | bash
|
||||
# shellcheck disable=SC1090
|
||||
eval "$(fnm env --use-on-cd)" 2>/dev/null || true
|
||||
if command -v fnm &>/dev/null; then
|
||||
fnm install --lts
|
||||
eval "$(fnm env --use-on-cd)"
|
||||
ok "Node $(node --version) (via fnm)"
|
||||
INSTALLED+=("node")
|
||||
else
|
||||
fail "fnm install (restart shell and re-run, or install Node manually)"
|
||||
FAILED+=("node")
|
||||
fi
|
||||
else
|
||||
info "Installing Node..."
|
||||
if sys_install nodejs nodejs; then
|
||||
ok "Node $(node --version)"
|
||||
INSTALLED+=("node")
|
||||
else
|
||||
fail "Node install"
|
||||
FAILED+=("node")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[6b] pnpm${NC}"
|
||||
check_or_install "pnpm" \
|
||||
"command -v pnpm" \
|
||||
"npm install -g pnpm || (curl -fsSL https://get.pnpm.io/install.sh | sh -)"
|
||||
|
||||
# ── cargo extras: binstall + machete + deny + nextest + llvm-cov ─────
|
||||
if [ "$SKIP_RUST" != "true" ]; then
|
||||
echo -e "${BLUE}[6c] cargo-binstall${NC}"
|
||||
check_or_install "cargo-binstall" \
|
||||
"command -v cargo-binstall" \
|
||||
"curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash"
|
||||
|
||||
_cargo_install_tool() {
|
||||
local bin="$1"; local crate="${2:-$1}"
|
||||
if command -v cargo-binstall &>/dev/null; then
|
||||
check_or_install "$bin" "command -v $bin" "cargo binstall --no-confirm $crate"
|
||||
else
|
||||
check_or_install "$bin" "command -v $bin" "cargo install $crate"
|
||||
fi
|
||||
}
|
||||
echo -e "${BLUE}[6d] cargo-machete (dead-deps)${NC}"
|
||||
_cargo_install_tool cargo-machete
|
||||
echo -e "${BLUE}[6e] cargo-deny (security+licenses)${NC}"
|
||||
_cargo_install_tool cargo-deny
|
||||
echo -e "${BLUE}[6f] cargo-nextest (fast test runner)${NC}"
|
||||
_cargo_install_tool cargo-nextest
|
||||
echo -e "${BLUE}[6g] cargo-llvm-cov (coverage)${NC}"
|
||||
_cargo_install_tool cargo-llvm-cov
|
||||
fi
|
||||
|
||||
# ── Project dependencies ─────────────────────────────────────────────
|
||||
echo -e "${BLUE}[7/7] Project dependencies${NC}"
|
||||
if [ -f "$REPO_ROOT/pnpm-lock.yaml" ] && command -v pnpm &>/dev/null; then
|
||||
info "Running pnpm install..."
|
||||
if (cd "$REPO_ROOT" && pnpm install 2>&1); then
|
||||
ok "pnpm dependencies"
|
||||
else
|
||||
warn "pnpm install had errors (private registry packages may need VPN/auth)"
|
||||
fi
|
||||
else
|
||||
skip "pnpm install (no pnpm-lock.yaml or pnpm missing)"
|
||||
fi
|
||||
|
||||
# ── Verify ───────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
||||
echo -e "${BLUE} Verification${NC}"
|
||||
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
||||
|
||||
verify_cmd() {
|
||||
local label="$1"
|
||||
local cmd="$2"
|
||||
if eval "$cmd" &>/dev/null; then
|
||||
local version
|
||||
version=$(eval "$3" 2>/dev/null || echo "installed")
|
||||
echo -e " ${GREEN}OK${NC} $label ${DIM}($version)${NC}"
|
||||
else
|
||||
echo -e " ${RED}--${NC} $label"
|
||||
fi
|
||||
}
|
||||
|
||||
verify_cmd "flatpak" "command -v flatpak" "flatpak --version"
|
||||
verify_cmd "godot (flatpak)" "flatpak info --user org.godotengine.Godot || flatpak info org.godotengine.Godot" \
|
||||
"echo 'org.godotengine.Godot'"
|
||||
verify_cmd "rustc" "command -v rustc" "rustc --version"
|
||||
verify_cmd "cargo" "command -v cargo" "cargo --version"
|
||||
verify_cmd "wasm-pack" "command -v wasm-pack" "wasm-pack --version"
|
||||
verify_cmd "gdlint" "command -v gdlint" "gdlint --version 2>&1 || echo installed"
|
||||
verify_cmd "gdformat" "command -v gdformat" "gdformat --version 2>&1 || echo installed"
|
||||
verify_cmd "node" "command -v node" "node --version"
|
||||
verify_cmd "pnpm" "command -v pnpm" "pnpm --version"
|
||||
verify_cmd "cargo-binstall" "command -v cargo-binstall" "cargo-binstall --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-machete" "command -v cargo-machete" "cargo-machete --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-deny" "command -v cargo-deny" "cargo-deny --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-nextest" "command -v cargo-nextest" "cargo-nextest --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-llvm-cov" "command -v cargo-llvm-cov" "cargo-llvm-cov --version 2>&1 || echo installed"
|
||||
|
||||
# ── Summary ──────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
||||
echo -e "${BLUE} Summary${NC}"
|
||||
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
||||
[ ${#INSTALLED[@]} -gt 0 ] && echo -e " ${GREEN}Installed:${NC} ${INSTALLED[*]}"
|
||||
[ ${#ALREADY[@]} -gt 0 ] && echo -e " ${DIM}Already had:${NC} ${ALREADY[*]}"
|
||||
[ ${#SKIPPED[@]} -gt 0 ] && echo -e " ${YELLOW}Skipped:${NC} ${SKIPPED[*]}"
|
||||
[ ${#FAILED[@]} -gt 0 ] && echo -e " ${RED}Failed:${NC} ${FAILED[*]}"
|
||||
|
||||
if [ ${#FAILED[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo -e " ${RED}Some tools failed to install. Fix the errors above and re-run.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e " ${GREEN}Ready to go.${NC} Try:"
|
||||
echo -e " ${DIM}./run verify${NC} — full lint + test pipeline"
|
||||
echo -e " ${DIM}./run test:golden${NC} — cross-language golden-vector parity"
|
||||
echo -e " ${DIM}./run autoplay 1${NC} — single-seed 500-turn simulation"
|
||||
echo ""
|
||||
|
|
@ -171,6 +171,35 @@ check_or_install "pnpm" \
|
|||
"command -v pnpm" \
|
||||
"npm install -g pnpm"
|
||||
|
||||
# ── cargo extras: binstall + machete + deny + nextest + llvm-cov ─────
|
||||
# These back the ./run verify and ./run coverage pipelines. binstall
|
||||
# first so the rest can skip from-source cargo builds.
|
||||
if [ "$SKIP_RUST" != "true" ]; then
|
||||
echo -e "${BLUE}[6c] cargo-binstall${NC}"
|
||||
check_or_install "cargo-binstall" \
|
||||
"command -v cargo-binstall" \
|
||||
"curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash"
|
||||
|
||||
_cargo_install_tool() {
|
||||
# $1 = tool binary name (e.g. cargo-machete)
|
||||
# $2 = crate name to install (usually same)
|
||||
local bin="$1"; local crate="${2:-$1}"
|
||||
if command -v cargo-binstall &>/dev/null; then
|
||||
check_or_install "$bin" "command -v $bin" "cargo binstall --no-confirm $crate"
|
||||
else
|
||||
check_or_install "$bin" "command -v $bin" "cargo install $crate"
|
||||
fi
|
||||
}
|
||||
echo -e "${BLUE}[6d] cargo-machete (dead-deps)${NC}"
|
||||
_cargo_install_tool cargo-machete
|
||||
echo -e "${BLUE}[6e] cargo-deny (security+licenses)${NC}"
|
||||
_cargo_install_tool cargo-deny
|
||||
echo -e "${BLUE}[6f] cargo-nextest (fast test runner)${NC}"
|
||||
_cargo_install_tool cargo-nextest
|
||||
echo -e "${BLUE}[6g] cargo-llvm-cov (coverage)${NC}"
|
||||
_cargo_install_tool cargo-llvm-cov
|
||||
fi
|
||||
|
||||
# ── pnpm install ─────────────────────────────────────────────────────
|
||||
echo -e "${BLUE}[7/7] Project dependencies${NC}"
|
||||
if [ -f "$REPO_ROOT/pnpm-lock.yaml" ]; then
|
||||
|
|
@ -212,6 +241,10 @@ verify_cmd "gdlint" "command -v gdlint" "gdlint --version 2>&1 || echo 'i
|
|||
verify_cmd "gdformat" "command -v gdformat" "gdformat --version 2>&1 || echo 'installed'"
|
||||
verify_cmd "node" "command -v node" "node --version"
|
||||
verify_cmd "pnpm" "command -v pnpm" "pnpm --version"
|
||||
verify_cmd "cargo-machete" "command -v cargo-machete" "cargo-machete --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-deny" "command -v cargo-deny" "cargo-deny --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-nextest" "command -v cargo-nextest" "cargo-nextest --version 2>&1 || echo installed"
|
||||
verify_cmd "cargo-llvm-cov" "command -v cargo-llvm-cov" "cargo-llvm-cov --version 2>&1 || echo installed"
|
||||
|
||||
# ── Summary ──────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ cmd_tools_spritegen() {
|
|||
|
||||
cmd_setup() {
|
||||
case "$(uname -s)" in
|
||||
Darwin) "$REPO_ROOT/scripts/dev-setup/osx.sh" "$@" ;;
|
||||
Linux) echo -e "${RED}Linux setup not yet implemented${NC}"; exit 1 ;;
|
||||
Darwin) "$REPO_ROOT/scripts/dev-setup/osx.sh" "$@" ;;
|
||||
Linux) "$REPO_ROOT/scripts/dev-setup/linux.sh" "$@" ;;
|
||||
*) echo -e "${RED}Unsupported OS: $(uname -s)${NC}"; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ fi
|
|||
ALLOWLISTED_ERRORS=(
|
||||
"Parameter \"t\" is null" # headless viewport texture — no display
|
||||
"texture_2d_get" # same; appears in dummy storage callsite
|
||||
"resources still in use at exit" # Godot engine shutdown, not game logic
|
||||
)
|
||||
|
||||
_is_allowlisted() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue