2020-09-10 17:27:46 +00:00
|
|
|
package flags
|
|
|
|
|
|
|
|
import (
|
2020-09-10 18:43:38 +00:00
|
|
|
"net/url"
|
2020-09-10 17:27:46 +00:00
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2020-09-10 18:43:38 +00:00
|
|
|
"github.com/BurntSushi/toml"
|
2020-09-10 17:27:46 +00:00
|
|
|
"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"`
|
2020-09-10 18:43:38 +00:00
|
|
|
URL *url.URL `toml:"-"`
|
2020-09-10 17:27:46 +00:00
|
|
|
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",
|
2020-09-10 18:43:38 +00:00
|
|
|
Usage: "Vanity domain, e.g. go.domain.tld",
|
2020-09-10 17:27:46 +00:00
|
|
|
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",
|
2020-09-10 18:43:38 +00:00
|
|
|
Usage: "BaseURL URL to service",
|
2020-09-10 17:27:46 +00:00
|
|
|
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)
|
|
|
|
|
2020-09-10 18:43:38 +00:00
|
|
|
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
|
|
|
|
|
2020-09-10 17:27:46 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|