generated from bool64/go-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcmd.go
101 lines (79 loc) · 2.46 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package brick
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"os"
"github.com/bool64/brick/config"
"github.com/bool64/dev/version"
"github.com/swaggest/assertjson"
)
// StartOptions allows more control on application startup.
type StartOptions struct {
// EnvPrefix is the prefix for environment variables.
EnvPrefix string
// EnvPrepare is called after all config loaders and before envconfig.Process,
// it can be used to override defaults via env vars.
EnvPrepare func() error
// NoHTTP instructs application to exit instead of starting HTTP server.
NoHTTP bool
// OnHTTPStart is called after the HTTP server is started.
OnHTTPStart func(addr string)
}
// Start loads config and runs application with provided service locator and http router.
func Start(cfg WithBaseConfig, init func(docsMode bool) (*BaseLocator, http.Handler), options ...func(o *StartOptions)) { //nolint:cyclop
ver := flag.Bool("version", false, "Print application version and exit.")
docs := flag.Bool("openapi", false, "Print application OpenAPI spec and exit.")
confFile := flag.String("conf", "", "Config file with ENV variables to load.")
flag.Parse()
if ver != nil && *ver {
fmt.Println(version.Info().Version)
return
}
if docs != nil && *docs {
loc, _ := init(true)
j, err := assertjson.MarshalIndentCompact(loc.OpenAPI.Reflector().Spec, "", " ", 100)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(j))
return
}
opt := StartOptions{}
for _, o := range options {
o(&opt)
}
loadConfig(opt.EnvPrefix, confFile, cfg, opt.EnvPrepare)
loc, router := init(false)
if !opt.NoHTTP {
addr, err := loc.StartHTTPServer(router)
if err != nil {
loc.CtxdLogger().Error(context.Background(), "failed to start http server: %v", "error", err)
os.Exit(1)
}
if opt.OnHTTPStart != nil {
opt.OnHTTPStart(addr)
}
} else {
loc.Shutdown()
}
// Wait for service locator termination finished.
err := <-loc.Wait()
if err != nil {
loc.CtxdLogger().Error(context.Background(), err.Error())
}
}
func loadConfig(envPrefix string, conf *string, cfg WithBaseConfig, envPrepare func() error) {
var cfgLoaders []func() error
if conf != nil && *conf != "" && *conf != ".env" {
cfgLoaders = append(cfgLoaders, config.WithEnvFiles(*conf))
} else {
cfgLoaders = config.DefaultLoaders(envPrefix)
}
cfgLoaders = append(cfgLoaders, envPrepare)
if err := config.Load(envPrefix, cfg, cfgLoaders...); err != nil {
log.Fatalf("failed to load config: %v", err)
}
}