From 55b6799127e3c0fc68cebd526c2da37b835f9fbe Mon Sep 17 00:00:00 2001 From: Karn Date: Mon, 9 Feb 2026 03:53:08 +0530 Subject: [PATCH] fix that bug --- cfgx.go | 20 +++++++++++--------- cfgx_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/cfgx.go b/cfgx.go index 59dde49..2f73f97 100644 --- a/cfgx.go +++ b/cfgx.go @@ -100,14 +100,22 @@ func GenerateFromFile(opts *GenerateOptions) error { return fmt.Errorf("failed to read input file %s: %w", opts.InputFile, err) } - // Parse TOML to apply environment variable overrides if enabled + // Set default mode if not specified + mode := opts.Mode + if mode == "" { + mode = "static" + } + + // Parse TOML to apply environment variable overrides if enabled. + // In getter mode, env vars are resolved at runtime via os.Getenv() calls + // in the generated code, so applying them at generation time would + // incorrectly bake runtime values (e.g. secrets) into the source as defaults. var configData map[string]any if err := toml.Unmarshal(data, &configData); err != nil { return fmt.Errorf("failed to parse TOML: %w", err) } - // Apply environment variable overrides - if opts.EnableEnv { + if opts.EnableEnv && mode != "getter" { if err := envoverride.Apply(configData); err != nil { return fmt.Errorf("failed to apply environment overrides: %w", err) } @@ -137,12 +145,6 @@ func GenerateFromFile(opts *GenerateOptions) error { maxFileSize = DefaultMaxFileSize } - // Set default mode if not specified - mode := opts.Mode - if mode == "" { - mode = "static" - } - // Generate code generated, err := GenerateWithOptions(data, packageName, opts.EnableEnv, inputDir, maxFileSize, mode) if err != nil { diff --git a/cfgx_test.go b/cfgx_test.go index e0fd884..ce2b04d 100644 --- a/cfgx_test.go +++ b/cfgx_test.go @@ -72,6 +72,53 @@ max_conns = 10 require.NotContains(t, outputStr, `":8080"`, "original server.addr should have been overridden") } +func TestGenerateFromFile_GetterModeIgnoresEnvOverrides(t *testing.T) { + tmpDir := t.TempDir() + inputFile := filepath.Join(tmpDir, "config.toml") + outputFile := filepath.Join(tmpDir, "config.go") + + tomlData := []byte(` +[server] +addr = ":8080" + +[secrets] +api_key = "set-from-env" +`) + + err := os.WriteFile(inputFile, tomlData, 0644) + require.NoError(t, err) + + // Set env var that would override the TOML value at generation time + os.Setenv("CONFIG_SECRETS_API_KEY", "sk-real-secret-key-12345") + defer os.Unsetenv("CONFIG_SECRETS_API_KEY") + + opts := &GenerateOptions{ + InputFile: inputFile, + OutputFile: outputFile, + PackageName: "config", + EnableEnv: true, + Mode: "getter", + } + + err = GenerateFromFile(opts) + require.NoError(t, err, "GenerateFromFile() should not error") + + output, err := os.ReadFile(outputFile) + require.NoError(t, err) + + outputStr := string(output) + + // The generated code should use the TOML default, NOT the env var value + require.Contains(t, outputStr, `"set-from-env"`, + "getter mode should use TOML default, not env var value") + require.NotContains(t, outputStr, "sk-real-secret-key-12345", + "getter mode must not bake env var values into generated code") + + // It should still have the os.Getenv call for runtime override + require.Contains(t, outputStr, `os.Getenv("CONFIG_SECRETS_API_KEY")`, + "getter mode should still generate runtime env var lookups") +} + func TestGenerateFromFile(t *testing.T) { // Create a temporary TOML file tmpDir := t.TempDir()