additional changes
CI / Detect changed paths (pull_request) Successful in 21s
CI / Odin unit tests and build (pull_request) Successful in 45s
CI / API unit tests and lint (pull_request) Failing after 28s
CI / Infra unit tests, vet, and preview (pull_request) Successful in 43s

This commit is contained in:
2026-09-07 19:51:22 -06:00
parent 1443369f6c
commit fade4a17dc
8 changed files with 103 additions and 82 deletions
+19 -1
View File
@@ -8,13 +8,28 @@
# output dirs live at the repo root and are referenced through `$(ROOT)`.
ODIN ?= odin
GDB ?= gdb
ROOT := ..
BIN := $(ROOT)/bin
BINARY := $(BIN)/desi_explorer
ODIN_FLAGS := -collection:lib=lib/local
WASM_DEFINE := RAYLIB_WASM_LIB=env.o
.PHONY: help setup add-dep run build build-debug build-web test clean fmt
# Normalize GUI_ENV_FILE (given relative to the repo root) to an absolute path
# so the Odin process can open it regardless of its working directory.
# "override" is required because GUI_ENV_FILE is usually set on the command
# line (or passed as an env var to this sub-make), which would otherwise
# override any assignment made here.
ifdef GUI_ENV_FILE
ifneq ($(abspath $(GUI_ENV_FILE)),$(GUI_ENV_FILE))
override GUI_ENV_FILE := $(abspath $(ROOT)/$(GUI_ENV_FILE))
endif
endif
# "override" on a command-line variable silently drops it from the recipe
# environment; re-export it so the app can find its env file (run + gdb).
export GUI_ENV_FILE
.PHONY: help setup add-dep run build build-debug gdb build-web test clean fmt
help: ## List available targets
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
@@ -41,6 +56,9 @@ build-debug: ## Debug build -> bin/desi_explorer
@mkdir -p lib/local $(BIN)
$(ODIN) build src $(ODIN_FLAGS) -o:none -debug -out:$(BINARY)
gdb: build-debug ## Run the native app under gdb (type 'run', then 'bt' on a crash)
$(GDB) -q --args $(BINARY) $(ARGS)
build-web: ## WebAssembly build -> build/web (needs emscripten)
@scripts/build_web.sh
+5 -19
View File
@@ -12,10 +12,7 @@ import "core:strings"
// double quotes. Real process environment variables take precedence over the
// file. The returned map owns its keys/values; release it with destroy.
@(private)
parse :: proc(
src: string,
allocator := context.allocator,
) -> map[string]string {
parse :: proc(src: string, allocator := context.allocator) -> map[string]string {
result := make(map[string]string, allocator)
it := src
@@ -54,18 +51,12 @@ parse :: proc(
// parse_file reads a dotenv file from disk and parses it into a map. It
// returns (nil, false) when the file cannot be read (e.g. it does not exist).
parse_file :: proc(
filename: string,
allocator := context.allocator,
) -> (
map[string]string,
bool,
) {
parse_file :: proc(filename: string, allocator := context.allocator) -> (map[string]string, bool) {
data, err := os.read_entire_file(filename, allocator)
if err != nil {
return nil, false
}
defer delete(data)
defer delete(data, allocator)
return parse(string(data), allocator), true
}
@@ -86,8 +77,7 @@ destroy :: proc(env: map[string]string) {
// case-insensitive, so API_URL maps onto api_url (or an `env:"API_URL"` tag).
@(private)
env_key_for_field :: proc(field: reflect.Struct_Field) -> string {
if tag_key, ok := reflect.struct_tag_lookup(field.tag, "env");
ok && tag_key != "" {
if tag_key, ok := reflect.struct_tag_lookup(field.tag, "env"); ok && tag_key != "" {
return tag_key
}
return field.name
@@ -100,11 +90,7 @@ env_key_for_field :: proc(field: reflect.Struct_Field) -> string {
// and floats with strconv.parse_f64. Keys missing from env leave the field
// at its zero value. It returns false if a present value cannot be converted
// to the field's type.
decode :: proc(
env: map[string]string,
dest: ^$T,
allocator := context.allocator,
) -> bool {
decode :: proc(env: map[string]string, dest: ^$T, allocator := context.allocator) -> bool {
ti := reflect.type_info_base(type_info_of(T))
fields, ok := ti.variant.(runtime.Type_Info_Struct)
if !ok {
+5 -8
View File
@@ -11,10 +11,7 @@ get_config :: proc(env_file: ^string = nil) -> (^Config, ^Error) {
path := ".env"
if env_file != nil && env_file^ != "" {
path = env_file^
} else if from_env, ok := os.lookup_env(
"GUI_ENV_FILE",
context.temp_allocator,
); ok {
} else if from_env, ok := os.lookup_env("GUI_ENV_FILE", context.temp_allocator); ok {
path = from_env
}
@@ -39,9 +36,9 @@ get_config :: proc(env_file: ^string = nil) -> (^Config, ^Error) {
return c, nil
}
validate_config :: proc(c: ^Config) -> ^Error {
err := new(Error)
if c.api_url == "" do err.type = .Config; err.message = "'API_URL' is required"
validate_config :: proc(c: ^Config) -> (err: ^Error) {
if c.api_url == "" {
err = &Error{.Config, "'API_URL' is required"}
}
return err
}
+5 -1
View File
@@ -1,7 +1,9 @@
package main
import "base:runtime"
import "core:math"
import "core:math/rand"
import "core:os"
import rl "vendor:raylib"
WIDTH :: 1280
@@ -27,7 +29,9 @@ main :: proc() {
c: ^Config
if c, err := get_config(); err != nil {
s := os.get_env("GUI_ENV_FILE", context.temp_allocator)
if c, err := get_config(&s); err != nil {
panic(format_error(err))
}