package main import ( "encoding/json" "fmt" "io" "os" "github.com/rs/zerolog/log" ) type Configuration struct { Port string `json:"port"` DatabaseDirectory string `json:"database_directory"` } func getDefaultConfig() Configuration { return Configuration{ Port: "8080", DatabaseDirectory: ".", } } func LoadConfiguration(configurationFilePath string) (Configuration, error) { config, err := fromFile(configurationFilePath) if err != nil { log.Info().Msg("failed to load configuration from file, using default values") } config.Port = os.Getenv("HTTP_PORT") config.DatabaseDirectory = os.Getenv("DATABASE_DIRECTORY") config = mergeConfig(getDefaultConfig(), config) err = checkConfiguration(&config) if err != nil { return config, err } return config, nil } func fromFile(filePath string) (Configuration, error) { file, err := os.Open(filePath) if err != nil { return Configuration{}, err } jsonData, err := io.ReadAll(file) if err != nil { return Configuration{}, err } var config Configuration err = json.Unmarshal(jsonData, &config) if err != nil { return Configuration{}, err } return config, nil } func mergeConfig(base Configuration, override Configuration) Configuration { mergedConfig := base if override.Port != "" { mergedConfig.Port = override.Port } if override.DatabaseDirectory != "" { mergedConfig.DatabaseDirectory = override.DatabaseDirectory } return mergedConfig } func checkConfiguration(configuration *Configuration) error { databaseDirectory := configuration.DatabaseDirectory if !checkDirectoryPath(databaseDirectory) { return fmt.Errorf("database directory %s does not exist", databaseDirectory) } return nil } func checkDirectoryPath(directoryPath string) bool { _, err := os.Stat(directoryPath) return !os.IsNotExist(err) }