From 4da7494c7e072f9fa83f46c6457a2c765134ba86 Mon Sep 17 00:00:00 2001 From: lxowalle Date: Sun, 12 Apr 2026 18:07:09 +0800 Subject: [PATCH] fix yaml overrides for default skills registries --- pkg/config/config_struct.go | 74 +++++++++++++++++++------------- pkg/config/config_struct_test.go | 33 ++++++++++++++ 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/pkg/config/config_struct.go b/pkg/config/config_struct.go index c7b6f2f1a..146a70f56 100644 --- a/pkg/config/config_struct.go +++ b/pkg/config/config_struct.go @@ -538,60 +538,74 @@ func (c SkillRegistryConfig) MarshalYAML() (any, error) { } func (v *SkillsRegistriesConfig) UnmarshalYAML(value *yaml.Node) error { - mm := make(map[string]*SkillRegistryConfig) - if err := value.Decode(&mm); err != nil { + decoded, err := decodeRegistryNodesFromYAML(value, nil) + if err != nil { logger.Errorf("Decode error: %v", err) return err } if len(*v) == 0 { - keys := make([]string, 0, len(mm)) - for name := range mm { + keys := make([]string, 0, len(decoded)) + for name := range decoded { keys = append(keys, name) } sort.Strings(keys) list := make([]*SkillRegistryConfig, 0, len(keys)) for _, name := range keys { - registry := mm[name] + registry := decoded[name] if registry == nil { continue } - registry.Name = name list = append(list, registry) } *v = list return nil } - for _, name := range sortedRegistryNames(mm) { - sec := mm[name] - if sec == nil { - continue - } - sec.Name = name - registry := findRegistryConfigByName(*v, name) + decoded, err = decodeRegistryNodesFromYAML(value, *v) + if err != nil { + logger.Errorf("Decode error: %v", err) + return err + } + for _, name := range sortedRegistryNames(decoded) { + registry := decoded[name] if registry == nil { - *v = append(*v, cloneRegistryConfig(sec)) continue } - registry.AuthToken = sec.AuthToken - if registry.BaseURL == "" { - registry.BaseURL = sec.BaseURL - } - if !registry.Enabled { - registry.Enabled = sec.Enabled - } - if registry.Param == nil { - registry.Param = map[string]any{} - } - for key, value := range sec.Param { - if _, ok := registry.Param[key]; ok { - continue - } - registry.Param[key] = value - } + v.Set(name, *registry) } return nil } +func decodeRegistryNodesFromYAML( + value *yaml.Node, + existing SkillsRegistriesConfig, +) (map[string]*SkillRegistryConfig, error) { + decoded := make(map[string]*SkillRegistryConfig) + if value == nil { + return decoded, nil + } + for i := 0; i+1 < len(value.Content); i += 2 { + nameNode := value.Content[i] + registryNode := value.Content[i+1] + if nameNode == nil || registryNode == nil { + continue + } + name := strings.TrimSpace(nameNode.Value) + if name == "" { + continue + } + registry := cloneRegistryConfig(findRegistryConfigByName(existing, name)) + if registry == nil { + registry = &SkillRegistryConfig{Name: name} + } + if err := registryNode.Decode(registry); err != nil { + return nil, err + } + registry.Name = name + decoded[name] = registry + } + return decoded, nil +} + func cloneRegistryParams(src map[string]any) map[string]any { if src == nil { return nil diff --git a/pkg/config/config_struct_test.go b/pkg/config/config_struct_test.go index 97d6eefab..e9a7f6661 100644 --- a/pkg/config/config_struct_test.go +++ b/pkg/config/config_struct_test.go @@ -304,6 +304,39 @@ func TestSkillsRegistriesConfigUnmarshalYAMLAppendsNewRegistryToExistingSlice(t assert.Equal(t, "https://github.com", github.BaseURL) } +func TestSkillsRegistriesConfigUnmarshalYAMLOverridesDefaultRegistryFields(t *testing.T) { + registries := DefaultConfig().Tools.Skills.Registries + + err := yaml.Unmarshal([]byte(`github: + enabled: false + base_url: https://ghe.example.com/git + proxy: http://127.0.0.1:7890 +`), ®istries) + assert.NoError(t, err) + + github, ok := registries.Get("github") + assert.True(t, ok) + assert.False(t, github.Enabled) + assert.Equal(t, "https://ghe.example.com/git", github.BaseURL) + assert.Equal(t, "http://127.0.0.1:7890", github.Param["proxy"]) +} + +func TestSkillsRegistriesConfigUnmarshalYAMLRetainsDefaultsForOmittedFields(t *testing.T) { + registries := DefaultConfig().Tools.Skills.Registries + + err := yaml.Unmarshal([]byte(`github: + auth_token: registry-token +`), ®istries) + assert.NoError(t, err) + + github, ok := registries.Get("github") + assert.True(t, ok) + assert.True(t, github.Enabled) + assert.Equal(t, "https://github.com", github.BaseURL) + assert.Equal(t, "registry-token", github.AuthToken.String()) + assert.Empty(t, github.Param) +} + func TestSkillsGithubConfigV0ToSkillsGithubConfigPreservesBaseURL(t *testing.T) { legacy := skillsGithubConfigV0{ BaseURL: "https://ghe.example.com/git",