New Sign in

fierj

Public

Tiny personal git forge

0d345980a75f73bd46166048167334ca8e6b5bb3
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..188d3fb
--- /dev/null
+++ b/config.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"encoding/json"
+	"log/slog"
+	"os"
+	"reflect"
+)
+
+const envPrefix = "FIERJ_"
+
+type Config struct {
+	Addr string `json:"addr" env:"ADDR"`
+}
+
+func LoadConfig(path string) Config {
+	// default config
+	cfg := Config{
+		Addr: ":8080",
+	}
+
+	// read file, log read/unmarshal errors, if any
+	b, err := os.ReadFile(path)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			slog.Error("failed to read config file", "error", err)
+		}
+	} else {
+		if err := json.Unmarshal(b, &cfg); err != nil {
+			slog.Error("failed to unmarshal config file", "error", err)
+		}
+	}
+
+	// scan fields and override with env vars (FIERJ_<env>) if present
+	v := reflect.ValueOf(&cfg).Elem()
+	slog.Info("scanning config fields for env overrides", "x", v)
+	for i := 0; i < v.NumField(); i++ {
+		field := v.Type().Field(i)
+		envTag := field.Tag.Get("env")
+		slog.Info("checking field for env override", "field", field, "env", envTag)
+		if envTag == "" {
+			continue
+		}
+		if envVal, ok := os.LookupEnv(envPrefix + envTag); ok {
+			v.Field(i).SetString(envVal)
+		}
+	}
+	return cfg
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..d0ba93a
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/zserge/fierj
+
+go 1.26.3
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..a4e47c9
--- /dev/null
+++ b/main.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"log/slog"
+	"net/http"
+	"os"
+)
+
+func main() {
+	cfgPath := "config.json"
+	if len(os.Args) > 1 {
+		cfgPath = os.Args[1]
+	}
+	cfg := LoadConfig(cfgPath)
+
+	slog.Info("Starting server", "addr", cfg.Addr)
+	if err := http.ListenAndServe(cfg.Addr, nil); err != nil {
+		slog.Error("Server exited", "error", err)
+	}
+}