diff --git a/cmd/showconfig.go b/cmd/showconfig.go index 99c47b0c..d87844b2 100644 --- a/cmd/showconfig.go +++ b/cmd/showconfig.go @@ -37,6 +37,11 @@ func showConfig( if err != nil { return stackerr.NewStackErrf(err, "failed to unmarshal config") } + log, err := logging.GetLogger(config.LogLevel) + if err != nil { + return fmt.Errorf("getting logger: %w", err) + } + ctx = log.WithContext(ctx) if err := config.Initialize(ctx); err != nil { return err } @@ -48,10 +53,7 @@ func showConfig( if err != nil { return stackerr.NewStackErrf(err, "failed to marshal yaml") } - log, err := logging.GetLogger(config.LogLevel) - if err != nil { - panic(err) - } + log.Info().Msgf("Using config: %s", config.Config) fmt.Fprintf(outputter, "%s", string(out)) diff --git a/pkg/config/config.go b/pkg/config/config.go index 8206bcb1..7899fd9c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -210,7 +210,11 @@ func (c *Config) getPackageConfigMap(ctx context.Context, packageName string) (m return configAsMap, nil } - return map[string]any{}, nil + // Package is something other than map, so set its value to an + // empty map. + emptyMap := map[string]any{} + packageSection[packageName] = emptyMap + return emptyMap, nil } func (c *Config) GetPackageConfig(ctx context.Context, packageName string) (*Config, error) { @@ -659,6 +663,17 @@ func contains[T comparable](slice []T, elem T) bool { return false } +func deepCopyConfigMap(src map[string]any) map[string]any { + new := map[string]any{} + for key, val := range src { + if contains([]string{"packages", "config", "interfaces"}, key) { + continue + } + new[key] = val + } + return new +} + // mergeInConfig takes care of merging inheritable configuration // in the config map. For example, it merges default config, then // package-level config, then interface-level config. @@ -684,15 +699,28 @@ func (c *Config) mergeInConfig(ctx context.Context) error { pkgLog.Err(err).Msg("failed to get package config") return fmt.Errorf("failed to get package config: %w", err) } + pkgLog.Trace().Msg("got package config map") + configSectionUntyped, configExists := packageConfig["config"] if !configExists { - packageConfig["config"] = defaultCfg - continue + pkgLog.Trace().Msg("config section doesn't exist, setting it to a deepcopy of the top-level config") + packageConfig["config"] = deepCopyConfigMap(defaultCfg) } + + pkgLog.Trace().Msg("got config section for package") // Sometimes the config section may be provided, but it's nil. // We need to account for this fact. if configSectionUntyped == nil { - configSectionUntyped = map[string]any{} + pkgLog.Trace().Msg("config section is nil, converting to empty map") + emptyMap := map[string]any{} + + // We need to add this to the "global" config mapping so the change + // gets persisted, and also into configSectionUntyped for the logic + // further down. + packageConfig["config"] = emptyMap + configSectionUntyped = emptyMap + } else { + pkgLog.Trace().Msg("config section is not nil") } configSectionTyped := configSectionUntyped.(map[string]any) @@ -701,8 +729,11 @@ func (c *Config) mergeInConfig(ctx context.Context) error { if contains([]string{"packages", "config"}, key) { continue } + keyValLog := pkgLog.With().Str("key", key).Str("value", fmt.Sprintf("%v", value)).Logger() + _, keyExists := configSectionTyped[key] if !keyExists { + keyValLog.Trace().Msg("setting key to value") configSectionTyped[key] = value } } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 580c1fb7..5a7b654e 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1204,6 +1204,7 @@ with-expecter: false } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() tmpdir := pathlib.NewPath(t.TempDir()) cfg := tmpdir.Join("config.yaml") require.NoError(t, cfg.WriteFile([]byte(tt.cfgYaml))) @@ -1218,7 +1219,10 @@ with-expecter: false t.Errorf("Config.Initialize() error = %v, wantErr %v", err, tt.wantErr) } - cfgAsStr, err := yaml.Marshal(c._cfgAsMap) + cfgAsMap, err := c.CfgAsMap(ctx) + require.NoError(t, err) + + cfgAsStr, err := yaml.Marshal(cfgAsMap) require.NoError(t, err) if tt.wantCfgMap != "" && !reflect.DeepEqual(string(cfgAsStr), tt.wantCfgMap) {