package cli import ( "code.mrmelon54.com/melon/summer/pkg/utils" "flag" "fmt" _ "github.com/go-sql-driver/mysql" "gopkg.in/yaml.v3" "log" "math/rand" "os" "os/signal" "syscall" "time" "xorm.io/xorm" ) func Run(software, dbString string, executor Executor[any]) { preSetup(software, nil) postSetup[any](software, dbString, nil, executor) } func RunWithConfig[T any](software string, dbFunc func(t T) string, executor Executor[T]) { var configPath string preSetup(software, &configPath) open, err := os.Open(configPath) utils.Check("Failed to open config file", err) decoder := yaml.NewDecoder(open) t := *new(T) utils.Check("Failed to decode config file", decoder.Decode(&t)) postSetup(software, dbFunc(t), t, executor) } func preSetup(software string, configPath *string) { rand.Seed(time.Now().UnixMilli()) var version bool flag.BoolVar(&version, "version", false, "Show program version") if configPath != nil { flag.StringVar(configPath, "config", fmt.Sprintf("/etc/melon-summer/%s.config.yml", software), fmt.Sprintf("Path to config file for %s", software)) } flag.Parse() if version { fmt.Printf("%s %s\n", software, utils.BuildVersion) return } } func postSetup[T any](software string, dbString string, t T, executor Executor[T]) { log.Printf("[Main] Starting up %s (%s from %s)\n", software, utils.BuildVersion, utils.BuildDate) // Load database engine, err := xorm.NewEngine("mysql", dbString) utils.Check("Failed to connect to database", err) // Start runner runner := &Runner[T]{software: software, executor: executor, Config: t, Database: engine} executor.Init(runner) // Wait for exit signal sc := make(chan os.Signal, 1) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) <-sc fmt.Println() // Stop runner log.Printf("[Main] Stopping " + software) n := time.Now() executor.Destroy() log.Printf("[Main] Took '%s' to shutdown\n", time.Now().Sub(n)) log.Println("[Main] Goodbye") } type Executor[T any] interface { Init(*Runner[T]) Destroy() } type Runner[T any] struct { software string executor Executor[T] Config T Database *xorm.Engine }