Skip to content
29 changes: 27 additions & 2 deletions internal/setup/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3659,7 +3659,7 @@ var setupTests = []setupTest{{
},
relerror: "essential loop detected: mypkg1_myslice, mypkg2_myslice",
}, {
summary: "Format v3 expects a map in 'essential' (pkg)",
summary: "Format v3 expects a map in 'essential' (pkg), received a list",
input: map[string]string{
"chisel.yaml": strings.ReplaceAll(testutil.DefaultChiselYaml, "format: v1", "format: v3"),
"slices/mydir/mypkg.yaml": `
Expand All @@ -3673,7 +3673,20 @@ var setupTests = []setupTest{{
},
relerror: `cannot parse package "mypkg": essential expects a map`,
}, {
summary: "Format v3 expects a map in 'essential' (slice)",
summary: "Format v3 expects a map in 'essential' (pkg), received a string",
input: map[string]string{
"chisel.yaml": strings.ReplaceAll(testutil.DefaultChiselYaml, "format: v1", "format: v3"),
"slices/mydir/mypkg.yaml": `
package: mypkg
essential: not-a-list-or-map
slices:
myslice1:
myslice2:
`,
},
relerror: `cannot parse package "mypkg": essential expects a map`,
}, {
summary: "Format v3 expects a map in 'essential' (slice), received a list",
input: map[string]string{
"chisel.yaml": strings.ReplaceAll(testutil.DefaultChiselYaml, "format: v1", "format: v3"),
"slices/mydir/mypkg.yaml": `
Expand All @@ -3686,6 +3699,18 @@ var setupTests = []setupTest{{
`,
},
relerror: `cannot parse slice mypkg_myslice1: essential expects a map`,
}, {
summary: "Format v3 expects a map in 'essential' (slice), received a string",
input: map[string]string{
"chisel.yaml": strings.ReplaceAll(testutil.DefaultChiselYaml, "format: v1", "format: v3"),
"slices/mydir/mypkg.yaml": `
package: mypkg
slices:
myslice:
essential: not-a-list-or-map
`,
},
relerror: `cannot parse slice mypkg_myslice: essential expects a map`,
}, {
summary: "In format v3 'v3-essential' is not supported (pkg)",
input: map[string]string{
Expand Down
34 changes: 24 additions & 10 deletions internal/setup/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,31 @@ type yamlPackage struct {
V3Essential map[string]*yamlEssential `yaml:"v3-essential,omitempty"`
}

type essentialStyle int

const (
unsetEssential essentialStyle = iota
// invalidEssential is set when the marshaler was called but the value was of an invalid kind.
invalidEssential
// listEssential is set when the marshaler found a list.
// A list is valid only in format "v1" and "v2".
listEssential
// mapEssential is set when the marshaler found a map.
// A map is valid only from format "v3" onwards.
mapEssential
)

type yamlEssentialListMap struct {
Values map[string]*yamlEssential
// isList is set to true when the marshaler found a list and false if it
// found a map. The former is only valid in format "v1" and "v2" while the
// latter is valid from "v3" onwards.
isList bool
// Style of value the marshaler found.
style essentialStyle
}

func (es *yamlEssentialListMap) UnmarshalYAML(value *yaml.Node) error {
m := map[string]*yamlEssential{}
switch value.Kind {
case yaml.SequenceNode:
es.isList = true
es.style = listEssential
l := []string{}
err := value.Decode(&l)
if err != nil {
Expand All @@ -90,11 +102,13 @@ func (es *yamlEssentialListMap) UnmarshalYAML(value *yaml.Node) error {
m[sliceName] = &yamlEssential{}
}
case yaml.MappingNode:
es.isList = false
es.style = mapEssential
err := value.Decode(&m)
if err != nil {
return err
}
default:
es.style = invalidEssential
}
es.Values = m
return nil
Expand Down Expand Up @@ -441,26 +455,26 @@ func parsePackage(format, pkgName, pkgPath string, data []byte) (*Package, error
}

if format == "v1" || format == "v2" {
if len(yamlPkg.Essential.Values) > 0 && !yamlPkg.Essential.isList {
if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != listEssential {
return nil, fmt.Errorf("cannot parse package %q: essential expects a list", pkgName)
}
for sliceName, yamlSlice := range yamlPkg.Slices {
if len(yamlSlice.Essential.Values) > 0 && !yamlSlice.Essential.isList {
if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != listEssential {
return nil, fmt.Errorf("cannot parse slice %s: essential expects a list", SliceKey{pkgName, sliceName})
}
}
} else {
if yamlPkg.V3Essential != nil {
return nil, fmt.Errorf("cannot parse package %q: v3-essential is obsolete since format v3", pkgName)
}
if len(yamlPkg.Essential.Values) > 0 && yamlPkg.Essential.isList {
if yamlPkg.Essential.style != unsetEssential && yamlPkg.Essential.style != mapEssential {
return nil, fmt.Errorf("cannot parse package %q: essential expects a map", pkgName)
}
for sliceName, yamlSlice := range yamlPkg.Slices {
if yamlSlice.V3Essential != nil {
return nil, fmt.Errorf("cannot parse slice %s: v3-essential is obsolete since format v3", SliceKey{pkgName, sliceName})
}
if len(yamlSlice.Essential.Values) > 0 && yamlSlice.Essential.isList {
if yamlSlice.Essential.style != unsetEssential && yamlSlice.Essential.style != mapEssential {
return nil, fmt.Errorf("cannot parse slice %s: essential expects a map", SliceKey{pkgName, sliceName})
}
}
Expand Down
Loading