package config import ( "flag" "fmt" "os" "github.com/peterbourgon/ff/v3" ) type Config struct { Github Github Port int } type Github struct { App App Token string APIv3URL string } type App struct { ID int64 `split_words:"true"` PrivateKey string `split_words:"true"` } func New() (*Config, error) { cfg := &Config{ Github: Github{App: App{}, APIv3URL: "https://api.github.com/"}, Port: 8080, } fs := flag.NewFlagSet("github-exporter", flag.ContinueOnError) // github config fs.Int64Var(&cfg.Github.App.ID, "github-app-id", 0, "integration ID for github app") // TODO: this should be a path to a private key fs.StringVar(&cfg.Github.App.PrivateKey, "github-app-private-key", "", "private key for github app") fs.StringVar(&cfg.Github.Token, "github-token", "", "github token to use for authentication. mutually exclusive with app config") // server config fs.IntVar(&cfg.Port, "port", cfg.Port, "port to serve on") if err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarNoPrefix()); err != nil { return nil, err } if err := cfg.Validate(); err != nil { return nil, err } return cfg, nil } func (c *Config) Validate() error { if c.Github.App == (App{}) && c.Github.Token == "" { return fmt.Errorf("either github app credentials or token is required") } return nil }