Files
ai-workflow/inbox/internal/servercmd/run.go
T

92 lines
2.2 KiB
Go

package servercmd
import (
"flag"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
)
type Config struct {
WorkspacesDir string
ProjectRoot string
Port int
Addr string
}
type RunnerDeps struct {
StdErr io.Writer
InitRuntime func(Config) (io.Closer, error)
BuildMux func(Config) http.Handler
ListenAndServe func(string, http.Handler) error
}
func Run(args []string, deps RunnerDeps) error {
cfg, err := parseConfig(args)
if err != nil {
return err
}
if deps.BuildMux == nil {
return fmt.Errorf("server mux builder is not configured")
}
listenAndServe := deps.ListenAndServe
if listenAndServe == nil {
listenAndServe = http.ListenAndServe
}
stderr := deps.StdErr
if stderr == nil {
stderr = os.Stderr
}
return runWithConfig(cfg, deps, stderr, listenAndServe)
}
func parseConfig(args []string) (Config, error) {
flagSet := flag.NewFlagSet("server", flag.ExitOnError)
port := flagSet.Int("port", 3000, "HTTP server port")
wsDir := flagSet.String("workspaces-dir", "", "directory containing workspace worktrees (required)")
flagSet.Parse(args)
if *wsDir == "" {
return Config{}, fmt.Errorf("--workspaces-dir is required")
}
absDir, err := filepath.Abs(*wsDir)
if err != nil {
return Config{}, fmt.Errorf("resolving workspaces-dir: %w", err)
}
info, err := os.Stat(absDir)
if err != nil || !info.IsDir() {
return Config{}, fmt.Errorf("workspaces-dir does not exist or is not a directory: %s", absDir)
}
return Config{
WorkspacesDir: absDir,
ProjectRoot: filepath.Dir(absDir),
Port: *port,
Addr: fmt.Sprintf(":%d", *port),
}, nil
}
func runWithConfig(cfg Config, deps RunnerDeps, stderr io.Writer, listenAndServe func(string, http.Handler) error) error {
var closer io.Closer
var err error
if deps.InitRuntime != nil {
closer, err = deps.InitRuntime(cfg)
if err != nil {
return fmt.Errorf("opening central database: %w", err)
}
if closer != nil {
defer closer.Close()
}
}
handler := deps.BuildMux(cfg)
fmt.Fprintf(stderr, "inbox API server listening on http://localhost%s\n", cfg.Addr)
fmt.Fprintf(stderr, "workspaces dir: %s\n", cfg.WorkspacesDir)
return listenAndServe(cfg.Addr, handler)
}