Skip to content

Commit a340630

Browse files
author
Mikalai Radchuk
committed
Fixes reading properties with the same type
Some properties like `olm.package` only can appear in a bundle once and we currently handle this correctly. However properties such as `olm.gvk` and `olm.gvk.required` can be present multiple times in the list. The current implementation overrides all the instances with the one which is the last in the list. This modifies the code to be able to read in both cases. Signed-off-by: Mikalai Radchuk <[email protected]>
1 parent 6640aac commit a340630

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

internal/catalogmetadata/types.go

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type Bundle struct {
4141

4242
mu sync.RWMutex
4343
// these properties are lazy loaded as they are requested
44-
propertiesMap map[string]property.Property
44+
propertiesMap map[string][]*property.Property
4545
bundlePackage *property.Package
4646
semVersion *bsemver.Version
4747
requiredPackages []PackageRequired
@@ -74,7 +74,7 @@ func (b *Bundle) loadPackage() error {
7474
b.mu.Lock()
7575
defer b.mu.Unlock()
7676
if b.bundlePackage == nil {
77-
bundlePackage, err := loadFromProps[property.Package](b, property.TypePackage, true)
77+
bundlePackage, err := loadOneFromProps[property.Package](b, property.TypePackage, true)
7878
if err != nil {
7979
return err
8080
}
@@ -94,7 +94,7 @@ func (b *Bundle) loadRequiredPackages() error {
9494
b.mu.Lock()
9595
defer b.mu.Unlock()
9696
if b.requiredPackages == nil {
97-
requiredPackages, err := loadFromProps[[]PackageRequired](b, property.TypePackageRequired, false)
97+
requiredPackages, err := loadOneFromProps[[]PackageRequired](b, property.TypePackageRequired, false)
9898
if err != nil {
9999
return fmt.Errorf("error determining bundle required packages for bundle %q: %s", b.Name, err)
100100
}
@@ -119,7 +119,7 @@ func (b *Bundle) loadMediaType() error {
119119
b.mu.Lock()
120120
defer b.mu.Unlock()
121121
if b.mediaType == nil {
122-
mediaType, err := loadFromProps[string](b, PropertyBundleMediaType, false)
122+
mediaType, err := loadOneFromProps[string](b, PropertyBundleMediaType, false)
123123
if err != nil {
124124
return fmt.Errorf("error determining bundle mediatype for bundle %q: %s", b.Name, err)
125125
}
@@ -128,31 +128,47 @@ func (b *Bundle) loadMediaType() error {
128128
return nil
129129
}
130130

131-
func (b *Bundle) propertyByType(propType string) *property.Property {
131+
func (b *Bundle) propertiesByType(propType string) []*property.Property {
132132
if b.propertiesMap == nil {
133-
b.propertiesMap = make(map[string]property.Property)
133+
b.propertiesMap = make(map[string][]*property.Property)
134134
for _, prop := range b.Properties {
135-
b.propertiesMap[prop.Type] = prop
135+
b.propertiesMap[prop.Type] = append(b.propertiesMap[prop.Type], &prop)
136136
}
137137
}
138138

139-
prop, ok := b.propertiesMap[propType]
140-
if !ok {
141-
return nil
139+
return b.propertiesMap[propType]
140+
}
141+
142+
func loadOneFromProps[T any](bundle *Bundle, propType string, required bool) (T, error) {
143+
r, err := loadFromProps[T](bundle, propType, required)
144+
if err != nil {
145+
return *new(T), err
146+
}
147+
if len(r) > 1 {
148+
return *new(T), fmt.Errorf("expected 1 instance of property with type %q, got %d", propType, len(r))
142149
}
143-
return &prop
150+
if !required && len(r) == 0 {
151+
return *new(T), nil
152+
}
153+
154+
return r[0], nil
144155
}
145156

146-
func loadFromProps[T any](bundle *Bundle, propType string, required bool) (T, error) {
147-
parsedProp := *new(T)
148-
prop := bundle.propertyByType(propType)
149-
if prop != nil {
150-
if err := json.Unmarshal(prop.Value, &parsedProp); err != nil {
151-
return parsedProp, fmt.Errorf("property %q with value %q could not be parsed: %s", propType, prop.Value, err)
157+
func loadFromProps[T any](bundle *Bundle, propType string, required bool) ([]T, error) {
158+
props := bundle.propertiesByType(propType)
159+
if len(props) != 0 {
160+
result := []T{}
161+
for i := range props {
162+
parsedProp := *new(T)
163+
if err := json.Unmarshal(props[i].Value, &parsedProp); err != nil {
164+
return nil, fmt.Errorf("property %q with value %q could not be parsed: %s", propType, props[i].Value, err)
165+
}
166+
result = append(result, parsedProp)
152167
}
168+
return result, nil
153169
} else if required {
154-
return parsedProp, fmt.Errorf("bundle property with type %q not found", propType)
170+
return nil, fmt.Errorf("bundle property with type %q not found", propType)
155171
}
156172

157-
return parsedProp, nil
173+
return nil, nil
158174
}

0 commit comments

Comments
 (0)