forked from scribble-rs/scribble.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
146 lines (132 loc) · 4.6 KB
/
config.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package config
import (
"fmt"
"log"
"os"
"reflect"
"strings"
"time"
"github.com/caarlos0/env/v9"
"github.com/subosito/gotenv"
)
type LobbySettingDefaults struct {
Public string `env:"PUBLIC"`
DrawingTime string `env:"DRAWING_TIME"`
Rounds string `env:"ROUNDS"`
MaxPlayers string `env:"MAX_PLAYERS"`
WordGroups string `env:"WORD_GROUPS"`
ClientsPerIPLimit string `env:"CLIENTS_PER_IP_LIMIT"`
Language string `env:"LANGUAGE"`
}
type CORS struct {
AllowedOrigins []string `env:"ALLOWED_ORIGINS"`
AllowCredentials bool `env:"ALLOW_CREDENTIALS"`
}
type LobbyCleanup struct {
// Interval is the interval in which the cleanup routine will run. If set
// to `0`, the cleanup routine will be disabled.
Interval time.Duration `env:"INTERVAL"`
// PlayerInactivityThreshold is the time after which a player counts as
// inactivity and won't keep the lobby up. Note that cleaning up a lobby can
// therefore take up to Interval + PlayerInactivityThreshold.
PlayerInactivityThreshold time.Duration `env:"PLAYER_INACTIVITY_THRESHOLD"`
}
type DbConfig struct {
Host string `env:"HOST"`
Port string `env:"PORT"`
User string `env:"USER"`
Password string `env:"PASSWORD"`
Database string `env:"DBNAME"`
SslMode string `env:"SSLMODE"`
}
type Config struct {
// NetworkAddress is empty by default, since that implies listening on
// all interfaces. For development usecases, on windows for example, this
// is very annoying, as windows will nag you with firewall prompts.
NetworkAddress string `env:"NETWORK_ADDRESS"`
// RootPath is the path directly after the domain and before the
// scribblers paths. For example if you host scribblers on painting.com
// but already host a different website on that domain, then your API paths
// might have to look like this: painting.com/scribblers/v1
RootPath string `env:"ROOT_PATH"`
CPUProfilePath string `env:"CPU_PROFILE_PATH"`
// LobbySettingDefaults is used for the server side rendering of the lobby
// creation page. It doesn't affect the default values of lobbies created
// via the API.
LobbySettingDefaults LobbySettingDefaults `envPrefix:"LOBBY_SETTING_DEFAULTS_"`
Port uint16 `env:"PORT"`
CORS CORS `envPrefix:"CORS_"`
LobbyCleanup LobbyCleanup `envPrefix:"LOBBY_CLEANUP_"`
Database DbConfig `envPrefix:"DB_CONFIG_"`
}
var Default = Config{
Port: 8080,
LobbySettingDefaults: LobbySettingDefaults{
Public: "false",
DrawingTime: "120",
Rounds: "4",
MaxPlayers: "12",
ClientsPerIPLimit: "1",
Language: "english",
},
CORS: CORS{
AllowedOrigins: []string{"*"},
AllowCredentials: false,
},
LobbyCleanup: LobbyCleanup{
Interval: 90 * time.Second,
PlayerInactivityThreshold: 75 * time.Second,
},
Database: DbConfig{
Host: "localhost",
Port: "5432",
User: "scribblers",
Password: "password",
Database: "scribblers",
SslMode: "require",
},
}
// Load loads the configuration from the environment. If a .env file is
// available, it will be loaded as well. Values found in the environment
// will overwrite whatever is load from the .env file.
func Load() (*Config, error) {
envVars := make(map[string]string)
dotEnvPath := ".env"
if _, err := os.Stat(dotEnvPath); err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("error checking for existence of .env file: %w", err)
}
} else {
envFileContent, err := gotenv.Read(dotEnvPath)
if err != nil {
return nil, fmt.Errorf("error reading .env file: %w", err)
}
for key, value := range envFileContent {
envVars[key] = value
}
}
// Add local environment variables to EnvVars map
for _, keyValuePair := range os.Environ() {
pair := strings.SplitN(keyValuePair, "=", 2)
// For some reason, gitbash can contain the variable `=::=::\` which
// gives us a pair where the first entry is empty.
if pair[0] == "" {
continue
}
envVars[pair[0]] = pair[1]
}
config := Default
if err := env.ParseWithOptions(&config, env.Options{
Environment: envVars,
OnSet: func(key string, value any, isDefault bool) {
if !reflect.ValueOf(value).IsZero() {
log.Printf("Setting '%s' to '%v' (isDefault: %v)\n", key, value, isDefault)
}
},
}); err != nil {
return nil, fmt.Errorf("error parsing environment variables: %w", err)
}
// Prevent user error and let the code decide when we need slashes.
config.RootPath = strings.Trim(config.RootPath, "/")
return &config, nil
}