Eric Bower
·
2025-03-28
cfg.go
1package git
2
3import (
4 "fmt"
5 "log/slog"
6 "path/filepath"
7 "strings"
8 "time"
9
10 "github.com/charmbracelet/ssh"
11 "github.com/knadh/koanf/parsers/toml"
12 "github.com/knadh/koanf/providers/env"
13 "github.com/knadh/koanf/providers/file"
14 "github.com/knadh/koanf/v2"
15)
16
17var k = koanf.New(".")
18
19type GitCfg struct {
20 DataDir string `koanf:"data_dir"`
21 Url string `koanf:"url"`
22 Host string `koanf:"host"`
23 SshPort string `koanf:"ssh_port"`
24 WebPort string `koanf:"web_port"`
25 AdminsStr []string `koanf:"admins"`
26 Admins []ssh.PublicKey `koanf:"admins_pk"`
27 CreateRepo string `koanf:"create_repo"`
28 Theme string `koanf:"theme"`
29 TimeFormat string `koanf:"time_format"`
30 Desc string `koanf:"desc"`
31 Logger *slog.Logger
32}
33
34func LoadConfigFile(fpath string, logger *slog.Logger) {
35 fpp, err := filepath.Abs(fpath)
36 if err != nil {
37 panic(err)
38 }
39 logger.Info("loading configuration file", "fpath", fpp)
40
41 if err := k.Load(file.Provider(fpp), toml.Parser()); err != nil {
42 panic(fmt.Sprintf("error loading config: %v", err))
43 }
44}
45
46func NewGitCfg(logger *slog.Logger) *GitCfg {
47 err := k.Load(env.Provider("GITPR_", ".", func(s string) string {
48 keyword := strings.ToLower(strings.TrimPrefix(s, "GITPR_"))
49 return keyword
50 }), nil)
51 if err != nil {
52 panic(fmt.Sprintf("could not load environment variables: %v", err))
53 }
54
55 var out GitCfg
56 err = k.UnmarshalWithConf("", &out, koanf.UnmarshalConf{Tag: "koanf"})
57 if err != nil {
58 panic(fmt.Sprintf("could not unmarshal config: %v", err))
59 }
60
61 if len(out.AdminsStr) > 0 {
62 keys, err := GetAuthorizedKeys(out.AdminsStr)
63 if err == nil {
64 out.Admins = keys
65 } else {
66 panic(fmt.Sprintf("could not parse authorized keys file: %v", err))
67 }
68 } else {
69 logger.Info("no admin specified in config so no one can submit a review!")
70 }
71
72 // make datadir absolute
73 tmpdir := out.DataDir
74 if out.DataDir == "" {
75 tmpdir = "./data"
76 }
77 datadir, err := filepath.Abs(tmpdir)
78 out.DataDir = datadir
79 if err != nil {
80 panic(err)
81 }
82
83 if out.Host == "" {
84 out.Host = "0.0.0.0"
85 }
86
87 if out.SshPort == "" {
88 out.SshPort = "2222"
89 }
90
91 if out.WebPort == "" {
92 out.WebPort = "3000"
93 }
94
95 if out.Theme == "" {
96 out.Theme = "dracula"
97 }
98
99 if out.TimeFormat == "" {
100 out.TimeFormat = time.RFC3339
101 }
102
103 if out.CreateRepo == "" {
104 out.CreateRepo = "admin"
105 }
106
107 logger.Info(
108 "config",
109 "url", out.Url,
110 "data_dir", out.DataDir,
111 "host", out.Host,
112 "ssh_port", out.SshPort,
113 "web_port", out.WebPort,
114 "theme", out.Theme,
115 "time_format", out.TimeFormat,
116 "create_repo", out.CreateRepo,
117 "desc", out.Desc,
118 )
119
120 for _, pubkey := range out.AdminsStr {
121 logger.Info("admin", "pubkey", pubkey)
122 }
123
124 out.Logger = logger
125 return &out
126}