cc-libs/Justfile
2026-06-08 04:13:22 +02:00

150 lines
5.4 KiB
Makefile

# Justfile for cc-libs
# Run `just ci` to verify local tooling and lint Lua code.
# List available recipes.
default:
@just --list
# Install local development tooling.
install: init-env install-git-hooks check-install
# Create a local environment file when one does not exist.
init-env:
@if [ ! -f .env ]; then \
cp .env.sample .env; \
printf '%s\n' 'Created .env from .env.sample'; \
fi
# Install Git hooks for this repository.
install-git-hooks:
@mkdir -p .git/hooks
@printf '%s\n' '#!/bin/sh' '' 'just ci' > .git/hooks/pre-commit
@chmod +x .git/hooks/pre-commit
@printf '%s\n' 'Installed .git/hooks/pre-commit'
# Verify the CraftOS-PC harness is installed and recent enough.
check-craftos:
@command -v craftos >/dev/null 2>&1 || { \
printf '%s\n' 'craftos not found on $PATH. See docs/install-craftos-pc.md.' >&2; \
exit 1; \
}
@version="$(craftos --version)"; \
number="${version##* v}"; \
case "$number" in \
*.*.*) \
;; \
*) \
printf '%s\n' "$version"; \
printf '%s\n' 'Could not parse CraftOS-PC version. See docs/install-craftos-pc.md.' >&2; \
exit 1; \
;; \
esac; \
major="${number%%.*}"; \
rest="${number#*.}"; \
minor="${rest%%.*}"; \
patch="${rest#*.}"; \
patch="${patch%%[^0-9]*}"; \
printf '%s\n' "$version"; \
case "$major.$minor.$patch" in \
*[!0-9.]*|.*|*..*|*.) \
printf '%s\n' 'Could not parse CraftOS-PC version. See docs/install-craftos-pc.md.' >&2; \
exit 1; \
;; \
esac; \
if ! { [ "${major:-0}" -gt 2 ] || \
{ [ "${major:-0}" -eq 2 ] && [ "${minor:-0}" -gt 8 ]; } || \
{ [ "${major:-0}" -eq 2 ] && [ "${minor:-0}" -eq 8 ] && [ "${patch:-0}" -ge 3 ]; }; }; then \
printf '%s\n' 'CraftOS-PC v2.8.3 or newer is required. See docs/install-craftos-pc.md.' >&2; \
exit 1; \
fi
# Verify jq is installed.
check-jq:
@command -v jq >/dev/null 2>&1 || { \
printf '%s\n' 'jq not found on $PATH. See DEVELOPMENT.md.' >&2; \
exit 1; \
}
# Verify luacheck is installed.
check-luacheck:
@command -v luacheck >/dev/null 2>&1 || { \
printf '%s\n' 'luacheck not found on $PATH. See DEVELOPMENT.md.' >&2; \
exit 1; \
}
# Verify tools needed for local installation and CraftOS-PC launch recipes.
check-install: check-craftos check-jq check-luacheck
# Pass args through to `craftos`, for example:
# just craftos --headless --exec 'print("__READY__"); os.shutdown()'
# Launch CraftOS-PC with repo-local data and read-only repo mounts.
[positional-arguments]
craftos *args: check-install
#!/usr/bin/env bash
set -euo pipefail
repo='{{justfile_directory()}}'
argv=(--directory "$repo/.craftos")
if [ "$(uname -s)" = "Darwin" ]; then
argv+=(--rom /Applications/CraftOS-PC.app/Contents/Resources)
fi
argv+=(--mount-ro "/trapos=$repo")
while IFS= read -r dir; do
argv+=(--mount-ro "/$dir=$repo/$dir")
done < <(jq -r '.files[] | split("/")[0]' "$repo/manifest.json" | sort -u)
exec craftos "${argv[@]}" "$@"
# Human-only interactive REPL. LLM agents must not execute this command.
repl:
@just craftos --cli
# Local CI entry point used by Git hooks. Pass args through to `test`.
ci *args: check-craftos check
@just test {{args}}
# Run CraftOS-PC headless smoke tests. Pass `--verbose` to list each test.
test *args:
@if [ -f .env ]; then set -a; . ./.env; set +a; fi; \
verbose=0; \
timeout_seconds="${TRAP_CCLIBS_TEST_TIMEOUT_SECONDS:-3}"; \
case "$timeout_seconds" in ''|*[!0-9]*) printf '%s\n' 'TRAP_CCLIBS_TEST_TIMEOUT_SECONDS must be a positive integer' >&2; exit 1 ;; esac; \
if [ "$timeout_seconds" -lt 1 ]; then printf '%s\n' 'TRAP_CCLIBS_TEST_TIMEOUT_SECONDS must be >= 1' >&2; exit 1; fi; \
for a in {{args}}; do [ "$a" = "--verbose" ] && verbose=1; done; \
script_args=""; \
if [ "$verbose" -eq 1 ]; then script_args="--verbose"; fi; \
rom_arg=""; \
if [ "$(uname -s)" = "Darwin" ]; then \
rom_arg="--rom /Applications/CraftOS-PC.app/Contents/Resources"; \
fi; \
repo='{{justfile_directory()}}'; \
mount_arg="--mount-ro /apis=$repo/apis"; \
green=$(printf '\033[32m'); reset=$(printf '\033[0m'); red=$(printf '\033[31m'); \
for script in tests/boot.lua tests/ready.lua tests/eventloop.lua; do \
tmp="$(mktemp)"; \
craftos --headless $rom_arg $mount_arg --script "$script" $script_args >"$tmp" 2>&1 & \
pid="$!"; \
( sleep "$timeout_seconds"; kill -TERM "$pid" >/dev/null 2>&1 ) & \
watchdog="$!"; \
wait "$pid" >/dev/null 2>&1; \
status="$?"; \
kill "$watchdog" >/dev/null 2>&1 || true; \
wait "$watchdog" >/dev/null 2>&1 || true; \
if grep -q __READY__ "$tmp"; then \
rm -f "$tmp"; \
[ "$verbose" -eq 1 ] && printf '%s\n' "${green}PASS${reset} $script"; \
else \
if [ "$status" -eq 143 ]; then \
printf '%s\n' "${red}FAIL${reset} $script timed out after ${timeout_seconds}s" >&2; \
else \
printf '%s\n' "${red}FAIL${reset} $script did not print __READY__" >&2; \
fi; \
cat "$tmp" >&2; \
rm -f "$tmp"; \
exit 1; \
fi; \
done; \
printf '%s\n' 'OK: smoke tests passed'
# Lint all Lua source with luacheck.
check: check-luacheck
luacheck .