vanity/flags/flags.go

238 lines
5.8 KiB
Go
Raw Normal View History

package flags
import (
"net/url"
"os"
"regexp"
"strings"
"time"
"github.com/BurntSushi/toml"
"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"`
URL *url.URL `toml:"-"`
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: "Vanity 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: "BaseURL URL to service",
EnvVars: []string{"VANITY_BASE_URL"},
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)
if Config.BaseURL == "" {
switch strings.ToLower(Config.Service) {
case "gitea":
Config.BaseURL = "https://gitea.com"
case "github":
Config.BaseURL = "https://github.com"
case "gitlab":
Config.BaseURL = "https://gitlab.com"
}
}
u, err := url.Parse(Config.BaseURL)
if err != nil {
return err
}
Config.URL = u
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
}
}