updated makefiles and added dependency installation for ODIN
This commit was merged in pull request #3.
This commit is contained in:
@@ -4,10 +4,11 @@ Odin + raylib interactive 3D universe map (DESI data), a Rust + axum API, with G
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
The root `Makefile` is a lean delegator: base commands (`run`, `build`, `test`, ...) forward into the per-project Makefiles in `gui/`, `api/`, and `infra/`. Project-specific commands are reached via `make -C <dir> <target>`.
|
The root `Makefile` is a lean delegator: base commands (`run`, `build`, `test`, ...) forward into the per-project Makefiles in `gui/`, `api/`, and `infra/`. Project-specific commands are reached via `make -C <dir> <target>`.
|
||||||
- Run: `make run`; Build: `make build` (`-> bin/desi_explorer`); Web: `make build-web` (Emscripten/WASM -> `build/web`); Debug: `make build-debug`
|
- Run: `make run`; Build: `make build` (`-> bin/desi_explorer`); Web: `make build-web` (Emscripten/WASM -> `build/web`); Debug: `make build-debug`; Run Web: `make run-web` (WASM build + API server)
|
||||||
- Test: `make test` (runs `odin test` in gui/, `cargo test` in api/, `go test` in infra/); Clean: `make clean`; Format: `make fmt`
|
- Test: `make test` (runs `odin test` in gui/, `cargo test` in api/, `go test` in infra/); Clean: `make clean`; Format: `make fmt`
|
||||||
- API: `make api-run`, `make api-test`, `make api-check` (thin passthroughs to `make -C api <target>`)
|
- API: `make api-run`, `make api-test`, `make api-check` (thin passthroughs to `make -C api <target>`)
|
||||||
- Setup: `make setup` (submodules + `go mod tidy` in infra/)
|
- Setup: `make setup` (submodules + gui lib/local + `cargo fetch` + `go mod tidy` in infra/)
|
||||||
|
- Add dependency: `make -C gui add-dep DEP=<name>` (searches Codeberg/GitHub/GitLab, adds as submodule to `gui/lib/local/`)
|
||||||
- Infra: `make infra-preview`, `make infra-up`, `make infra-down`, `make infra-refresh` (passthroughs to `make -C infra <target>`)
|
- Infra: `make infra-preview`, `make infra-up`, `make infra-down`, `make infra-refresh` (passthroughs to `make -C infra <target>`)
|
||||||
- Renovate: `make renovate-validate` (npx renovate-config-validator)
|
- Renovate: `make renovate-validate` (npx renovate-config-validator)
|
||||||
- Format Odin with `odinfmt` (config `gui/odinfmt.json`: tabs, width 80); format Rust with `cargo fmt`
|
- Format Odin with `odinfmt` (config `gui/odinfmt.json`: tabs, width 80); format Rust with `cargo fmt`
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ GUI := gui
|
|||||||
API := api
|
API := api
|
||||||
INFRA := infra
|
INFRA := infra
|
||||||
|
|
||||||
.PHONY: help setup run build build-debug build-web test clean fmt \
|
.PHONY: help setup run run-web build build-debug build-web test clean fmt \
|
||||||
renovate-validate
|
renovate-validate
|
||||||
|
|
||||||
help: ## List available targets
|
help: ## List available targets
|
||||||
@@ -23,24 +23,37 @@ help: ## List available targets
|
|||||||
|
|
||||||
## ---- Setup ---------------------------------------------------------------
|
## ---- Setup ---------------------------------------------------------------
|
||||||
|
|
||||||
setup: ## Pull submodules + tidy Go deps
|
setup: ## Setup all sub-projects (submodules, gui deps, api deps, infra deps)
|
||||||
@git submodule update --init --recursive
|
@git submodule update --init --recursive
|
||||||
|
@$(MAKE) -C $(GUI) setup
|
||||||
|
@$(MAKE) -C $(API) setup
|
||||||
@$(MAKE) -C $(INFRA) tidy
|
@$(MAKE) -C $(INFRA) tidy
|
||||||
|
|
||||||
## ---- Renderer (Odin) -----------------------------------------------------
|
## ---- Renderer (Odin) -----------------------------------------------------
|
||||||
|
|
||||||
run: ## Run the native app (gui/)
|
run: ## Run the native app (gui/)
|
||||||
@$(MAKE) -C $(GUI) run
|
@$(MAKE) -C $(API) run & api_pid=$$!; \
|
||||||
|
trap 'kill $$api_pid 2>/dev/null' INT TERM EXIT; \
|
||||||
|
$(MAKE) -C $(GUI) run; \
|
||||||
|
kill $$api_pid 2>/dev/null
|
||||||
|
|
||||||
build: ## Release build -> bin/desi_explorer (gui/)
|
build: ## Release build (gui/ + api/)
|
||||||
@$(MAKE) -C $(GUI) build
|
@$(MAKE) -C $(GUI) build
|
||||||
|
@$(MAKE) -C $(API) build
|
||||||
|
|
||||||
build-debug: ## Debug build -> bin/desi_explorer (gui/)
|
build-debug: ## Debug build (gui/ + api/)
|
||||||
@$(MAKE) -C $(GUI) build-debug
|
@$(MAKE) -C $(GUI) build-debug
|
||||||
|
@$(MAKE) -C $(API) build
|
||||||
|
|
||||||
build-web: ## WebAssembly build -> build/web (gui/, needs emscripten)
|
build-web: ## WebAssembly build -> build/web (gui/, needs emscripten)
|
||||||
@$(MAKE) -C $(GUI) build-web
|
@$(MAKE) -C $(GUI) build-web
|
||||||
|
|
||||||
|
run-web: ## Start WASM build + API server for web dev
|
||||||
|
@$(MAKE) -C $(API) run & api_pid=$$!; \
|
||||||
|
trap 'kill $$api_pid 2>/dev/null' INT TERM EXIT; \
|
||||||
|
$(MAKE) -C $(GUI) build-web; \
|
||||||
|
kill $$api_pid 2>/dev/null
|
||||||
|
|
||||||
## ---- Aggregates ----------------------------------------------------------
|
## ---- Aggregates ----------------------------------------------------------
|
||||||
|
|
||||||
test: ## Test all projects (odin + cargo + go)
|
test: ## Test all projects (odin + cargo + go)
|
||||||
|
|||||||
+4
-1
@@ -5,12 +5,15 @@
|
|||||||
|
|
||||||
CARGO ?= cargo
|
CARGO ?= cargo
|
||||||
|
|
||||||
.PHONY: help run build test check fmt clean
|
.PHONY: help setup run build test check fmt clean
|
||||||
|
|
||||||
help: ## List available targets
|
help: ## List available targets
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
|
setup: ## Fetch dependencies
|
||||||
|
$(CARGO) fetch
|
||||||
|
|
||||||
run: ## Run the API server (dev)
|
run: ## Run the API server (dev)
|
||||||
$(CARGO) run
|
$(CARGO) run
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -14,12 +14,21 @@ BINARY := $(BIN)/desi_explorer
|
|||||||
ODIN_FLAGS := -collection:lib=lib/local
|
ODIN_FLAGS := -collection:lib=lib/local
|
||||||
WASM_DEFINE := RAYLIB_WASM_LIB=env.o
|
WASM_DEFINE := RAYLIB_WASM_LIB=env.o
|
||||||
|
|
||||||
.PHONY: help run build build-debug build-web test clean fmt
|
.PHONY: help setup add-dep run build build-debug build-web test clean fmt
|
||||||
|
|
||||||
help: ## List available targets
|
help: ## List available targets
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
|
setup: ## Prepare build environment (lib/local)
|
||||||
|
@mkdir -p lib/local
|
||||||
|
|
||||||
|
add-dep: ## Add a dependency from Codeberg/GitHub/GitLab as a submodule (DEP=name)
|
||||||
|
ifndef DEP
|
||||||
|
$(error Usage: make add-dep DEP=<dependency-name>)
|
||||||
|
endif
|
||||||
|
@scripts/add_dep.sh "$(DEP)"
|
||||||
|
|
||||||
run: ## Run the native app
|
run: ## Run the native app
|
||||||
@mkdir -p lib/local
|
@mkdir -p lib/local
|
||||||
$(ODIN) run src $(ODIN_FLAGS)
|
$(ODIN) run src $(ODIN_FLAGS)
|
||||||
|
|||||||
Executable
+151
@@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Search Codeberg, GitHub, and GitLab for an Odin dependency and add it
|
||||||
|
# as a git submodule under gui/lib/local/. Run via `make -C gui add-dep`.
|
||||||
|
#
|
||||||
|
# Usage: add_dep.sh <dependency-name>
|
||||||
|
#
|
||||||
|
# Requires: curl, jq
|
||||||
|
# Optional: fzf (interactive selector; falls back to numbered menu)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
GUI_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
ROOT_DIR="$(cd "${GUI_DIR}/.." && pwd)"
|
||||||
|
LIB_DIR="${GUI_DIR}/lib/local"
|
||||||
|
|
||||||
|
# ---- Args ------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo "Usage: $0 <dependency-name>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
QUERY="$1"
|
||||||
|
|
||||||
|
# ---- Helpers ---------------------------------------------------------------
|
||||||
|
|
||||||
|
TMPDIR_WORK="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "${TMPDIR_WORK}"' EXIT
|
||||||
|
|
||||||
|
RESULTS="${TMPDIR_WORK}/results"
|
||||||
|
touch "$RESULTS"
|
||||||
|
|
||||||
|
search_codeberg() {
|
||||||
|
local url
|
||||||
|
url="https://codeberg.org/api/v1/repos/search?q=$(printf '%s' "$QUERY" | jq -sRr @uri)&limit=10"
|
||||||
|
local data
|
||||||
|
data=$(curl -sf --max-time 10 "$url" 2>/dev/null) || return 0
|
||||||
|
printf '%s' "$data" | jq -r '.data[]? | [.owner.username, .name, "codeberg", (.description // "")] | @tsv' 2>/dev/null \
|
||||||
|
| while IFS=$'\t' read -r owner name _ desc; do
|
||||||
|
printf '%s\t%s\t%s\t%s\n' "$owner" "$name" "codeberg" "$desc"
|
||||||
|
done >> "$RESULTS"
|
||||||
|
}
|
||||||
|
|
||||||
|
search_github() {
|
||||||
|
local url
|
||||||
|
url="https://api.github.com/search/repositories?q=$(printf '%s' "$QUERY" | jq -sRr @uri)&per_page=10"
|
||||||
|
local data
|
||||||
|
data=$(curl -sf --max-time 10 -H "Accept: application/vnd.github+json" "$url" 2>/dev/null) || return 0
|
||||||
|
printf '%s' "$data" | jq -r '.items[]? | [.owner.login, .name, "github", (.description // "")] | @tsv' 2>/dev/null \
|
||||||
|
| while IFS=$'\t' read -r owner name _ desc; do
|
||||||
|
printf '%s\t%s\t%s\t%s\n' "$owner" "$name" "github" "$desc"
|
||||||
|
done >> "$RESULTS"
|
||||||
|
}
|
||||||
|
|
||||||
|
search_gitlab() {
|
||||||
|
local url
|
||||||
|
url="https://gitlab.com/api/v4/projects?search=$(printf '%s' "$QUERY" | jq -sRr @uri)&per_page=10"
|
||||||
|
local data
|
||||||
|
data=$(curl -sf --max-time 10 "$url" 2>/dev/null) || return 0
|
||||||
|
printf '%s' "$data" | jq -r '.[]? | [.namespace.full_path, .name, "gitlab", (.description // "")] | @tsv' 2>/dev/null \
|
||||||
|
| while IFS=$'\t' read -r owner name _ desc; do
|
||||||
|
printf '%s\t%s\t%s\t%s\n' "$owner" "$name" "gitlab" "$desc"
|
||||||
|
done >> "$RESULTS"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Search (Codeberg → GitHub → GitLab) -----------------------------------
|
||||||
|
|
||||||
|
echo "Searching for '${QUERY}'..." >&2
|
||||||
|
|
||||||
|
search_codeberg
|
||||||
|
search_github
|
||||||
|
search_gitlab
|
||||||
|
|
||||||
|
TOTAL=$(wc -l < "$RESULTS" | tr -d ' ')
|
||||||
|
|
||||||
|
if [[ "$TOTAL" -eq 0 ]]; then
|
||||||
|
echo "No results found for '${QUERY}' on Codeberg, GitHub, or GitLab." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- Select ----------------------------------------------------------------
|
||||||
|
|
||||||
|
SELECTED=""
|
||||||
|
|
||||||
|
if command -v fzf >/dev/null 2>&1; then
|
||||||
|
SELECTED=$(while IFS=$'\t' read -r owner name forge desc; do
|
||||||
|
printf '%-20s %-30s [%s] %s\n' "$owner" "$name" "$forge" "$desc"
|
||||||
|
done < "$RESULTS" \
|
||||||
|
| fzf --prompt="Select dependency > " \
|
||||||
|
--header="${TOTAL} result(s) for '${QUERY}'" \
|
||||||
|
--height=40% \
|
||||||
|
--reverse)
|
||||||
|
else
|
||||||
|
echo "" >&2
|
||||||
|
echo "Results for '${QUERY}':" >&2
|
||||||
|
echo "---" >&2
|
||||||
|
IDX=0
|
||||||
|
while IFS=$'\t' read -r owner name forge desc; do
|
||||||
|
IDX=$((IDX + 1))
|
||||||
|
printf ' %2d) %-20s %-30s [%s] %s\n' "$IDX" "$owner" "$name" "$forge" "$desc" >&2
|
||||||
|
done < "$RESULTS"
|
||||||
|
echo "---" >&2
|
||||||
|
printf 'Select [1-%d]: ' "$TOTAL" >&2
|
||||||
|
read -r CHOICE
|
||||||
|
|
||||||
|
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || [[ "$CHOICE" -lt 1 ]] || [[ "$CHOICE" -gt "$TOTAL" ]]; then
|
||||||
|
echo "Invalid selection." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
SELECTED=$(sed -n "${CHOICE}p" "$RESULTS")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$SELECTED" ]]; then
|
||||||
|
echo "No selection made." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- Parse & Add -----------------------------------------------------------
|
||||||
|
|
||||||
|
ENTRYowner=$(printf '%s' "$SELECTED" | cut -f1)
|
||||||
|
ENTRYname=$(printf '%s' "$SELECTED" | cut -f2)
|
||||||
|
ENTRYforge=$(printf '%s' "$SELECTED" | cut -f3)
|
||||||
|
|
||||||
|
case "$ENTRYforge" in
|
||||||
|
codeberg) URL="https://codeberg.org/${ENTRYowner}/${ENTRYname}.git" ;;
|
||||||
|
github) URL="https://github.com/${ENTRYowner}/${ENTRYname}.git" ;;
|
||||||
|
gitlab) URL="https://gitlab.com/${ENTRYowner}/${ENTRYname}.git" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
MODULE_PATH="lib/local/${ENTRYname}"
|
||||||
|
|
||||||
|
# Check for name collisions (same dir, different repo).
|
||||||
|
if [[ -d "${GUI_DIR}/${MODULE_PATH}" ]]; then
|
||||||
|
EXISTING=$(git -C "${ROOT_DIR}" config --get "submodule.${MODULE_PATH}.url" 2>/dev/null || true)
|
||||||
|
if [[ -n "$EXISTING" ]]; then
|
||||||
|
echo "Dependency '${ENTRYname}' is already installed from ${EXISTING}." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Error: '${MODULE_PATH}' already exists but is not a submodule." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Adding ${ENTRYowner}/${ENTRYname} (${ENTRYforge}) as submodule..." >&2
|
||||||
|
|
||||||
|
mkdir -p "${LIB_DIR}"
|
||||||
|
git -C "${ROOT_DIR}" submodule add "$URL" "$MODULE_PATH"
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo "Done — added ${ENTRYowner}/${ENTRYname} from ${ENTRYforge}" >&2
|
||||||
|
echo " path: ${MODULE_PATH}" >&2
|
||||||
|
echo " The Makefile's -collection:lib=lib/local will pick it up automatically." >&2
|
||||||
Reference in New Issue
Block a user