mirror of
https://codeberg.org/june64/mrvc.git
synced 2026-01-11 08:16:33 +01:00
refactor config building into separate package for better organization
This commit is contained in:
parent
f939294723
commit
5ca794f435
2 changed files with 132 additions and 78 deletions
123
config/config.go
Normal file
123
config/config.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type configOption[T any] struct {
|
||||
flagName string
|
||||
flagDefaultValue T
|
||||
flagHelpBase string
|
||||
envVarName string
|
||||
}
|
||||
|
||||
type configOptions struct {
|
||||
userID configOption[string]
|
||||
token configOption[string]
|
||||
room configOption[string]
|
||||
printHomeserverMemberCount configOption[bool]
|
||||
homeserverVersionInfoTimeout configOption[time.Duration]
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
UserID string
|
||||
Token string
|
||||
Room string
|
||||
PrintHomeserverMemberCount bool
|
||||
HomeserverVersionInfoTimeout time.Duration
|
||||
}
|
||||
|
||||
var configOpts = configOptions{
|
||||
userID: configOption[string]{"user-id", "", "The Matrix user ID to use.", "MRVC_USER_ID"},
|
||||
token: configOption[string]{"token", "", "The Matrix access token to use.", "MRVC_TOKEN"},
|
||||
room: configOption[string]{"room", "", "The Matrix room to check.", "MRVC_ROOM"},
|
||||
printHomeserverMemberCount: configOption[bool]{"print-homeserver-member-count", false, "Print the member count for each homeserver.", "MRVC_PRINT_HOMESERVER_MEMBER_COUNT"},
|
||||
homeserverVersionInfoTimeout: configOption[time.Duration]{"homeserver-version-info-timeout", time.Second * 5, "Timeout for getting the homeservers version information per homeserver.", "MRVC_HOMESERVER_VERSION_INFO_TIMEOUT"},
|
||||
}
|
||||
|
||||
func (configOpt configOption[T]) getFlagHelp() string {
|
||||
return fmt.Sprintf("%s (EnvVar: %s)", configOpt.flagHelpBase, configOpt.envVarName)
|
||||
}
|
||||
|
||||
func (configOpt configOption[T]) getFlagArgs() (string, T, string) {
|
||||
return configOpt.flagName, configOpt.flagDefaultValue, configOpt.getFlagHelp()
|
||||
}
|
||||
|
||||
// Functions for getting config values from flags and environment variables.
|
||||
// Flags take precedence over environment variables.
|
||||
func (configOpt configOption[T]) getConfigValueWithDefault(configFlag *T, visitedFlags map[string]bool, envVarParser func(string) T) T {
|
||||
if visitedFlags[configOpt.flagName] {
|
||||
return *configFlag
|
||||
} else if envVar, ok := os.LookupEnv(configOpt.envVarName); ok {
|
||||
return envVarParser(envVar)
|
||||
} else {
|
||||
return configOpt.flagDefaultValue
|
||||
}
|
||||
}
|
||||
|
||||
// This function can be used to ensure some configuration options got explicitly set.
|
||||
func (configOpt configOption[T]) getConfigValueWithError(configFlag *T, visitedFlags map[string]bool, envVarParser func(string) T) (T, error) {
|
||||
if visitedFlags[configOpt.flagName] {
|
||||
return *configFlag, nil
|
||||
} else if envVar, ok := os.LookupEnv(configOpt.envVarName); ok {
|
||||
return envVarParser(envVar), nil
|
||||
} else {
|
||||
return configOpt.flagDefaultValue, errors.New("no command-line flag or environment variable set")
|
||||
}
|
||||
}
|
||||
|
||||
var userIdFlag = flag.String(configOpts.userID.getFlagArgs())
|
||||
var tokenFlag = flag.String(configOpts.token.getFlagArgs())
|
||||
var roomFlag = flag.String(configOpts.room.getFlagArgs())
|
||||
var printHomeserverMemberCountFlag = flag.Bool(configOpts.printHomeserverMemberCount.getFlagArgs())
|
||||
var homeserverVersionInfoTimeoutFlag = flag.Duration(configOpts.homeserverVersionInfoTimeout.getFlagArgs())
|
||||
|
||||
func Get() Config {
|
||||
flag.Parse()
|
||||
|
||||
var config Config
|
||||
|
||||
visitedFlags := make(map[string]bool)
|
||||
flag.Visit(func(flag *flag.Flag) {
|
||||
visitedFlags[flag.Name] = true
|
||||
})
|
||||
|
||||
var err error
|
||||
|
||||
config.UserID, err = configOpts.userID.getConfigValueWithError(userIdFlag, visitedFlags, func(envVar string) string { return envVar })
|
||||
if err != nil {
|
||||
log.Fatal("A Matrix user ID must be provided.")
|
||||
}
|
||||
config.Token, err = configOpts.token.getConfigValueWithError(tokenFlag, visitedFlags, func(envVar string) string { return envVar })
|
||||
if err != nil {
|
||||
log.Fatal("A Matrix access token must be provided.")
|
||||
}
|
||||
config.Room, err = configOpts.room.getConfigValueWithError(roomFlag, visitedFlags, func(envVar string) string { return envVar })
|
||||
if err != nil {
|
||||
log.Fatal("A Matrix room must be provided.")
|
||||
}
|
||||
config.PrintHomeserverMemberCount = configOpts.printHomeserverMemberCount.getConfigValueWithDefault(printHomeserverMemberCountFlag, visitedFlags, func(envVar string) bool {
|
||||
parsedEnvVar, err := strconv.ParseBool(envVar)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing %s:\n", configOpts.printHomeserverMemberCount.envVarName)
|
||||
log.Fatal(err)
|
||||
}
|
||||
return parsedEnvVar
|
||||
})
|
||||
config.HomeserverVersionInfoTimeout = configOpts.homeserverVersionInfoTimeout.getConfigValueWithDefault(homeserverVersionInfoTimeoutFlag, visitedFlags, func(envVar string) time.Duration {
|
||||
parsedEnvVar, err := time.ParseDuration(envVar)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing %s:\n", configOpts.homeserverVersionInfoTimeout.envVarName)
|
||||
log.Fatal(err)
|
||||
}
|
||||
return parsedEnvVar
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue