package bell import ( "context" "errors" "fmt" "log/slog" "net/http" "os" "os/signal" "syscall" "git.ilapage.cn/ila/yovision/Bell/server/config" "git.ilapage.cn/ila/yovision/Bell/server/internal/platform" ) const Version = "0.1.0" func Run(ctx context.Context, args []string) error { command := "serve" if len(args) > 0 { command = args[0] } if command == "version" { fmt.Println(Version) return nil } if command != "serve" && command != "migrate" { return fmt.Errorf("unknown command %q (use serve, migrate, or version)", command) } cfg, err := config.Load() if err != nil { return err } db, err := platform.OpenDatabase(ctx, cfg.DatabaseURL) if err != nil { return err } defer db.Close() if err := platform.Migrate(ctx, db); err != nil { return err } if command == "migrate" { return nil } app := platform.NewHTTPApp(db) server := &http.Server{Addr: cfg.HTTPAddress, Handler: app.Handler()} serverCtx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) defer stop() go func() { <-serverCtx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout) defer cancel() _ = server.Shutdown(shutdownCtx) }() slog.Info("Bell listening", "address", cfg.HTTPAddress, "environment", cfg.Environment) if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { return err } return nil }