Compare commits
2 Commits
ezconf/v0.
...
ezconf/v0.
| Author | SHA1 | Date | |
|---|---|---|---|
| e9b96fedb1 | |||
| da6ad0cf2e |
@@ -18,16 +18,16 @@ type EnvVar struct {
|
|||||||
|
|
||||||
// ConfigLoader manages configuration loading from multiple sources
|
// ConfigLoader manages configuration loading from multiple sources
|
||||||
type ConfigLoader struct {
|
type ConfigLoader struct {
|
||||||
configFuncs map[string]ConfigFunc // Map of config names to ConfigFromEnv functions
|
configFuncs map[string]ConfigFunc // Map of config names to ConfigFromEnv functions
|
||||||
packagePaths []string // Paths to packages to parse for ENV comments
|
packagePaths []string // Paths to packages to parse for ENV comments
|
||||||
groupNames map[string]string // Map of package paths to group names
|
groupNames map[string]string // Map of package paths to group names
|
||||||
extraEnvVars []EnvVar // Additional environment variables to track
|
extraEnvVars []EnvVar // Additional environment variables to track
|
||||||
envVars []EnvVar // All extracted environment variables
|
envVars []EnvVar // All extracted environment variables
|
||||||
configs map[string]interface{} // Loaded configurations
|
configs map[string]any // Loaded configurations
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigFunc is a function that loads configuration from environment variables
|
// ConfigFunc is a function that loads configuration from environment variables
|
||||||
type ConfigFunc func() (interface{}, error)
|
type ConfigFunc func() (any, error)
|
||||||
|
|
||||||
// New creates a new ConfigLoader
|
// New creates a new ConfigLoader
|
||||||
func New() *ConfigLoader {
|
func New() *ConfigLoader {
|
||||||
@@ -37,7 +37,7 @@ func New() *ConfigLoader {
|
|||||||
groupNames: make(map[string]string),
|
groupNames: make(map[string]string),
|
||||||
extraEnvVars: make([]EnvVar, 0),
|
extraEnvVars: make([]EnvVar, 0),
|
||||||
envVars: make([]EnvVar, 0),
|
envVars: make([]EnvVar, 0),
|
||||||
configs: make(map[string]interface{}),
|
configs: make(map[string]any),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,8 +72,12 @@ func (cl *ConfigLoader) AddEnvVar(envVar EnvVar) {
|
|||||||
cl.extraEnvVars = append(cl.extraEnvVars, envVar)
|
cl.extraEnvVars = append(cl.extraEnvVars, envVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads all configurations and extracts environment variables
|
// ParseEnvVars extracts environment variables from packages and extra vars
|
||||||
func (cl *ConfigLoader) Load() error {
|
// This can be called without having actual environment variables set
|
||||||
|
func (cl *ConfigLoader) ParseEnvVars() error {
|
||||||
|
// Clear existing env vars to prevent duplicates
|
||||||
|
cl.envVars = make([]EnvVar, 0)
|
||||||
|
|
||||||
// Parse packages for ENV comments
|
// Parse packages for ENV comments
|
||||||
for _, pkgPath := range cl.packagePaths {
|
for _, pkgPath := range cl.packagePaths {
|
||||||
envVars, err := ParseConfigPackage(pkgPath)
|
envVars, err := ParseConfigPackage(pkgPath)
|
||||||
@@ -102,6 +106,12 @@ func (cl *ConfigLoader) Load() error {
|
|||||||
cl.envVars[i].CurrentValue = os.Getenv(cl.envVars[i].Name)
|
cl.envVars[i].CurrentValue = os.Getenv(cl.envVars[i].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfigs executes the config functions to load actual configurations
|
||||||
|
// This should be called after environment variables are properly set
|
||||||
|
func (cl *ConfigLoader) LoadConfigs() error {
|
||||||
// Load configurations
|
// Load configurations
|
||||||
for name, fn := range cl.configFuncs {
|
for name, fn := range cl.configFuncs {
|
||||||
cfg, err := fn()
|
cfg, err := fn()
|
||||||
@@ -114,14 +124,22 @@ func (cl *ConfigLoader) Load() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load loads all configurations and extracts environment variables
|
||||||
|
func (cl *ConfigLoader) Load() error {
|
||||||
|
if err := cl.ParseEnvVars(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cl.LoadConfigs()
|
||||||
|
}
|
||||||
|
|
||||||
// GetConfig returns a loaded configuration by name
|
// GetConfig returns a loaded configuration by name
|
||||||
func (cl *ConfigLoader) GetConfig(name string) (interface{}, bool) {
|
func (cl *ConfigLoader) GetConfig(name string) (any, bool) {
|
||||||
cfg, ok := cl.configs[name]
|
cfg, ok := cl.configs[name]
|
||||||
return cfg, ok
|
return cfg, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllConfigs returns all loaded configurations
|
// GetAllConfigs returns all loaded configurations
|
||||||
func (cl *ConfigLoader) GetAllConfigs() map[string]interface{} {
|
func (cl *ConfigLoader) GetAllConfigs() map[string]any {
|
||||||
return cl.configs
|
return cl.configs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ezconf
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -240,6 +241,163 @@ func TestGetEnvVars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseEnvVars(t *testing.T) {
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
// Add a test config function
|
||||||
|
loader.AddConfigFunc("test", func() (interface{}, error) {
|
||||||
|
return "test config", nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add current package path
|
||||||
|
loader.AddPackagePath(".")
|
||||||
|
|
||||||
|
// Add an extra env var
|
||||||
|
loader.AddEnvVar(EnvVar{
|
||||||
|
Name: "EXTRA_VAR",
|
||||||
|
Description: "Extra test variable",
|
||||||
|
Default: "extra",
|
||||||
|
})
|
||||||
|
|
||||||
|
err := loader.ParseEnvVars()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseEnvVars failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that env vars were extracted
|
||||||
|
envVars := loader.GetEnvVars()
|
||||||
|
if len(envVars) == 0 {
|
||||||
|
t.Error("expected at least one env var")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for extra var
|
||||||
|
foundExtra := false
|
||||||
|
for _, ev := range envVars {
|
||||||
|
if ev.Name == "EXTRA_VAR" {
|
||||||
|
foundExtra = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundExtra {
|
||||||
|
t.Error("extra env var not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that configs are NOT loaded (should be empty)
|
||||||
|
configs := loader.GetAllConfigs()
|
||||||
|
if len(configs) != 0 {
|
||||||
|
t.Errorf("expected no configs loaded after ParseEnvVars, got %d", len(configs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadConfigs(t *testing.T) {
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
// Add a test config function
|
||||||
|
testCfg := struct {
|
||||||
|
Value string
|
||||||
|
}{Value: "test"}
|
||||||
|
|
||||||
|
loader.AddConfigFunc("test", func() (interface{}, error) {
|
||||||
|
return testCfg, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// Manually set some env vars (simulating ParseEnvVars already called)
|
||||||
|
loader.envVars = []EnvVar{
|
||||||
|
{Name: "TEST_VAR", Description: "Test variable"},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := loader.LoadConfigs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("LoadConfigs failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that config was loaded
|
||||||
|
cfg, ok := loader.GetConfig("test")
|
||||||
|
if !ok {
|
||||||
|
t.Error("test config not loaded")
|
||||||
|
}
|
||||||
|
if cfg == nil {
|
||||||
|
t.Error("test config is nil")
|
||||||
|
}
|
||||||
|
_ = cfg // Use the variable to avoid unused variable error
|
||||||
|
|
||||||
|
// Check that env vars are NOT modified (should remain as set)
|
||||||
|
envVars := loader.GetEnvVars()
|
||||||
|
if len(envVars) != 1 {
|
||||||
|
t.Errorf("expected 1 env var, got %d", len(envVars))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadConfigs_Error(t *testing.T) {
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
loader.AddConfigFunc("error", func() (interface{}, error) {
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
})
|
||||||
|
|
||||||
|
err := loader.LoadConfigs()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error from failing config func")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseEnvVars_Then_LoadConfigs(t *testing.T) {
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
// Add a test config function
|
||||||
|
testCfg := struct {
|
||||||
|
Value string
|
||||||
|
}{Value: "test"}
|
||||||
|
|
||||||
|
loader.AddConfigFunc("test", func() (interface{}, error) {
|
||||||
|
return testCfg, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add current package path
|
||||||
|
loader.AddPackagePath(".")
|
||||||
|
|
||||||
|
// Add an extra env var
|
||||||
|
loader.AddEnvVar(EnvVar{
|
||||||
|
Name: "EXTRA_VAR",
|
||||||
|
Description: "Extra test variable",
|
||||||
|
Default: "extra",
|
||||||
|
})
|
||||||
|
|
||||||
|
// First parse env vars
|
||||||
|
err := loader.ParseEnvVars()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseEnvVars failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check env vars are extracted but configs are not loaded
|
||||||
|
envVars := loader.GetEnvVars()
|
||||||
|
if len(envVars) == 0 {
|
||||||
|
t.Error("expected env vars to be extracted")
|
||||||
|
}
|
||||||
|
|
||||||
|
configs := loader.GetAllConfigs()
|
||||||
|
if len(configs) != 0 {
|
||||||
|
t.Error("expected no configs loaded yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then load configs
|
||||||
|
err = loader.LoadConfigs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("LoadConfigs failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check both env vars and configs are loaded
|
||||||
|
_, ok := loader.GetConfig("test")
|
||||||
|
if !ok {
|
||||||
|
t.Error("test config not loaded after LoadConfigs")
|
||||||
|
}
|
||||||
|
|
||||||
|
configs = loader.GetAllConfigs()
|
||||||
|
if len(configs) != 1 {
|
||||||
|
t.Errorf("expected 1 config loaded, got %d", len(configs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoad_Integration(t *testing.T) {
|
func TestLoad_Integration(t *testing.T) {
|
||||||
// Integration test with real hlog package
|
// Integration test with real hlog package
|
||||||
hlogPath := filepath.Join("..", "hlog")
|
hlogPath := filepath.Join("..", "hlog")
|
||||||
@@ -269,3 +427,62 @@ func TestLoad_Integration(t *testing.T) {
|
|||||||
t.Logf(" %s: %s (default: %s, required: %t)", ev.Name, ev.Description, ev.Default, ev.Required)
|
t.Logf(" %s: %s (default: %s, required: %t)", ev.Name, ev.Description, ev.Default, ev.Required)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseEnvVars_GenerateEnvFile_Integration(t *testing.T) {
|
||||||
|
// Test the new separated ParseEnvVars functionality
|
||||||
|
hlogPath := filepath.Join("..", "hlog")
|
||||||
|
if _, err := os.Stat(hlogPath); os.IsNotExist(err) {
|
||||||
|
t.Skip("hlog package not found, skipping integration test")
|
||||||
|
}
|
||||||
|
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
// Add hlog package
|
||||||
|
if err := loader.AddPackagePath(hlogPath); err != nil {
|
||||||
|
t.Fatalf("failed to add hlog package: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse env vars without loading configs (this should work even if required env vars are missing)
|
||||||
|
if err := loader.ParseEnvVars(); err != nil {
|
||||||
|
t.Fatalf("ParseEnvVars failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
envVars := loader.GetEnvVars()
|
||||||
|
if len(envVars) == 0 {
|
||||||
|
t.Error("expected env vars from hlog package")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now test that we can generate an env file without calling Load()
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
envFile := filepath.Join(tempDir, "test-generated.env")
|
||||||
|
|
||||||
|
err := loader.GenerateEnvFile(envFile, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GenerateEnvFile failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the file was created and contains expected content
|
||||||
|
content, err := os.ReadFile(envFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read generated file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := string(content)
|
||||||
|
if !strings.Contains(output, "# Environment Configuration") {
|
||||||
|
t.Error("expected header in generated file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should contain environment variables from hlog
|
||||||
|
foundHlogVar := false
|
||||||
|
for _, ev := range envVars {
|
||||||
|
if strings.Contains(output, ev.Name) {
|
||||||
|
foundHlogVar = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundHlogVar {
|
||||||
|
t.Error("expected to find at least one hlog environment variable in generated file")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Successfully generated env file with %d variables", len(envVars))
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,20 +12,20 @@ import (
|
|||||||
|
|
||||||
// PrintEnvVars prints all environment variables to the provided writer
|
// PrintEnvVars prints all environment variables to the provided writer
|
||||||
func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
||||||
if cl.envVars == nil || len(cl.envVars) == 0 {
|
if len(cl.envVars) == 0 {
|
||||||
return errors.New("no environment variables loaded (did you call Load()?)")
|
return errors.New("no environment variables loaded (did you call Load()?)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group variables by their Group field
|
// Group variables by their Group field
|
||||||
groups := make(map[string][]EnvVar)
|
groups := make(map[string][]EnvVar)
|
||||||
groupOrder := make([]string, 0)
|
groupOrder := make([]string, 0)
|
||||||
|
|
||||||
for _, envVar := range cl.envVars {
|
for _, envVar := range cl.envVars {
|
||||||
group := envVar.Group
|
group := envVar.Group
|
||||||
if group == "" {
|
if group == "" {
|
||||||
group = "Other"
|
group = "Other"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := groups[group]; !exists {
|
if _, exists := groups[group]; !exists {
|
||||||
groupOrder = append(groupOrder, group)
|
groupOrder = append(groupOrder, group)
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
|||||||
// Print variables grouped by section
|
// Print variables grouped by section
|
||||||
for _, group := range groupOrder {
|
for _, group := range groupOrder {
|
||||||
vars := groups[group]
|
vars := groups[group]
|
||||||
|
|
||||||
// Calculate max name length for alignment within this group
|
// Calculate max name length for alignment within this group
|
||||||
maxNameLen := 0
|
maxNameLen := 0
|
||||||
for _, envVar := range vars {
|
for _, envVar := range vars {
|
||||||
@@ -51,12 +51,12 @@ func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
|||||||
maxNameLen = nameLen
|
maxNameLen = nameLen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print group header
|
// Print group header
|
||||||
fmt.Fprintf(w, "\n%s Configuration\n", group)
|
fmt.Fprintf(w, "\n%s Configuration\n", group)
|
||||||
fmt.Fprintln(w, strings.Repeat("=", len(group)+14))
|
fmt.Fprintln(w, strings.Repeat("=", len(group)+14))
|
||||||
fmt.Fprintln(w)
|
fmt.Fprintln(w)
|
||||||
|
|
||||||
for _, envVar := range vars {
|
for _, envVar := range vars {
|
||||||
// Build the variable line
|
// Build the variable line
|
||||||
var varLine string
|
var varLine string
|
||||||
@@ -69,10 +69,10 @@ func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
|||||||
} else {
|
} else {
|
||||||
varLine = envVar.Name
|
varLine = envVar.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate padding for alignment
|
// Calculate padding for alignment
|
||||||
padding := maxNameLen - len(varLine) + 2
|
padding := maxNameLen - len(varLine) + 2
|
||||||
|
|
||||||
// Print with indentation and alignment
|
// Print with indentation and alignment
|
||||||
fmt.Fprintf(w, " %s%s# %s", varLine, strings.Repeat(" ", padding), envVar.Description)
|
fmt.Fprintf(w, " %s%s# %s", varLine, strings.Repeat(" ", padding), envVar.Description)
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ func (cl *ConfigLoader) PrintEnvVars(w io.Writer, showValues bool) error {
|
|||||||
fmt.Fprintln(w)
|
fmt.Fprintln(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(w)
|
fmt.Fprintln(w)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -109,7 +109,7 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
for _, envVar := range cl.envVars {
|
for _, envVar := range cl.envVars {
|
||||||
managedVars[envVar.Name] = true
|
managedVars[envVar.Name] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect untracked variables
|
// Collect untracked variables
|
||||||
for _, line := range existingVars {
|
for _, line := range existingVars {
|
||||||
if line.IsVar && !managedVars[line.Key] {
|
if line.IsVar && !managedVars[line.Key] {
|
||||||
@@ -118,7 +118,7 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Create(filename)
|
file, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create env file")
|
return errors.Wrap(err, "failed to create env file")
|
||||||
@@ -138,13 +138,13 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
// Group variables by their Group field
|
// Group variables by their Group field
|
||||||
groups := make(map[string][]EnvVar)
|
groups := make(map[string][]EnvVar)
|
||||||
groupOrder := make([]string, 0)
|
groupOrder := make([]string, 0)
|
||||||
|
|
||||||
for _, envVar := range cl.envVars {
|
for _, envVar := range cl.envVars {
|
||||||
group := envVar.Group
|
group := envVar.Group
|
||||||
if group == "" {
|
if group == "" {
|
||||||
group = "Other"
|
group = "Other"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := groups[group]; !exists {
|
if _, exists := groups[group]; !exists {
|
||||||
groupOrder = append(groupOrder, group)
|
groupOrder = append(groupOrder, group)
|
||||||
}
|
}
|
||||||
@@ -154,12 +154,12 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
// Write variables grouped by section
|
// Write variables grouped by section
|
||||||
for _, group := range groupOrder {
|
for _, group := range groupOrder {
|
||||||
vars := groups[group]
|
vars := groups[group]
|
||||||
|
|
||||||
// Print group header
|
// Print group header
|
||||||
fmt.Fprintln(writer)
|
fmt.Fprintln(writer)
|
||||||
fmt.Fprintf(writer, "# %s Configuration\n", group)
|
fmt.Fprintf(writer, "# %s Configuration\n", group)
|
||||||
fmt.Fprintln(writer, strings.Repeat("#", len(group)+15))
|
fmt.Fprintln(writer, strings.Repeat("#", len(group)+15))
|
||||||
|
|
||||||
for _, envVar := range vars {
|
for _, envVar := range vars {
|
||||||
// Write comment with description
|
// Write comment with description
|
||||||
fmt.Fprintf(writer, "# %s", envVar.Description)
|
fmt.Fprintf(writer, "# %s", envVar.Description)
|
||||||
@@ -185,7 +185,7 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(writer, "%s=%s\n", envVar.Name, value)
|
fmt.Fprintf(writer, "%s=%s\n", envVar.Name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(writer)
|
fmt.Fprintln(writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ func (cl *ConfigLoader) GenerateEnvFile(filename string, useCurrentValues bool)
|
|||||||
fmt.Fprintln(writer, "# These variables were in the original file but are not managed by ezconf")
|
fmt.Fprintln(writer, "# These variables were in the original file but are not managed by ezconf")
|
||||||
fmt.Fprintln(writer, strings.Repeat("#", 72))
|
fmt.Fprintln(writer, strings.Repeat("#", 72))
|
||||||
fmt.Fprintln(writer)
|
fmt.Fprintln(writer)
|
||||||
|
|
||||||
for _, line := range existingUntracked {
|
for _, line := range existingUntracked {
|
||||||
fmt.Fprintf(writer, "%s=%s\n", line.Key, line.Value)
|
fmt.Fprintf(writer, "%s=%s\n", line.Key, line.Value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,3 +360,46 @@ func TestPrintEnvVarsStdout_NoEnvVars(t *testing.T) {
|
|||||||
t.Error("expected error when no env vars are loaded")
|
t.Error("expected error when no env vars are loaded")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintEnvVars_AfterParseEnvVars(t *testing.T) {
|
||||||
|
loader := New()
|
||||||
|
|
||||||
|
// Add some env vars manually to simulate ParseEnvVars
|
||||||
|
loader.envVars = []EnvVar{
|
||||||
|
{
|
||||||
|
Name: "LOG_LEVEL",
|
||||||
|
Description: "Log level for the application",
|
||||||
|
Required: false,
|
||||||
|
Default: "info",
|
||||||
|
CurrentValue: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DATABASE_URL",
|
||||||
|
Description: "Database connection string",
|
||||||
|
Required: true,
|
||||||
|
Default: "",
|
||||||
|
CurrentValue: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that PrintEnvVars works after ParseEnvVars (without Load)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := loader.PrintEnvVars(buf, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("PrintEnvVars failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
if !strings.Contains(output, "LOG_LEVEL") {
|
||||||
|
t.Error("output should contain LOG_LEVEL")
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "DATABASE_URL") {
|
||||||
|
t.Error("output should contain DATABASE_URL")
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "(required)") {
|
||||||
|
t.Error("output should indicate required variables")
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "(default: info)") {
|
||||||
|
t.Error("output should contain default value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user