+ New

fierj

Public

Tiny personal git forge

← fierj / config.go
package main

import (
	"encoding/json"
	"log/slog"
	"os"
	"reflect"
)

const envPrefix = "FIERJ_"

type Config struct {
	Addr       string `json:"addr" env:"ADDR"`
	Host       string `json:"host" env:"HOST"`
	Dir        string `json:"dir" env:"DIR"`
	SSHAddr    string `json:"ssh_addr" env:"SSH_ADDR"`
	SSHHostKey string `json:"ssh_host_key" env:"SSH_HOST_KEY"`
}

func LoadConfig(path string) Config {
	// default config
	cfg := Config{
		Addr:    ":8080",
		Host:    "localhost:8080",
		SSHAddr: ":2222",
		Dir:     "repos",
	}

	// 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()
	for i := 0; i < v.NumField(); i++ {
		field := v.Type().Field(i)
		envTag := field.Tag.Get("env")
		if envTag == "" {
			continue
		}
		if envVal, ok := os.LookupEnv(envPrefix + envTag); ok {
			v.Field(i).SetString(envVal)
		}
	}
	return cfg
}