feat: add cmd flags
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Environment struct {
|
||||
Version string `env:"VERSION" default:"0.0.1" flag:"version"`
|
||||
Codename string `env:"CODENAME" default:"Magical Anomaly" flag:"codename"`
|
||||
LogLevel string `env:"LOG_LEVEL" default:"debug" flag:"log-level"`
|
||||
|
||||
DataDirectory string `env:"DATA_DIR" default:"./data" flag:"data-dir" usage:"option to specify where the state data gets stored"`
|
||||
ContentDirectory string `env:"CONTENT_DIR" default:"./content" flag:"content-dir" usage:"option to specify where the content gets stored"`
|
||||
Hostname string `env:"HOSTNAME" default:"0.0.0.0" flag:"hostname" usage:"option specify the address/hostname to bind the api server to"`
|
||||
Port int `env:"PORT" default:"8080" flag:"port" usage:"option to specify the port to bind the api server to"`
|
||||
AuthenticationEnabled bool `env:"AUTH_ENABLED" default:"true" flag:"auth" usage:"option to disable authentication"`
|
||||
|
||||
WatchdogEnabled bool `env:"WATCHDOG_ENABLED" default:"true" flag:"watchdog" usage:"option to disable watchdog"`
|
||||
WatchdogInterval int `env:"WATCHDOG_INTERVAL" default:"60" flag:"watchdog-interval" usage:"option to specify the interval in second(s) on which watchdog runs"`
|
||||
WatchdogSyncMode string `env:"WATCHDOG_SYNC_MODE" default:"strict" flag:"watchdog-mode" usage:"option to specify the mode watchdog will run with: strict|sync|dry"`
|
||||
}
|
||||
|
||||
func loadFromEnv(env *Environment) {
|
||||
v := reflect.ValueOf(env).Elem()
|
||||
t := v.Type()
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
valueField := v.Field(i)
|
||||
|
||||
// It is of great importance we set these fields above
|
||||
key := field.Tag.Get("env")
|
||||
fallback := field.Tag.Get("default")
|
||||
|
||||
// If the variable is not found or is empty
|
||||
raw, ok := os.LookupEnv(key)
|
||||
if !ok || raw == "" {
|
||||
raw = fallback
|
||||
}
|
||||
|
||||
switch valueField.Kind() {
|
||||
case reflect.String:
|
||||
valueField.SetString(raw)
|
||||
|
||||
case reflect.Int:
|
||||
if parsed, err := strconv.Atoi(raw); err == nil {
|
||||
valueField.SetInt(int64(parsed))
|
||||
}
|
||||
|
||||
case reflect.Bool:
|
||||
if parsed, err := strconv.ParseBool(raw); err == nil {
|
||||
valueField.SetBool(parsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func bindFlags(env *Environment) {
|
||||
v := reflect.ValueOf(env).Elem()
|
||||
t := v.Type()
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
valueField := v.Field(i)
|
||||
|
||||
flagName := field.Tag.Get("flag")
|
||||
flagUsage := field.Tag.Get("usage")
|
||||
if flagName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch valueField.Kind() {
|
||||
case reflect.String:
|
||||
flag.StringVar(valueField.Addr().Interface().(*string), flagName,
|
||||
valueField.String(), flagUsage,
|
||||
)
|
||||
case reflect.Int:
|
||||
flag.IntVar(valueField.Addr().Interface().(*int), flagName,
|
||||
int(valueField.Int()), flagUsage,
|
||||
)
|
||||
case reflect.Bool:
|
||||
flag.BoolVar(
|
||||
valueField.Addr().Interface().(*bool), flagName,
|
||||
valueField.Bool(), flagUsage,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LoadConfig() Environment {
|
||||
var env Environment
|
||||
|
||||
loadFromEnv(&env)
|
||||
bindFlags(&env)
|
||||
flag.Parse()
|
||||
|
||||
return env
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Environment struct {
|
||||
// Items made for the presentation of ORBITS
|
||||
Version string
|
||||
Codename string
|
||||
LogLevel string
|
||||
|
||||
// Items made for the configuration of the server parts
|
||||
DataDirectory string
|
||||
ContentDirectory string
|
||||
Hostname string
|
||||
Port int
|
||||
AuthenticationEnabled bool
|
||||
|
||||
// Items made for the server watchdog
|
||||
WatchdogEnabled bool
|
||||
WatchdogInterval int
|
||||
WatchdogSyncMode string
|
||||
}
|
||||
|
||||
func GrabEnvironment() Environment {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
cwd = "."
|
||||
}
|
||||
|
||||
fbBase := filepath.Join(cwd, "data")
|
||||
fbContent := filepath.Join(fbBase, "content")
|
||||
|
||||
return Environment{
|
||||
// Basic server configuration
|
||||
Version: safeStringGrab("VERSION", "0.0.1"),
|
||||
Codename: safeStringGrab("CODENAME", "Magical Anomaly"),
|
||||
LogLevel: safeStringGrab("LOG_LEVEL", "debug"),
|
||||
|
||||
// GIN API configuration
|
||||
DataDirectory: safeStringGrab("DATA_DIR", fbBase),
|
||||
ContentDirectory: safeStringGrab("CONTENT_DIR", fbContent),
|
||||
Hostname: safeStringGrab("HOSTNAME", "0.0.0.0"),
|
||||
Port: safeIntGrab("PORT", 8080),
|
||||
AuthenticationEnabled: safeBoolGrab("AUTH_ENABLED", true),
|
||||
|
||||
// watchdog configuration
|
||||
// watchdog is the integrity checker/steward
|
||||
WatchdogEnabled: safeBoolGrab("WATCHDOG_ENABLED", true),
|
||||
WatchdogInterval: safeIntGrab("WATCHDOG_INTERVAL", 60),
|
||||
// sync: sync local files to the database, for example when you want to allow local inserting files which then get added to the database
|
||||
// strict: make the database leading, this is when you only allow API uploads to be registered, and remove orphaned filesystem files
|
||||
// dry: do nothing
|
||||
WatchdogSyncMode: safeStringGrab("WATCHDOG_SYNC_MODE", "strict"),
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// part of filesystem checking
|
||||
func EnsureOperation(workDir string) error {
|
||||
nDirs := []string{
|
||||
workDir,
|
||||
filepath.Join(workDir),
|
||||
filepath.Join(workDir, "content"),
|
||||
}
|
||||
|
||||
for _, p := range nDirs {
|
||||
if err := os.MkdirAll(p, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
validSyncModes = []string{
|
||||
"sync",
|
||||
"strict",
|
||||
"dry",
|
||||
}
|
||||
)
|
||||
|
||||
// part of environment checking
|
||||
func safeStringGrab(key, fallback string) string {
|
||||
if v, ok := os.LookupEnv(key); ok {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func safeIntGrab(key string, fallback int) int {
|
||||
if v, ok := os.LookupEnv(key); ok {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func safeBoolGrab(key string, fallback bool) bool {
|
||||
if v, ok := os.LookupEnv(key); ok {
|
||||
if b, err := strconv.ParseBool(v); err == nil {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func safeSyncModeGrab(key, fallback string) string {
|
||||
if v, ok := os.LookupEnv(key); ok {
|
||||
if slices.Contains(validSyncModes, v) {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
Reference in New Issue
Block a user