package main import ( "flag" "html/template" "log" "net/http" "os" "strings" "time" "github.com/BurntSushi/toml" ) func main() { if err := run(); err != nil { log.Fatal(err) } } type duration struct { time.Duration } func (d *duration) UnmarshalText(text []byte) error { var err error d.Duration, err = time.ParseDuration(string(text)) return err } type options struct { BindAddress string `toml:"bind_address"` CacheExpiry duration `toml:"cache_expiry"` UpstreamTimeout duration `toml:"upstream_timeout"` SourcehutUsername string `toml:"srht_username"` SourcehutToken string `toml:"srht_token"` GithubUsername string `toml:"github_username"` GithubToken string `toml:"github_token"` CanonicalPrefix string `toml:"canonical_prefix"` } func run() error { cfgPath := flag.String("c", "", "path to configuration file") flag.Parse() if cfgPath == nil || *cfgPath == "" { flag.Usage() os.Exit(1) } var opts options if _, err := toml.DecodeFile(*cfgPath, &opts); err != nil { return err } log.Printf("caches expire after %s", opts.CacheExpiry.Duration) log.Printf("upstream reqs time out after %s", opts.UpstreamTimeout.Duration) cache := &PackageCache{ CanonicalPrefix: opts.CanonicalPrefix, ExpireAfter: opts.CacheExpiry.Duration, UpstreamTimeout: opts.UpstreamTimeout.Duration, Logger: log.New(os.Stdout, "", log.LstdFlags), Hosts: []RepoHost{ Sourcehut{Username: opts.SourcehutUsername, Token: opts.SourcehutToken}, Github{Username: opts.GithubUsername, Token: opts.GithubToken}, }, } handler := handlePackage(cache) log.Printf("starting server to listen on %s...", opts.BindAddress) return http.ListenAndServe(opts.BindAddress, handler) } func handlePackage(pkgs *PackageCache) http.HandlerFunc { tmpl, err := template.New("package").Parse(`