The card hid Start now until the roster filled or the deadline elapsed, preventing groups from starting early with fewer players. Expose the existing start action for every unfinished caller-owned call, including scheduled calls before check-in. Keep check-in controls and launch only after core acceptance. Add rendered-card regressions for six-of-eight players, solo and scheduled starts, creator authority, terminal states, and unavailable local games. Use installed React packages for these tests without rewriting the app lockfile, and document the caller's control over start time. Test Plan: - `just frontend-test` -- passed, 107 tests including 8 rendered-card tests - `just test` -- passed, 797 Rust tests - `just clippy` -- passed with warnings denied - `just fmt` -- passed - `deno task build` -- passed TypeScript and Vite production build - `git diff --cached --check` -- passed
315 lines
15 KiB
Makefile
315 lines
15 KiB
Makefile
export RUSTFLAGS := "-C target-cpu=native"
|
|
export WEBKIT_DISABLE_COMPOSITING_MODE := "1"
|
|
export DOCKER_CONFIG := env_var_or_default("DOCKER_CONFIG", ".lanspread-peer-cli/docker-config")
|
|
|
|
set export
|
|
|
|
default: run
|
|
|
|
FIXTURE_CATALOG_SOURCE := "crates/lanspread-tauri-deno-ts/src-tauri/game.db"
|
|
FIXTURE_CATALOG_ROOT := "crates/lanspread-peer-cli/catalogs"
|
|
PRODUCTION_CATALOG_SOURCE := "crates/lanspread-tauri-deno-ts/src-tauri/game.db"
|
|
PRODUCTION_CATALOG_ROOT := "crates/lanspread-tauri-deno-ts/src-tauri/production-catalog"
|
|
PRODUCTION_CATALOG_DB := PRODUCTION_CATALOG_ROOT / "game.db"
|
|
PRODUCTION_MANIFEST_ROOT := PRODUCTION_CATALOG_ROOT / "manifests"
|
|
CATALOG_CACHE_STAMP := ".lanspread/catalog-cache/production.json"
|
|
LOCAL_CATALOG_ROOT := "crates/lanspread-tauri-deno-ts/src-tauri/local-catalog"
|
|
LOCAL_CATALOG_DB := LOCAL_CATALOG_ROOT / "game.db"
|
|
LOCAL_MANIFEST_ROOT := LOCAL_CATALOG_ROOT / "manifests"
|
|
LOCAL_CATALOG_CACHE_STAMP := ".lanspread/catalog-cache/local.json"
|
|
CATALOG_UNRAR := env_var_or_default("LANSPREAD_UNRAR", "crates/lanspread-tauri-deno-ts/src-tauri/binaries/unrar-x86_64-unknown-linux-gnu")
|
|
GAMES_DIR := env_var_or_default("LANSPREAD_GAMES_DIR", "")
|
|
CATALOG_FORCE := env_var_or_default("LANSPREAD_CATALOG_FORCE", "0")
|
|
CATALOG_MISSING_MODE := env_var_or_default("LANSPREAD_CATALOG_MISSING_MODE", "")
|
|
CATALOG_VERSION_MODE := env_var_or_default("LANSPREAD_CATALOG_VERSION_MODE", "")
|
|
TAURI_DEV_CONFIG := '{"bundle":{"resources":{"../../lanspread-peer-cli/catalogs/default/game.db":"game.db","../../lanspread-peer-cli/catalogs/default/manifests/":"manifests/","assets/*":"assets/"}}}'
|
|
TAURI_FIXTURE_ENV := "LANSPREAD_USE_FIXTURE_CATALOG=1"
|
|
|
|
setup:
|
|
cargo install tauri-cli
|
|
cd crates/lanspread-tauri-deno-ts && deno install --frozen=true
|
|
|
|
run: catalog-check-production
|
|
cargo tauri dev --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.production.conf.json --release
|
|
|
|
run-fixture: fixture-catalog-check
|
|
{{ TAURI_FIXTURE_ENV }} cargo tauri dev --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.dev.conf.json --release
|
|
|
|
run-production GAMES_DIR MODE_1="" MODE_2="":
|
|
just catalog-generate-production "$GAMES_DIR" "$MODE_1" "$MODE_2"
|
|
just catalog-check-production
|
|
cargo tauri dev --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.production.conf.json --release
|
|
|
|
# Build a separate test authority from these local games and select their folder.
|
|
run-local GAMES_DIR:
|
|
@local_games_dir="$(cd -- "$GAMES_DIR" && pwd -P)" && \
|
|
echo "LOCAL TEST MODE: $local_games_dir (separate local catalog; development build only)" && \
|
|
just catalog-generate-local "$local_games_dir" && \
|
|
LANSPREAD_USE_LOCAL_CATALOG=1 LANSPREAD_LOCAL_GAMES_DIR="$local_games_dir" \
|
|
cargo tauri dev --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.local.conf.json --release
|
|
|
|
build:
|
|
just build-production "$GAMES_DIR" "$CATALOG_MISSING_MODE" "$CATALOG_VERSION_MODE"
|
|
|
|
build-fixture: fixture-catalog-check
|
|
{{ TAURI_FIXTURE_ENV }} cargo tauri build --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.dev.conf.json --no-bundle #-- --profile dev
|
|
|
|
build-production GAMES_DIR="" MODE_1="" MODE_2="":
|
|
if [ -n "$GAMES_DIR" ]; then \
|
|
just catalog-generate-production "$GAMES_DIR" "$MODE_1" "$MODE_2"; \
|
|
else \
|
|
just catalog-check-production; \
|
|
fi
|
|
cargo tauri build --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.production.conf.json --no-bundle -- --profile production
|
|
|
|
bundle: catalog-check-production
|
|
cargo tauri build --config crates/lanspread-tauri-deno-ts/src-tauri/tauri.production.conf.json -- --profile production
|
|
|
|
fmt:
|
|
cargo +nightly fmt
|
|
cargo +nightly fmt --manifest-path vendor/mdns-sd/Cargo.toml
|
|
fd -tf -e toml -E vendor -x tombi format --offline
|
|
fd -tf -e md -E security-report -E vendor -E 'SECURITY_AUDIT_*.md' -x prettier --write --prose-wrap always --print-width 80
|
|
rumdl check --flavor commonmark --exclude 'security-report/**,vendor/**,SECURITY_AUDIT_*.md' --fix
|
|
just --fmt
|
|
|
|
_fix:
|
|
{{ TAURI_FIXTURE_ENV }} TAURI_CONFIG='{{ TAURI_DEV_CONFIG }}' cargo fix --workspace --all-targets --all-features
|
|
{{ TAURI_FIXTURE_ENV }} TAURI_CONFIG='{{ TAURI_DEV_CONFIG }}' cargo clippy --workspace --all-targets --all-features --fix
|
|
|
|
fix: _fix fmt
|
|
|
|
clippy:
|
|
{{ TAURI_FIXTURE_ENV }} TAURI_CONFIG='{{ TAURI_DEV_CONFIG }}' cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
|
|
test:
|
|
{{ TAURI_FIXTURE_ENV }} TAURI_CONFIG='{{ TAURI_DEV_CONFIG }}' cargo test --workspace --all-targets --all-features
|
|
|
|
# The patched dependency is intentionally outside the Cargo workspace.
|
|
mdns-vendor-test:
|
|
cargo test --manifest-path vendor/mdns-sd/Cargo.toml --all-targets --all-features
|
|
|
|
# Check both locked backend and frontend dependency graphs.
|
|
security-audit:
|
|
cargo audit
|
|
cd crates/lanspread-tauri-deno-ts && deno audit --lock deno.lock --frozen-lockfile
|
|
|
|
# Regenerate the committed acceptance catalogs from their fixture packages.
|
|
fixture-catalogs:
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir {{ FIXTURE_CATALOG_ROOT }}/default \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-alpha/alienswarm \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-alpha/bf1942 \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-alpha/ggoo \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-bravo/bfbc2 \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-bravo/cnc4 \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-bravo/cnctw \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-charlie/cod5 \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-charlie/cod6 \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-charlie/coh \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-persona/css
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir {{ FIXTURE_CATALOG_ROOT }}/solid \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-solid/cnctw
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir {{ FIXTURE_CATALOG_ROOT }}/multi \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-multi/cnctw
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir {{ FIXTURE_CATALOG_ROOT }}/unknown \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root crates/lanspread-peer-cli/fixtures/fixture-unknown/cod2
|
|
|
|
fixture-catalog OUTPUT GAME_ROOT:
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir "$OUTPUT" \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root "$GAME_ROOT"
|
|
|
|
fixture-download-only-catalog OUTPUT GAME_ID GAME_ROOT:
|
|
cargo run -p lanspread-compat --bin lanspread-fixture-catalog -- \
|
|
--source-catalog-db {{ FIXTURE_CATALOG_SOURCE }} \
|
|
--output-dir "$OUTPUT" \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-root "$GAME_ROOT" \
|
|
--no-stream-install "$GAME_ID"
|
|
|
|
fixture-catalog-check:
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- check \
|
|
--catalog-db {{ FIXTURE_CATALOG_ROOT }}/default/game.db --all
|
|
|
|
# Check every catalog profile used by the peer-CLI acceptance matrix.
|
|
fixture-catalogs-check: fixture-catalog-check
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- check \
|
|
--catalog-db {{ FIXTURE_CATALOG_ROOT }}/solid/game.db --all
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- check \
|
|
--catalog-db {{ FIXTURE_CATALOG_ROOT }}/multi/game.db --all
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- check \
|
|
--catalog-db {{ FIXTURE_CATALOG_ROOT }}/unknown/game.db --all
|
|
|
|
catalog-check-production:
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- check \
|
|
--catalog-db {{ PRODUCTION_CATALOG_DB }} \
|
|
--manifests-dir {{ PRODUCTION_MANIFEST_ROOT }} \
|
|
--all
|
|
|
|
# Generate production authority from PACKAGES_DIR/<game_id>/.
|
|
# Pass allow-missing-games and/or allow-version-mismatch as explicit modes.
|
|
catalog-generate-production PACKAGES_DIR MODE_1="" MODE_2="":
|
|
@set --; \
|
|
for mode in "$MODE_1" "$MODE_2"; do \
|
|
case "$mode" in \
|
|
"") ;; \
|
|
allow-missing-games) set -- "$@" --allow-missing-games ;; \
|
|
allow-version-mismatch) set -- "$@" --allow-version-mismatch ;; \
|
|
*) echo "mode must be allow-missing-games or allow-version-mismatch" >&2; exit 2 ;; \
|
|
esac; \
|
|
done; \
|
|
if [ "$CATALOG_FORCE" = "1" ] || ! python3 tools/catalog_source_cache.py check \
|
|
--stamp {{ CATALOG_CACHE_STAMP }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--catalog-db {{ PRODUCTION_CATALOG_DB }} \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--manifests-dir {{ PRODUCTION_MANIFEST_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" "$@"; then \
|
|
cargo run --release -p lanspread-compat --bin lanspread-production-catalog -- \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--output-dir {{ PRODUCTION_CATALOG_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
"$@" && \
|
|
python3 tools/catalog_source_cache.py record \
|
|
--stamp {{ CATALOG_CACHE_STAMP }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--catalog-db {{ PRODUCTION_CATALOG_DB }} \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--manifests-dir {{ PRODUCTION_MANIFEST_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" "$@"; \
|
|
else \
|
|
echo "catalog generation skipped: source metadata matches {{ CATALOG_CACHE_STAMP }}"; \
|
|
fi
|
|
|
|
# Local test authority never overwrites the generated production catalog.
|
|
catalog-generate-local PACKAGES_DIR:
|
|
@if [ "$CATALOG_FORCE" = "1" ] || ! python3 tools/catalog_source_cache.py check \
|
|
--stamp {{ LOCAL_CATALOG_CACHE_STAMP }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--catalog-db {{ LOCAL_CATALOG_DB }} \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--manifests-dir {{ LOCAL_MANIFEST_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" --allow-missing-games --allow-version-mismatch; then \
|
|
cargo run --release -p lanspread-compat --bin lanspread-production-catalog -- \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--output-dir {{ LOCAL_CATALOG_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--allow-missing-games --allow-version-mismatch && \
|
|
python3 tools/catalog_source_cache.py record \
|
|
--stamp {{ LOCAL_CATALOG_CACHE_STAMP }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--catalog-db {{ LOCAL_CATALOG_DB }} \
|
|
--source-catalog-db {{ PRODUCTION_CATALOG_SOURCE }} \
|
|
--manifests-dir {{ LOCAL_MANIFEST_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" --allow-missing-games --allow-version-mismatch; \
|
|
else \
|
|
echo "local catalog generation skipped: source metadata matches {{ LOCAL_CATALOG_CACHE_STAMP }}"; \
|
|
fi
|
|
|
|
# Regenerate one game in an already complete production authority.
|
|
catalog-generate-production-game PACKAGES_DIR GAME_ID:
|
|
cargo run -p lanspread-compat --bin lanspread-catalog-publisher -- generate \
|
|
--catalog-db {{ PRODUCTION_CATALOG_DB }} \
|
|
--packages-dir "$PACKAGES_DIR" \
|
|
--manifests-dir {{ PRODUCTION_MANIFEST_ROOT }} \
|
|
--unrar "$CATALOG_UNRAR" \
|
|
--game-id "$GAME_ID"
|
|
|
|
frontend-test:
|
|
cd crates/lanspread-tauri-deno-ts && deno test --config deno.test.json --allow-env=NODE_ENV --unstable-sloppy-imports tests
|
|
|
|
clean:
|
|
cargo clean
|
|
|
|
peer-cli-build:
|
|
cargo build -p lanspread-peer-cli
|
|
|
|
peer-cli-image: fixture-catalogs-check
|
|
mkdir -p "$DOCKER_CONFIG"
|
|
docker build -f crates/lanspread-peer-cli/Dockerfile -t lanspread-peer-cli:dev .
|
|
|
|
[positional-arguments]
|
|
peer-cli-tests *SCENARIOS: peer-cli-image
|
|
python3 crates/lanspread-peer-cli/scripts/run_extended_scenarios.py "$@"
|
|
|
|
# macvlan: each peer container gets its own MAC/IP on the real LAN.
|
|
# Override on the command line if your LAN differs, e.g.
|
|
# just LANSPREAD_PARENT_IFACE=enp4s0 LANSPREAD_SUBNET=10.0.0.0/24 LANSPREAD_GATEWAY=10.0.0.1 peer-cli-net
|
|
LANSPREAD_NET := "lanspread"
|
|
LANSPREAD_PARENT_IFACE := "eth0"
|
|
LANSPREAD_SUBNET := "192.168.1.0/24"
|
|
LANSPREAD_GATEWAY := "192.168.1.1"
|
|
|
|
peer-cli-net:
|
|
mkdir -p "$DOCKER_CONFIG"
|
|
docker network inspect "$LANSPREAD_NET" >/dev/null 2>&1 || \
|
|
docker network create -d macvlan \
|
|
--subnet="$LANSPREAD_SUBNET" \
|
|
--gateway="$LANSPREAD_GATEWAY" \
|
|
-o parent="$LANSPREAD_PARENT_IFACE" \
|
|
"$LANSPREAD_NET"
|
|
|
|
peer-cli-run NAME: peer-cli-net
|
|
mkdir -p ".lanspread-peer-cli/$NAME/state" ".lanspread-peer-cli/$NAME/games"
|
|
docker run --rm --init --network "$LANSPREAD_NET" --name "lanspread-peer-cli-$NAME" -i \
|
|
-v "$PWD/.lanspread-peer-cli/$NAME/state:/state" \
|
|
-v "$PWD/.lanspread-peer-cli/$NAME/games:/games" \
|
|
lanspread-peer-cli:dev \
|
|
--name "$NAME" \
|
|
--games-dir /games \
|
|
--state-dir /state \
|
|
--catalog-db /app/game.db \
|
|
--manifests-dir /app/manifests
|
|
|
|
peer-cli-alpha: peer-cli-net
|
|
mkdir -p ".lanspread-peer-cli/alpha/state"
|
|
docker run --rm --init --network "$LANSPREAD_NET" --name "lanspread-peer-cli-alpha" -i \
|
|
-v "$PWD/.lanspread-peer-cli/alpha/state:/state" \
|
|
-v "$PWD/crates/lanspread-peer-cli/fixtures/fixture-alpha:/games:ro" \
|
|
lanspread-peer-cli:dev \
|
|
--name "alpha" \
|
|
--games-dir /games \
|
|
--state-dir /state \
|
|
--catalog-db /app/game.db \
|
|
--manifests-dir /app/manifests
|
|
|
|
peer-cli-bravo: peer-cli-net
|
|
mkdir -p ".lanspread-peer-cli/bravo/state"
|
|
docker run --rm --init --network "$LANSPREAD_NET" --name "lanspread-peer-cli-bravo" -i \
|
|
-v "$PWD/.lanspread-peer-cli/bravo/state:/state" \
|
|
-v "$PWD/crates/lanspread-peer-cli/fixtures/fixture-bravo:/games:ro" \
|
|
lanspread-peer-cli:dev \
|
|
--name "bravo" \
|
|
--games-dir /games \
|
|
--state-dir /state \
|
|
--catalog-db /app/game.db \
|
|
--manifests-dir /app/manifests
|
|
|
|
peer-cli-charlie: peer-cli-net
|
|
mkdir -p ".lanspread-peer-cli/charlie/state"
|
|
docker run --rm --init --network "$LANSPREAD_NET" --name "lanspread-peer-cli-charlie" -i \
|
|
-v "$PWD/.lanspread-peer-cli/charlie/state:/state" \
|
|
-v "$PWD/crates/lanspread-peer-cli/fixtures/fixture-charlie:/games:ro" \
|
|
lanspread-peer-cli:dev \
|
|
--name "charlie" \
|
|
--games-dir /games \
|
|
--state-dir /state \
|
|
--catalog-db /app/game.db \
|
|
--manifests-dir /app/manifests
|