From 333e999d76c1f0479a8ed4c6846d6838dde01e8e Mon Sep 17 00:00:00 2001 From: panw Date: Tue, 31 Mar 2026 16:24:36 +0800 Subject: [PATCH] feat: wire up main server with all routes Co-Authored-By: Claude Opus 4.6 --- main.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/main.go b/main.go index 828eb9b..da3313e 100644 --- a/main.go +++ b/main.go @@ -4,29 +4,114 @@ import ( "flag" "fmt" "log" + "os" + + "github.com/gin-gonic/gin" + "golang.org/x/crypto/bcrypt" + "gitm/internal/config" + "gitm/internal/database" + "gitm/internal/handler" + "gitm/internal/middleware" + "gitm/internal/sync" ) var ( - flagAddr = flag.String("addr", ":9000", "Listen address") - flagDataDir = flag.String("data", "./data", "Data directory") + flagAddr = flag.String("addr", "", "Listen address") + flagDataDir = flag.String("data", "", "Data directory") flagInit = flag.Bool("init", false, "Initialize database and set password") ) func main() { flag.Parse() + cfg := config.Get() + if *flagDataDir != "" { + cfg.SetDataDir(*flagDataDir) + } else { + cfg.SetDataDir(cfg.DataDir) + } + if *flagAddr != "" { + cfg.ListenAddr = *flagAddr + } + if err := cfg.EnsureDirs(); err != nil { + log.Fatalf("Failed to create directories: %v", err) + } + if err := database.Initialize(cfg.DBPath); err != nil { + log.Fatalf("Failed to initialize database: %v", err) + } + defer database.Close() - fmt.Printf("GitM - Gitea Repository Sync Tool\n") - fmt.Printf("Listen: %s\n", *flagAddr) - fmt.Printf("Data: %s\n", *flagDataDir) + if listenAddr, err := database.GetSetting("listen_addr"); err == nil && listenAddr != "" { + cfg.ListenAddr = listenAddr + } + maxConcurrent := 3 + if maxStr, err := database.GetSetting("max_concurrent"); err == nil && maxStr != "" { + fmt.Sscanf(maxStr, "%d", &maxConcurrent) + } + + engine := sync.NewEngine(maxConcurrent) + scheduler := sync.NewScheduler(engine) if *flagInit { - fmt.Println("Initialize mode: TODO") + runInitMode() return } - log.Fatal(runServer()) + if pwd, _ := database.GetSetting("admin_password"); pwd == "" { + fmt.Println("Not initialized. Please run with --init flag first.") + os.Exit(1) + } + + middleware.SetJWTSecret("gitm-default-secret") + scheduler.ReloadAll() + scheduler.Start() + defer scheduler.Stop() + + log.Printf("GitM starting on %s", cfg.ListenAddr) + log.Fatal(runServer(cfg, engine)) } -func runServer() error { - return fmt.Errorf("not implemented") +func runInitMode() { + var password string + fmt.Print("Enter admin password: ") + fmt.Scanln(&password) + if password == "" { + log.Fatal("Password cannot be empty") + } + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + log.Fatalf("Failed to hash password: %v", err) + } + database.SetSetting("admin_password", string(hash)) + database.SetSetting("listen_addr", ":9000") + database.SetSetting("max_concurrent", "3") + fmt.Println("Initialized successfully!") +} + +func runServer(cfg *config.Config, engine *sync.Engine) error { + gin.SetMode(gin.ReleaseMode) + r := gin.Default() + api := r.Group("/api") + { + api.POST("/login", handler.HandleLogin) + api.POST("/init", handler.HandleInit) + protected := api.Group("") + protected.Use(middleware.AuthMiddleware()) + { + protected.GET("/settings", handler.HandleGetSettings) + protected.PUT("/settings", handler.HandleUpdateSettings) + protected.GET("/servers", handler.HandleListServers) + protected.POST("/servers", handler.HandleCreateServer) + protected.PUT("/servers/:id", handler.HandleUpdateServer) + protected.DELETE("/servers/:id", handler.HandleDeleteServer) + protected.POST("/servers/:id/test", handler.HandleTestConnection) + protected.GET("/servers/:id/repos", handler.HandleListRepos) + protected.POST("/servers/:id/discover", handler.HandleDiscoverRepos) + protected.POST("/servers/:id/sync", handler.HandleSyncServer(engine)) + protected.GET("/servers/:id/sync/status", handler.HandleGetSyncStatus(engine)) + protected.POST("/sync/all", handler.HandleSyncAll(engine)) + protected.GET("/sync/logs", handler.HandleGetSyncLogs) + protected.GET("/sync/stats", handler.HandleGetStats) + } + } + return r.Run(cfg.ListenAddr) }