144 lines
3.7 KiB
Bash
144 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Starts the whole app: game server, Vite client and the Aspire dashboard.
|
|
# Skips MSBuild when AppHost and Server dlls are newer than C# / csproj / props.
|
|
# ./run-aspire.sh
|
|
# ./run-aspire.sh --launch-profile http
|
|
# ./run-aspire.sh --rebuild
|
|
# ./run-aspire.sh --no-tailscale
|
|
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
log() {
|
|
echo "[run-aspire] $*"
|
|
}
|
|
|
|
skip_tailscale() {
|
|
log "WARNING: $*"
|
|
echo " Friends cannot reach the client over the tailnet."
|
|
echo " Continuing with local access only (http://localhost:5173)."
|
|
}
|
|
|
|
# Same rules as tools/apphost-uptodate.ps1 and LaunchBuildStamp.cs.
|
|
needs_build() {
|
|
local tfm=net10.0
|
|
local apphost="src/HSchool.AppHost/bin/${configuration}/${tfm}/HSchool.AppHost.dll"
|
|
local server="src/HSchool.Server/bin/${configuration}/${tfm}/HSchool.Server.dll"
|
|
[[ -f "$apphost" && -f "$server" ]] || return 0
|
|
|
|
local oldest=$apphost
|
|
[[ "$server" -ot "$apphost" ]] && oldest=$server
|
|
|
|
local name
|
|
for name in global.json Directory.Build.props Directory.Packages.props; do
|
|
[[ -f "$name" && "$name" -nt "$oldest" ]] && return 0
|
|
done
|
|
|
|
[[ -d src ]] || return 0
|
|
|
|
local found
|
|
found=$(find src \( -name bin -o -name obj -o -name node_modules \) -prune -o \
|
|
-type f \( -name '*.cs' -o -name '*.csproj' -o -name '*.props' \) -newer "$oldest" -print -quit)
|
|
[[ -n "$found" ]]
|
|
}
|
|
|
|
configuration=Debug
|
|
rebuild=0
|
|
tailscale_serve=1
|
|
dotnet_args=()
|
|
expect_configuration=0
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
if [[ $expect_configuration -eq 1 ]]; then
|
|
configuration=$1
|
|
expect_configuration=0
|
|
shift
|
|
continue
|
|
fi
|
|
case $1 in
|
|
--rebuild) rebuild=1 ;;
|
|
--no-tailscale) tailscale_serve=0 ;;
|
|
-c|--configuration) expect_configuration=1 ;;
|
|
*) dotnet_args+=("$1") ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [[ $expect_configuration -eq 1 ]]; then
|
|
log "missing value for -c / --configuration."
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v dotnet >/dev/null; then
|
|
log "dotnet SDK not found in PATH."
|
|
echo " Install .NET 10: https://dotnet.microsoft.com/download"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v node >/dev/null; then
|
|
log "Node.js not found in PATH - the client resource will fail to start."
|
|
echo " Install Node 22.12 or newer: https://nodejs.org"
|
|
echo
|
|
fi
|
|
|
|
need_build=0
|
|
if [[ $rebuild -eq 1 ]]; then
|
|
log "--rebuild: building."
|
|
need_build=1
|
|
elif needs_build; then
|
|
log "sources changed or binaries missing, building."
|
|
need_build=1
|
|
else
|
|
log "binaries are up to date, skipping build."
|
|
fi
|
|
|
|
if [[ $need_build -eq 1 ]]; then
|
|
echo
|
|
if ! dotnet build src/HSchool.AppHost/HSchool.AppHost.csproj -c "$configuration"; then
|
|
echo
|
|
log "build failed."
|
|
exit 1
|
|
fi
|
|
echo
|
|
fi
|
|
|
|
client_tailscale_url=
|
|
if [[ $tailscale_serve -eq 1 ]]; then
|
|
if ! command -v tailscale >/dev/null; then
|
|
skip_tailscale "tailscale not found in PATH."
|
|
elif ! tailscale status >/dev/null 2>&1; then
|
|
skip_tailscale "tailscale is not connected or not running."
|
|
else
|
|
log "tailscale serve --bg 5173"
|
|
if ! tailscale serve --bg 5173; then
|
|
skip_tailscale "tailscale serve failed."
|
|
else
|
|
line=$(tailscale serve status 2>/dev/null | head -n 1 || true)
|
|
token=${line%% *}
|
|
case $token in
|
|
https://*) client_tailscale_url=$token ;;
|
|
esac
|
|
fi
|
|
fi
|
|
echo
|
|
fi
|
|
|
|
log "Starting the Aspire AppHost. Press Ctrl+C to shut everything down."
|
|
log "Client: http://localhost:5173"
|
|
if [[ -n "$client_tailscale_url" ]]; then
|
|
log "Client (Tailscale): $client_tailscale_url"
|
|
fi
|
|
echo
|
|
|
|
set +e
|
|
dotnet run --project src/HSchool.AppHost/HSchool.AppHost.csproj --no-build --no-restore "${dotnet_args[@]}"
|
|
exit_code=$?
|
|
set -e
|
|
|
|
if [[ $exit_code -ne 0 ]]; then
|
|
echo
|
|
log "AppHost exited with code ${exit_code}."
|
|
fi
|
|
|
|
exit "$exit_code"
|