rin
Public Open-source lightweight git hosting.
config.go · 154 lines · 3.4 KB
Raw
1 package config
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strconv"
8 "strings"
9
10 "github.com/BurntSushi/toml"
11 )
12
13 type Config struct {
14 Server ServerConfig `toml:"server"`
15 Storage StorageConfig `toml:"storage"`
16 Auth AuthConfig `toml:"auth"`
17 Landing LandingConfig `toml:"landing"`
18 }
19
20 type ServerConfig struct {
21 Host string `toml:"host"`
22 Port int `toml:"port"`
23 BaseURL string `toml:"base_url"`
24 }
25
26 type StorageConfig struct {
27 DataDir string `toml:"data_dir"`
28 }
29
30 type AuthConfig struct {
31 RegistrationEnabled bool `toml:"registration_enabled"`
32 }
33
34 type LandingConfig struct {
35 Enabled bool `toml:"enabled"`
36 DefaultLang string `toml:"default_lang"`
37 }
38
39 func Default() Config {
40 return Config{
41 Server: ServerConfig{
42 Host: "0.0.0.0",
43 Port: 3000,
44 BaseURL: "http://localhost:3000",
45 },
46 Storage: StorageConfig{
47 DataDir: "./data",
48 },
49 Auth: AuthConfig{
50 RegistrationEnabled: true,
51 },
52 Landing: LandingConfig{
53 Enabled: true,
54 DefaultLang: "ru",
55 },
56 }
57 }
58
59 func Load(configPath string) (Config, error) {
60 cfg := Default()
61
62 if envPath := os.Getenv("POLAR_CONFIG"); envPath != "" && configPath == "" {
63 configPath = envPath
64 }
65 if configPath == "" {
66 if _, err := os.Stat("polar.toml"); err == nil {
67 configPath = "polar.toml"
68 }
69 }
70
71 if configPath != "" {
72 data, err := os.ReadFile(configPath)
73 if err != nil {
74 return cfg, fmt.Errorf("read config file %s: %w", configPath, err)
75 }
76 if err := toml.Unmarshal(data, &cfg); err != nil {
77 return cfg, fmt.Errorf("parse config file %s: %w", configPath, err)
78 }
79 }
80
81 applyEnv(&cfg)
82
83 cfg.Server.BaseURL = strings.TrimRight(cfg.Server.BaseURL, "/")
84 if cfg.Server.BaseURL == "" {
85 host := cfg.Server.Host
86 if host == "0.0.0.0" || host == "" {
87 host = "localhost"
88 }
89 cfg.Server.BaseURL = fmt.Sprintf("http://%s:%d", host, cfg.Server.Port)
90 }
91 if cfg.Landing.DefaultLang != "en" && cfg.Landing.DefaultLang != "ru" {
92 cfg.Landing.DefaultLang = "ru"
93 }
94
95 return cfg, nil
96 }
97
98 func applyEnv(cfg *Config) {
99 getEnv := os.Getenv
100
101 if v := getEnv("POLAR_SERVER_HOST"); v != "" {
102 cfg.Server.Host = v
103 }
104 if v := getEnv("POLAR_HOST"); v != "" {
105 cfg.Server.Host = v
106 }
107 if v := getEnv("POLAR_SERVER_PORT"); v != "" {
108 if p, err := strconv.Atoi(v); err == nil && p > 0 {
109 cfg.Server.Port = p
110 }
111 }
112 if v := getEnv("POLAR_PORT"); v != "" {
113 if p, err := strconv.Atoi(v); err == nil && p > 0 {
114 cfg.Server.Port = p
115 }
116 }
117 if v := getEnv("POLAR_SERVER_BASE_URL"); v != "" {
118 cfg.Server.BaseURL = v
119 }
120 if v := getEnv("POLAR_BASE_URL"); v != "" {
121 cfg.Server.BaseURL = v
122 }
123 if v := getEnv("POLAR_STORAGE_DATA_DIR"); v != "" {
124 cfg.Storage.DataDir = v
125 }
126 if v := getEnv("POLAR_DATA_DIR"); v != "" {
127 cfg.Storage.DataDir = v
128 }
129 if v := getEnv("POLAR_AUTH_REGISTRATION_ENABLED"); v != "" {
130 if b, err := strconv.ParseBool(v); err == nil {
131 cfg.Auth.RegistrationEnabled = b
132 }
133 }
134 if v := getEnv("POLAR_LANDING_ENABLED"); v != "" {
135 if b, err := strconv.ParseBool(v); err == nil {
136 cfg.Landing.Enabled = b
137 }
138 }
139 if v := getEnv("POLAR_LANDING_DEFAULT_LANG"); v != "" {
140 cfg.Landing.DefaultLang = strings.ToLower(strings.TrimSpace(v))
141 }
142 }
143
144 func (c Config) Addr() string {
145 return fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port)
146 }
147
148 func (c Config) DBPath() string {
149 return filepath.Join(c.Storage.DataDir, "polar.db")
150 }
151
152 func (c Config) ReposDir() string {
153 return filepath.Join(c.Storage.DataDir, "repos")
154 }
155