76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"go.jolheiser.com/vanity/server/database"
|
|
"go.jolheiser.com/vanity/server/router"
|
|
|
|
"github.com/peterbourgon/ff/v3"
|
|
"github.com/peterbourgon/ff/v3/ffcli"
|
|
"github.com/peterbourgon/ff/v3/fftoml"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func New() *ffcli.Command {
|
|
fs := flag.NewFlagSet("vanity", flag.ExitOnError)
|
|
portFlag := fs.Int("port", 3333, "Port to run the vanity server on")
|
|
domainFlag := fs.String("domain", "", "The Go module domain (e.g. go.jolheiser.com)")
|
|
tokenFlag := fs.String("token", "", "vanity auth token to use")
|
|
dbFlag := fs.String("database", dbPath(), "The path to the database")
|
|
|
|
cmd := &ffcli.Command{
|
|
Name: "vanity",
|
|
ShortUsage: "vanity",
|
|
ShortHelp: "Vanity Server",
|
|
LongHelp: "Vanity Server to serve the Go module vanity domain",
|
|
FlagSet: fs,
|
|
Options: []ff.Option{
|
|
ff.WithEnvVarPrefix("VANITY"),
|
|
ff.WithAllowMissingConfigFile(true),
|
|
ff.WithConfigFileFlag("config"),
|
|
ff.WithConfigFileParser(fftoml.New().Parse),
|
|
},
|
|
Exec: server(portFlag, domainFlag, tokenFlag, dbFlag),
|
|
}
|
|
return cmd
|
|
}
|
|
|
|
func server(port *int, domain, token, dbPath *string) func(context.Context, []string) error {
|
|
return func(ctx context.Context, args []string) error {
|
|
if *token == "" || *domain == "" {
|
|
return errors.New("vanity server requires --token and --domain")
|
|
}
|
|
|
|
db, err := database.Load(*dbPath)
|
|
if err != nil {
|
|
log.Fatal().Msgf("could not load database at %s: %v", *dbPath, err)
|
|
}
|
|
|
|
log.Info().Msgf("Running vanity server at http://localhost:%d", *port)
|
|
if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), router.New(*token, *domain, db)); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func dbPath() string {
|
|
fn := "vanity.db"
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
bin, err := os.Executable()
|
|
if err != nil {
|
|
return fn
|
|
}
|
|
return filepath.Join(filepath.Dir(bin), fn)
|
|
}
|
|
return filepath.Join(home, fn)
|
|
}
|