package main import ( "flag" "log" "net/http" "time" mux "github.com/gorilla/mux" errors "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) type ParsedArguments struct { databaseName string } var appConfig ParsedArguments var db *bolt.DB func main() { // Parse the arguments and construct the ParsedArguments appConfigRef, err := parseArguments() if err != nil { log.Fatal(err) } appConfig = *appConfigRef // Open the bolt database db, err = bolt.Open(appConfig.databaseName, 0666, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { decoratedErr := errors.Wrapf(err, "failed to open database at '%v'", appConfig.databaseName) log.Fatal(decoratedErr) } defer db.Close() err = db.Update(migrateDatabase) if err != nil { decoratedErr := errors.Wrapf(err, "failed to migrate database") log.Fatal(decoratedErr) } // Initialize Gorilla router router := mux.NewRouter() router.HandleFunc("/", indexGetHandler).Methods("GET") router.HandleFunc("/", indexPostHandler).Methods("POST") router.HandleFunc("/{key:[A-Za-z0-9-_]{4,}}", redirectHandler).Methods("GET") // Start the server srv := &http.Server{ Handler: router, Addr: "127.0.0.1:8000", WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } log.Fatal(srv.ListenAndServe()) } // Parse the input arguments and return the initialized application config struct func parseArguments() (*ParsedArguments, error) { config := ParsedArguments{} flag.StringVar(&config.databaseName, "database", "", "Location of the database file") flag.Parse() if config.databaseName == "" { return nil, errors.New("database not set") } return &config, nil }