graw.bat
Rama main · réplica de lectura del repositorio original.
@echo off
rem =============================================================================
rem graw.bat - Graw "non-Docker local build + daemon" one-shot command (Windows)
rem
rem Production form, different from start.bat (dev hot start):
rem build frontend dist -> compile Go backend -> backend serves it as a
rem detached daemon.
rem
rem Usage:
rem graw.bat deps install deps (Go modules + npm install)
rem graw.bat build build frontend (frontend\dist) and Go binary
rem graw.bat start auto deps/build when missing, then start daemon
rem graw.bat stop stop daemon
rem graw.bat restart restart
rem graw.bat status process + health check
rem graw.bat log tail running log (Ctrl+C to exit, service keeps running)
rem
rem Env vars: GRAW_PORT (default 8000), GRAW_HOST (default 0.0.0.0)
rem Note: keep this file ASCII-only, cmd parses batch under legacy code page.
rem =============================================================================
setlocal EnableExtensions
set "ROOT=%~dp0"
set "BACKEND_GO_DIR=%ROOT%backend-go"
set "FRONTEND_DIR=%ROOT%frontend"
set "BIN=%BACKEND_GO_DIR%\graw-go.exe"
set "LOG_DIR=%ROOT%logs"
set "LOG_FILE=%LOG_DIR%\graw.log"
set "PID_FILE=%LOG_DIR%\graw.pid"
set "RUNNER=%LOG_DIR%\graw-runner.cmd"
set "PORT=8000"
if defined GRAW_PORT set "PORT=%GRAW_PORT%"
set "HOST=0.0.0.0"
if defined GRAW_HOST set "HOST=%GRAW_HOST%"
set "ADDR=%HOST%:%PORT%"
if "%~1"=="" goto :usage
if /i "%~1"=="deps" goto :deps
if /i "%~1"=="build" goto :build
if /i "%~1"=="start" goto :start
if /i "%~1"=="stop" goto :stop
if /i "%~1"=="restart" goto :restart
if /i "%~1"=="status" goto :status
if /i "%~1"=="log" goto :log
goto :usage
:deps
where go >nul 2>nul
if errorlevel 1 (
echo [graw] Go not found. Please install Go 1.23+ first.
exit /b 1
)
echo [graw] Downloading Go modules (skipped if cached)...
pushd "%BACKEND_GO_DIR%"
call go mod download
set "DEPS_RC=%ERRORLEVEL%"
popd
if not "%DEPS_RC%"=="0" (
echo [graw] Go module download failed.
exit /b 1
)
if not exist "%FRONTEND_DIR%\node_modules" (
echo [graw] Installing frontend dependencies (npm install, slow at first time)...
pushd "%FRONTEND_DIR%"
call npm install --no-audit --no-fund
if errorlevel 1 (
popd
echo [graw] npm install failed.
exit /b 1
)
popd
)
echo [graw] Deps ready.
goto :eof
:build_frontend
if not exist "%FRONTEND_DIR%\node_modules" call :deps
if errorlevel 1 exit /b 1
echo [graw] Building frontend (npm run build)...
pushd "%FRONTEND_DIR%"
call npm run build
set "FE_RC=%ERRORLEVEL%"
popd
if not "%FE_RC%"=="0" (
echo [graw] Frontend build failed.
exit /b 1
)
goto :eof
:build_backend
echo [graw] Building Go backend (CGO_ENABLED=0)...
set "CGO_ENABLED=0"
pushd "%BACKEND_GO_DIR%"
call go build -trimpath -ldflags "-s -w" -o "%BIN%" .
set "BUILD_RC=%ERRORLEVEL%"
popd
set "CGO_ENABLED="
if not "%BUILD_RC%"=="0" (
echo [graw] Go build failed. See the output above.
exit /b 1
)
goto :eof
:build
call :deps
if errorlevel 1 exit /b 1
call :build_frontend
if errorlevel 1 exit /b 1
call :build_backend
if errorlevel 1 exit /b 1
goto :eof
:start
call :check_running
if "%RUNNING%"=="1" (
echo [graw] Already running, PID %DPID%. Use "graw.bat restart" to restart.
goto :eof
)
call :deps
if errorlevel 1 exit /b 1
if not exist "%FRONTEND_DIR%\dist\index.html" call :build_frontend
if errorlevel 1 exit /b 1
call :build_backend
if errorlevel 1 exit /b 1
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
rem Runner script keeps stdout/stderr in one log while the daemon stays detached
rem from the current console (closing this window does not stop the service).
> "%RUNNER%" (
echo @echo off
echo cd /d "%BACKEND_GO_DIR%"
echo "%BIN%" ^>^> "%LOG_FILE%" 2^>^&1
)
set "GRAW_ADDR=%ADDR%"
set "GRAW_DATA_DIR=%ROOT%backend\data"
set "GRAW_FRONTEND_DIST=%FRONTEND_DIR%\dist"
echo [graw] Starting daemon: graw-go on %ADDR% ...
powershell -NoProfile -Command "$p = Start-Process -FilePath 'cmd.exe' -ArgumentList '/c','graw-runner.cmd' -WorkingDirectory '%LOG_DIR%' -WindowStyle Hidden -PassThru; $p.Id | Out-File -Encoding ascii -NoNewline '%PID_FILE%'"
call :wait_healthy
goto :eof
:check_running
rem Check daemon state: read PID file and verify the process exists.
rem Result: RUNNING=0/1, DPID=pid.
set "RUNNING=0"
if not exist "%PID_FILE%" goto :eof
set /p DPID=<"%PID_FILE%"
tasklist /FI "PID eq %DPID%" 2>nul | find /i "%DPID%" >nul
if not errorlevel 1 set "RUNNING=1"
goto :eof
:stop
if not exist "%PID_FILE%" (
echo [graw] Not running.
goto :eof
)
set /p DPID=<"%PID_FILE%"
echo [graw] Stopping daemon (PID %DPID%)...
taskkill /PID %DPID% /T /F >nul 2>&1
del "%PID_FILE%" >nul 2>&1
echo [graw] Stopped.
goto :eof
:restart
call :stop
call :start
goto :eof
:status
if not exist "%PID_FILE%" (
echo [graw] Not running.
exit /b 1
)
set /p DPID=<"%PID_FILE%"
echo [graw] Running (PID %DPID%, port %PORT%).
curl -fsS -o nul --max-time 3 http://127.0.0.1:%PORT%/api/health >nul 2>&1
if errorlevel 1 (
echo [graw] Health check: not ready yet (see %LOG_FILE%).
) else (
echo [graw] Health check: OK.
)
goto :eof
:log
if not exist "%LOG_FILE%" (
echo [graw] No log yet: %LOG_FILE%
goto :eof
)
powershell -NoProfile -Command "Get-Content '%LOG_FILE%' -Tail 100 -Wait"
goto :eof
:wait_healthy
rem Poll /api/health up to 30s. DPID must be read BEFORE the for-block (batch
rem expands %DPID% at parse time of the whole block). Sleep via ping because
rem timeout requires an interactive console.
if exist "%PID_FILE%" set /p DPID=<"%PID_FILE%"
for /l %%i in (1,1,30) do (
curl -fsS -o nul --max-time 3 http://127.0.0.1:%PORT%/api/health >nul 2>&1
if not errorlevel 1 (
echo [graw] Started OK. Open: http://localhost:%PORT% Log: %LOG_FILE%
goto :eof
)
tasklist /FI "PID eq %DPID%" 2>nul | find /i "%DPID%" >nul
if errorlevel 1 (
echo [graw] Daemon exited unexpectedly. Check log: %LOG_FILE%
goto :eof
)
ping -n 2 127.0.0.1 >nul
)
echo [graw] Warning: health check not passed in 30s, confirm via %LOG_FILE%
goto :eof
:usage
echo Usage: graw.bat {deps^|build^|start^|stop^|restart^|status^|log}
echo deps download Go modules + npm dependencies
echo build build frontend dist and Go backend binary
echo start start as daemon (auto deps/build when missing)
echo stop stop daemon
echo restart stop + start
echo status process and health check
echo log tail log (Ctrl+C to exit)
exit /b 1