Validate POC A and POC B foundations
This commit is contained in:
1 parent
44fd4b4b43
commit
c38e09a663
47 files changed
+4990
-35
No files matched your search
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIRECTORY="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||
PROJECT_DIRECTORY="$(CDPATH= cd -- "$SCRIPT_DIRECTORY/.." && pwd)"
|
||||
cd "$PROJECT_DIRECTORY"
|
||||
|
||||
failure_count=0
|
||||
|
||||
fail_with_matches() {
|
||||
local label="$1"
|
||||
local matches="$2"
|
||||
if [ -n "$matches" ]; then
|
||||
printf 'ARCHITECTURE ERROR: %s\n%s\n' "$label" "$matches"
|
||||
failure_count=$((failure_count + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
source_directories="src tests"
|
||||
if [ -d game ]; then
|
||||
source_directories="$source_directories game"
|
||||
fi
|
||||
|
||||
duplicate_classes="$(
|
||||
rg --no-filename -o \
|
||||
'^[[:space:]]*class_name[[:space:]]+[A-Za-z_][A-Za-z0-9_]*' \
|
||||
$source_directories 2>/dev/null \
|
||||
| awk '{print $2}' \
|
||||
| sort \
|
||||
| uniq -d \
|
||||
|| true
|
||||
)"
|
||||
fail_with_matches "duplicate class_name declarations" "$duplicate_classes"
|
||||
|
||||
if [ -d game ]; then
|
||||
prototype_imports="$(rg -n 'res://(src|scenes)/' game --glob '*.gd' || true)"
|
||||
fail_with_matches "production imports prototype code or scenes" "$prototype_imports"
|
||||
|
||||
test_imports="$(rg -n 'res://tests/' game --glob '*.gd' || true)"
|
||||
fail_with_matches "production imports test code" "$test_imports"
|
||||
|
||||
poc_references="$(rg -n 'poc_[ab]|POC_[AB]' game --glob '*.gd' --glob '*.tscn' || true)"
|
||||
fail_with_matches "production contains a prototype dependency" "$poc_references"
|
||||
|
||||
if [ -d game/domain ]; then
|
||||
domain_nodes="$(
|
||||
rg -n '^extends[[:space:]]+(Node|Node2D|Node3D|Control|CanvasLayer|CharacterBody3D|SubViewport)' \
|
||||
game/domain --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "domain extends scene-tree or presentation nodes" "$domain_nodes"
|
||||
|
||||
domain_dependencies="$(
|
||||
rg -n 'res://game/(application|world|presentation|infrastructure|composition)/' \
|
||||
game/domain --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "domain depends on an outer layer" "$domain_dependencies"
|
||||
fi
|
||||
|
||||
if [ -d game/application ]; then
|
||||
application_dependencies="$(
|
||||
rg -n 'res://game/(world|presentation|infrastructure|composition)/' \
|
||||
game/application --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "application depends on an adapter layer" "$application_dependencies"
|
||||
fi
|
||||
|
||||
if [ -d game/world ]; then
|
||||
world_dependencies="$(
|
||||
rg -n 'res://game/(presentation|infrastructure|composition)/' \
|
||||
game/world --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "world depends on presentation or infrastructure" "$world_dependencies"
|
||||
fi
|
||||
|
||||
if [ -d game/presentation ]; then
|
||||
presentation_dependencies="$(
|
||||
rg -n 'res://game/(world|infrastructure|composition)/' \
|
||||
game/presentation --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "presentation depends on a concrete adapter" "$presentation_dependencies"
|
||||
fi
|
||||
|
||||
if [ -d game/infrastructure ]; then
|
||||
infrastructure_dependencies="$(
|
||||
rg -n 'res://game/(world|presentation|composition)/' \
|
||||
game/infrastructure --glob '*.gd' || true
|
||||
)"
|
||||
fail_with_matches "infrastructure depends on world or presentation" "$infrastructure_dependencies"
|
||||
fi
|
||||
|
||||
input_violations="$(
|
||||
rg -n '\bInput\.' game --glob '*.gd' \
|
||||
| rg -v '^game/infrastructure/input/' \
|
||||
|| true
|
||||
)"
|
||||
fail_with_matches "direct Input access outside infrastructure/input" "$input_violations"
|
||||
fi
|
||||
|
||||
if [ "$failure_count" -ne 0 ]; then
|
||||
printf 'Architecture checks: %d failure(s).\n' "$failure_count"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Architecture checks: passed.\n'
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIRECTORY="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||
PROJECT_DIRECTORY="$(CDPATH= cd -- "$SCRIPT_DIRECTORY/.." && pwd)"
|
||||
GODOT_EXECUTABLE="${GODOT_BIN:-godot}"
|
||||
REQUIRED_GODOT_VERSION="4.7.1"
|
||||
QUALITY_TEMP_DIRECTORY="$(mktemp -d "${TMPDIR:-/tmp}/ransoms-wake-quality.XXXXXX")"
|
||||
|
||||
cleanup_quality_directory() {
|
||||
if [ -n "$QUALITY_TEMP_DIRECTORY" ] && [ -d "$QUALITY_TEMP_DIRECTORY" ]; then
|
||||
rm -r -- "$QUALITY_TEMP_DIRECTORY"
|
||||
fi
|
||||
}
|
||||
trap cleanup_quality_directory EXIT
|
||||
|
||||
cd "$PROJECT_DIRECTORY"
|
||||
|
||||
check_godot_log() {
|
||||
local stage_name="$1"
|
||||
local log_path="$2"
|
||||
local unexpected_messages
|
||||
unexpected_messages="$(
|
||||
rg -n '^(ERROR|SCRIPT ERROR|WARNING):' "$log_path" \
|
||||
| rg -v '^.*ERROR: Condition "ret != noErr" is true\. Returning: ""$' \
|
||||
|| true
|
||||
)"
|
||||
if [ -n "$unexpected_messages" ]; then
|
||||
printf 'Quality gate: unexpected Godot diagnostics during %s\n%s\n' \
|
||||
"$stage_name" "$unexpected_messages"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
actual_version="$($GODOT_EXECUTABLE --version)"
|
||||
case "$actual_version" in
|
||||
"$REQUIRED_GODOT_VERSION"*) ;;
|
||||
*)
|
||||
printf 'Quality gate: Godot %s required, found %s.\n' \
|
||||
"$REQUIRED_GODOT_VERSION" "$actual_version"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
printf 'Quality gate: shell scripts\n'
|
||||
bash -n scripts/check_architecture.sh scripts/quality_gate.sh
|
||||
|
||||
printf 'Quality gate: architecture\n'
|
||||
bash scripts/check_architecture.sh
|
||||
|
||||
printf 'Quality gate: resource loading\n'
|
||||
"$GODOT_EXECUTABLE" --headless \
|
||||
--log-file "$QUALITY_TEMP_DIRECTORY/load.log" \
|
||||
--path . \
|
||||
--script tests/run_load_checks.gd \
|
||||
2>&1 | tee "$QUALITY_TEMP_DIRECTORY/load-console.log"
|
||||
check_godot_log "resource loading" "$QUALITY_TEMP_DIRECTORY/load-console.log"
|
||||
|
||||
printf 'Quality gate: unit tests\n'
|
||||
"$GODOT_EXECUTABLE" --headless \
|
||||
--log-file "$QUALITY_TEMP_DIRECTORY/unit.log" \
|
||||
--path . \
|
||||
--script tests/run_tests.gd \
|
||||
2>&1 | tee "$QUALITY_TEMP_DIRECTORY/unit-console.log"
|
||||
check_godot_log "unit tests" "$QUALITY_TEMP_DIRECTORY/unit-console.log"
|
||||
|
||||
printf 'Quality gate: POC B integration\n'
|
||||
"$GODOT_EXECUTABLE" --headless \
|
||||
--log-file "$QUALITY_TEMP_DIRECTORY/poc_b_integration.log" \
|
||||
--path . \
|
||||
--script tests/run_poc_b_integration.gd \
|
||||
2>&1 | tee "$QUALITY_TEMP_DIRECTORY/poc_b-integration-console.log"
|
||||
check_godot_log "POC B integration" "$QUALITY_TEMP_DIRECTORY/poc_b-integration-console.log"
|
||||
|
||||
printf 'Quality gate: passed.\n'
|
||||
Reference in new issue
Block a user