2026-02-18 13:48:29 -08:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2026-02-18 23:27:27 -07:00
|
|
|
"context"
|
2026-02-18 13:48:29 -08:00
|
|
|
"embed"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io/fs"
|
2026-02-18 23:27:27 -07:00
|
|
|
"net"
|
2026-02-18 13:48:29 -08:00
|
|
|
"net/http"
|
|
|
|
|
"os"
|
2026-02-18 23:27:27 -07:00
|
|
|
"os/exec"
|
|
|
|
|
"strings"
|
2026-02-18 13:48:29 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
//go:embed static
|
|
|
|
|
var staticFS embed.FS
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
addr := ":8080"
|
2026-02-18 23:27:27 -07:00
|
|
|
var runAndExit []string
|
|
|
|
|
|
|
|
|
|
for _, arg := range os.Args[1:] {
|
|
|
|
|
if v, ok := strings.CutPrefix(arg, "--run-and-exit="); ok {
|
|
|
|
|
runAndExit = strings.Fields(v)
|
|
|
|
|
} else {
|
|
|
|
|
addr = arg
|
|
|
|
|
}
|
2026-02-18 13:48:29 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub, err := fs.Sub(staticFS, "static")
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
http.Handle("/", http.FileServer(http.FS(sub)))
|
|
|
|
|
|
2026-02-18 23:27:27 -07:00
|
|
|
if len(runAndExit) > 0 {
|
|
|
|
|
ln, err := net.Listen("tcp", addr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
srv := &http.Server{}
|
|
|
|
|
go srv.Serve(ln)
|
|
|
|
|
|
|
|
|
|
cmd := exec.Command(runAndExit[0], runAndExit[1:]...)
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
cmdErr := cmd.Run()
|
|
|
|
|
srv.Shutdown(context.Background())
|
|
|
|
|
if cmdErr != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", cmdErr)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-18 13:48:29 -08:00
|
|
|
fmt.Printf("Listening on %s\n", addr)
|
|
|
|
|
if err := http.ListenAndServe(addr, nil); err != nil {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
}
|