package flags import ( "github.com/BurntSushi/toml" "os" "regexp" "strings" "time" "github.com/urfave/cli/v2" "go.jolheiser.com/beaver" ) type flagConfig struct { Port int `toml:"port"` Domain string `toml:"domain"` Service string `toml:"service"` BaseURL string `toml:"base_url"` Namespace string `toml:"namespace"` Token string `toml:"token"` Include []*regexp.Regexp `toml:"-"` Exclude []*regexp.Regexp `toml:"-"` Private bool `toml:"private"` Fork bool `toml:"fork"` Mirror bool `toml:"mirror"` Archive bool `toml:"archive"` Interval time.Duration `toml:"interval"` Debug bool `toml:"debug"` Overrides map[string]nameOverride `toml:"overrides"` } type nameOverride struct { Name string `toml:"name"` } var ( Config = flagConfig{ Overrides: make(map[string]nameOverride), } configPath string include cli.StringSlice exclude cli.StringSlice ) var Flags = []cli.Flag{ &cli.StringFlag{ Name: "config", Usage: "Path to a config file", EnvVars: []string{"VANITY_CONFIG"}, Destination: &configPath, }, &cli.IntFlag{ Name: "port", Usage: "Port to run the vanity server on", Value: 7777, EnvVars: []string{"VANITY_PORT"}, Destination: &Config.Port, }, &cli.StringFlag{ Name: "domain", Usage: "Domain, e.g. go.domain.tld", EnvVars: []string{"VANITY_DOMAIN"}, Required: true, Destination: &Config.Domain, }, &cli.StringFlag{ Name: "service", Usage: "Service type (Gitea, GitHub, GitLab)", Value: "gitea", EnvVars: []string{"VANITY_SERVICE"}, Destination: &Config.Service, }, &cli.StringFlag{ Name: "base-url", Usage: "Base URL to service", EnvVars: []string{"VANITY_BASE_URL"}, Required: true, Destination: &Config.BaseURL, }, &cli.StringFlag{ Name: "namespace", Usage: "Owner namespace", EnvVars: []string{"VANITY_NAMESPACE"}, Required: true, Destination: &Config.Namespace, }, &cli.StringFlag{ Name: "token", Usage: "Access token", EnvVars: []string{"VANITY_TOKEN"}, Required: true, Destination: &Config.Token, }, &cli.StringSliceFlag{ Name: "include", Usage: "Repository names to include (regex)", EnvVars: []string{"VANITY_INCLUDE"}, Destination: &include, }, &cli.StringSliceFlag{ Name: "exclude", Usage: "Repository names to exclude (regex)", EnvVars: []string{"VANITY_EXCLUDE"}, Destination: &exclude, }, &cli.BoolFlag{ Name: "private", Usage: "Include private repositories", EnvVars: []string{"VANITY_PRIVATE"}, Destination: &Config.Private, }, &cli.BoolFlag{ Name: "fork", Usage: "Include forked repositories", EnvVars: []string{"VANITY_FORK"}, Destination: &Config.Private, }, &cli.BoolFlag{ Name: "mirror", Usage: "Include mirrored repositories", EnvVars: []string{"VANITY_MIRROR"}, Destination: &Config.Mirror, }, &cli.BoolFlag{ Name: "archive", Usage: "Include archived repositories", EnvVars: []string{"VANITY_ARCHIVE"}, Destination: &Config.Archive, }, &cli.DurationFlag{ Name: "interval", Usage: "Interval between updating repositories", Value: time.Minute * 15, EnvVars: []string{"VANITY_INTERVAL"}, Destination: &Config.Interval, }, &cli.BoolFlag{ Name: "debug", Usage: "Debug logging", EnvVars: []string{"VANITY_DEBUG"}, Destination: &Config.Debug, }, } func Before(ctx *cli.Context) error { setConfig(ctx) Config.Include = make([]*regexp.Regexp, len(include.Value())) for idx, i := range include.Value() { Config.Include[idx] = regexp.MustCompile(i) } Config.Exclude = make([]*regexp.Regexp, len(exclude.Value())) for idx, e := range exclude.Value() { Config.Exclude[idx] = regexp.MustCompile(e) } if Config.Debug { beaver.Console.Level = beaver.DEBUG } return nil } func setConfig(ctx *cli.Context) { for _, env := range os.Environ() { kv := strings.Split(env, "=") if strings.HasPrefix(kv[0], "VANITY_OVERRIDES_") { override := strings.ToLower(strings.TrimPrefix(kv[0], "VANITY_OVERRIDES_")) Config.Overrides[override] = nameOverride{kv[1]} } } var cfg flagConfig if configPath != "" { beaver.Infof("Loading configuration from %s", configPath) _, err := toml.DecodeFile(configPath, &cfg) if err != nil { beaver.Errorf("Could not load configuration from %s: %v", configPath, err) return } } if !ctx.IsSet("port") && cfg.Port > 0 { Config.Port = cfg.Port } if !ctx.IsSet("domain") && cfg.Domain != "" { Config.Domain = cfg.Domain } if !ctx.IsSet("service") && cfg.Service != "" { Config.Service = cfg.Service } if !ctx.IsSet("base-url") && cfg.BaseURL != "" { Config.BaseURL = cfg.BaseURL } if !ctx.IsSet("namespace") && cfg.Namespace != "" { Config.Namespace = cfg.Namespace } if !ctx.IsSet("token") && cfg.Token != "" { Config.Token = cfg.Token } if !ctx.IsSet("private") && cfg.Private { Config.Private = cfg.Private } if !ctx.IsSet("fork") && cfg.Fork { Config.Fork = cfg.Fork } if !ctx.IsSet("mirror") && cfg.Mirror { Config.Mirror = cfg.Mirror } if !ctx.IsSet("archive") && cfg.Archive { Config.Archive = cfg.Archive } if !ctx.IsSet("debug") && cfg.Debug { Config.Debug = cfg.Debug } }