build: support selecting environment config file

This commit is contained in:
Eric 1549169735@qq.com
2026-08-19 22:01:54 +08:00
parent 5ac8086ce2
commit f93d093928
5 changed files with 65 additions and 4 deletions

View File

@@ -93,6 +93,7 @@ type MultiTableTables struct {
type LoadOptions struct {
Environment string
ConfigDir string
ConfigFile string
}
func Load(options LoadOptions) (Config, error) {
@@ -105,6 +106,9 @@ func Load(options LoadOptions) (Config, error) {
if environment == "" {
environment = normalizeEnvironment(os.Getenv("APP_ENV"))
}
if options.ConfigFile != "" && environment == "" {
environment = normalizeEnvironment(environmentFromConfigFile(options.ConfigFile))
}
var cfg Config
basePath := filepath.Join(configDir, "config.yml")
@@ -112,7 +116,15 @@ func Load(options LoadOptions) (Config, error) {
return Config{}, fmt.Errorf("load base config %s: %w", basePath, err)
}
if environment == "test" || environment == "prod" {
if options.ConfigFile != "" {
profilePath := options.ConfigFile
if !filepath.IsAbs(profilePath) {
profilePath = filepath.Join(configDir, profilePath)
}
if err := cleanenv.ReadConfig(profilePath, &cfg); err != nil {
return Config{}, fmt.Errorf("load config file %s: %w", profilePath, err)
}
} else if environment == "test" || environment == "prod" {
profilePath := filepath.Join(configDir, "config."+environment+".yml")
if err := cleanenv.ReadConfig(profilePath, &cfg); err != nil {
return Config{}, fmt.Errorf("load profile config %s: %w", profilePath, err)
@@ -139,6 +151,11 @@ func Load(options LoadOptions) (Config, error) {
return cfg, nil
}
func environmentFromConfigFile(path string) string {
name := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
return strings.TrimPrefix(name, "config.")
}
func normalizeEnvironment(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "production", "prod":

View File

@@ -51,6 +51,24 @@ auth:
}
}
func TestLoadExplicitConfigFile(t *testing.T) {
dir := writeConfigs(t, `
app:
env: test
server:
port: 8081
database:
name: explicit_db
`)
cfg, err := Load(LoadOptions{ConfigDir: dir, ConfigFile: "config.test.yml"})
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.App.Env != "test" || cfg.Server.Port != 8081 || cfg.Database.Name != "explicit_db" || cfg.Database.User != "base_user" {
t.Fatalf("unexpected explicit config: %+v", cfg)
}
}
func TestLoadProductionRequiresEnvironmentSecrets(t *testing.T) {
dir := writeConfigs(t, "app:\n env: production\n")
t.Setenv("APP_DATABASE_PASSWORD", "")