Make cascade front matter order deterministic

Fixes #12594
This commit is contained in:
Bjørn Erik Pedersen
2025-01-22 17:47:54 +01:00
parent 77a8e347bc
commit 7f0f50b133
10 changed files with 318 additions and 48 deletions

View File

@@ -104,9 +104,9 @@ func CheckCascadePattern(logger loggers.Logger, m PageMatcher) {
}
}
func DecodeCascadeConfig(logger loggers.Logger, in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, map[PageMatcher]maps.Params], error) {
buildConfig := func(in any) (map[PageMatcher]maps.Params, any, error) {
cascade := make(map[PageMatcher]maps.Params)
func DecodeCascadeConfig(logger loggers.Logger, in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]], error) {
buildConfig := func(in any) (*maps.Ordered[PageMatcher, maps.Params], any, error) {
cascade := maps.NewOrdered[PageMatcher, maps.Params]()
if in == nil {
return cascade, []map[string]any{}, nil
}
@@ -134,7 +134,7 @@ func DecodeCascadeConfig(logger loggers.Logger, in any) (*config.ConfigNamespace
for _, cfg := range cfgs {
m := cfg.Target
CheckCascadePattern(logger, m)
c, found := cascade[m]
c, found := cascade.Get(m)
if found {
// Merge
for k, v := range cfg.Params {
@@ -143,18 +143,18 @@ func DecodeCascadeConfig(logger loggers.Logger, in any) (*config.ConfigNamespace
}
}
} else {
cascade[m] = cfg.Params
cascade.Set(m, cfg.Params)
}
}
return cascade, cfgs, nil
}
return config.DecodeNamespace[[]PageMatcherParamsConfig](in, buildConfig)
return config.DecodeNamespace[[]PageMatcherParamsConfig, *maps.Ordered[PageMatcher, maps.Params]](in, buildConfig)
}
// DecodeCascade decodes in which could be either a map or a slice of maps.
func DecodeCascade(logger loggers.Logger, in any) (map[PageMatcher]maps.Params, error) {
func DecodeCascade(logger loggers.Logger, in any) (*maps.Ordered[PageMatcher, maps.Params], error) {
conf, err := DecodeCascadeConfig(logger, in)
if err != nil {
return nil, err

View File

@@ -133,16 +133,8 @@ func TestDecodeCascadeConfig(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(got, qt.IsNotNil)
c.Assert(got.Config, qt.DeepEquals,
map[PageMatcher]maps.Params{
{Path: "", Kind: "page", Lang: "", Environment: ""}: {
"b": "bv",
},
{Path: "", Kind: "page", Lang: "", Environment: "production"}: {
"a": "av",
},
},
)
c.Assert(got.Config.Keys(), qt.DeepEquals, []PageMatcher{{Kind: "page", Environment: "production"}, {Kind: "page"}})
c.Assert(got.Config.Values(), qt.DeepEquals, []maps.Params{{"a": string("av")}, {"b": string("bv")}})
c.Assert(got.SourceStructure, qt.DeepEquals, []PageMatcherParamsConfig{
{
Params: maps.Params{"a": string("av")},

View File

@@ -114,9 +114,9 @@ type PageConfig struct {
Content Source
// Compiled values.
CascadeCompiled map[page.PageMatcher]maps.Params
ContentMediaType media.Type `mapstructure:"-" json:"-"`
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
CascadeCompiled *maps.Ordered[page.PageMatcher, maps.Params] `mapstructure:"-" json:"-"`
ContentMediaType media.Type `mapstructure:"-" json:"-"`
IsFromContentAdapter bool `mapstructure:"-" json:"-"`
}
var DefaultPageConfig = PageConfig{