package config import ( "deploy/pkg/set" "deploy/pkg/tools" "fmt" "strings" errors "github.com/pkg/errors" "github.com/robfig/cron/v3" confLoader "github.com/otakukaze/config-loader" ) type Config struct { Server Server `yaml:"server"` Listens []Listen `yaml:"listens"` CronJobs []CronJob `yaml:"cron_jobs"` } type Server struct { Port int `yaml:"port" env:"SERVER_PORT" default:"10230"` } type CronJob struct { CronTime string `yaml:"cron_time"` Script string `yaml:"script"` } type Listen struct { HTTP *HTTPListen `yaml:"http"` } type HTTPListen struct { Method string `yaml:"method"` Path string `yaml:"path"` Headers map[string]string `yaml:"headers"` Script string `yaml:"script"` } func Load(p ...string) (*Config, error) { cfg := &Config{} opts := &confLoader.LoadOptions{ FromEnv: true, } // check path exists if len(p) > 0 && p[0] != "" { if !tools.CheckExists(p[0], false) { return nil, errors.New("config not exist") } opts.ConfigFile = &confLoader.ConfigFile{ Type: confLoader.ConfigFileTypeYAML, Path: tools.ParsePath(p[0]), } } if err := confLoader.Load(&cfg, opts); err != nil { return nil, err } // check all listen path and script pathSet := set.NewSet() for _, v := range cfg.Listens { if v.HTTP == nil { continue } key := fmt.Sprintf("%s-%s", v.HTTP.Method, v.HTTP.Path) if pathSet.Has(key) { return nil, errors.WithStack(fmt.Errorf("path is duplicate: %s\n", v.HTTP.Path)) } v.HTTP.Method = strings.ToUpper(v.HTTP.Method) // check method support switch v.HTTP.Method { case "GET": case "POST": break default: return nil, errors.WithStack(fmt.Errorf("http method (%s) not support", v.HTTP.Method)) } pathSet.Add(key) // check script exists if !tools.CheckExists(v.HTTP.Script, false) { return nil, errors.WithStack(fmt.Errorf("path (%s) script not exists: %s\n", v.HTTP.Path, v.HTTP.Script)) } } // check cronJob cronParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) for _, v := range cfg.CronJobs { _, err := cronParser.Parse(v.CronTime) if err != nil { return nil, err } // check script exists if !tools.CheckExists(v.Script, false) { return nil, errors.WithStack(fmt.Errorf("cron (%s) script not exists: %s\n", v.CronTime, v.Script)) } } return cfg, nil }