From f16b39165bbf8880bb0b6d8fdce08bdf20b2d28a Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 28 Jul 2025 12:14:13 +0100 Subject: [PATCH] fs: add NonDefaultRC for discovering options in use This enables us to send rc messages with the config in use. --- fs/registry.go | 31 +++++++++++++++++++++++++++++++ fs/registry_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/fs/registry.go b/fs/registry.go index 2df893394..59e82936c 100644 --- a/fs/registry.go +++ b/fs/registry.go @@ -154,6 +154,37 @@ func (os Options) NonDefault(m configmap.Getter) configmap.Simple { return nonDefault } +// NonDefaultRC discovers which config values aren't at their default +// +// It expects a pointer to the current config struct in opts. +// +// It returns the overridden config in rc config format. +func (os Options) NonDefaultRC(opts any) (map[string]any, error) { + items, err := configstruct.Items(opts) + if err != nil { + return nil, err + } + itemsByName := map[string]*configstruct.Item{} + for i := range items { + item := &items[i] + itemsByName[item.Name] = item + } + var nonDefault = map[string]any{} + for i := range os { + opt := &os[i] + item, found := itemsByName[opt.Name] + if !found { + return nil, fmt.Errorf("key %q in OptionsInfo not found in Options struct", opt.Name) + } + value := fmt.Sprint(item.Value) + defaultValue := fmt.Sprint(opt.Default) + if value != defaultValue { + nonDefault[item.Field] = item.Value + } + } + return nonDefault, nil +} + // HasAdvanced discovers if any options have an Advanced setting func (os Options) HasAdvanced() bool { for i := range os { diff --git a/fs/registry_test.go b/fs/registry_test.go index 0ecaa5c50..593049c38 100644 --- a/fs/registry_test.go +++ b/fs/registry_test.go @@ -279,3 +279,30 @@ func TestOptionGetters(t *testing.T) { } } + +func TestOptionsNonDefaultRC(t *testing.T) { + type cfg struct { + X string `config:"x"` + Y int `config:"y"` + } + c := &cfg{X: "a", Y: 6} + opts := Options{ + {Name: "x", Default: "a"}, // at default, should be omitted + {Name: "y", Default: 5}, // non-default, should be included + } + + got, err := opts.NonDefaultRC(c) + require.NoError(t, err) + require.Equal(t, map[string]any{"Y": 6}, got) +} + +func TestOptionsNonDefaultRCMissingKey(t *testing.T) { + type cfg struct { + X string `config:"x"` + } + c := &cfg{X: "a"} + // Options refers to a key not present in the struct -> expect error + opts := Options{{Name: "missing", Default: ""}} + _, err := opts.NonDefaultRC(c) + assert.ErrorContains(t, err, "not found") +}