@@ -25,13 +25,6 @@ const (
2525
2626// ----
2727
28- type ChannelProperties struct {
29- property.Channel
30- Replaces string `json:"replaces,omitempty"`
31- Skips []string `json:"skips,omitempty"`
32- SkipRange string `json:"skipRange,omitempty"`
33- }
34-
3528type propertyRequirement bool
3629
3730const (
@@ -46,6 +39,10 @@ type PackageRequired struct {
4639
4740type GVK property.GVK
4841
42+ type Replaces struct {
43+ Replaces string `json:"replaces"`
44+ }
45+
4946func (g GVK ) String () string {
5047 return fmt .Sprintf (`group:"%s" version:"%s" kind:"%s"` , g .Group , g .Version , g .Kind )
5148}
@@ -64,15 +61,16 @@ type BundleEntity struct {
6461 * input.Entity
6562
6663 // these properties are lazy loaded as they are requested
67- bundlePackage * property.Package
68- providedGVKs []GVK
69- requiredGVKs []GVKRequired
70- requiredPackages []PackageRequired
71- channelProperties * ChannelProperties
72- semVersion * semver.Version
73- bundlePath string
74- mediaType string
75- mu sync.RWMutex
64+ bundlePackage * property.Package
65+ providedGVKs []GVK
66+ requiredGVKs []GVKRequired
67+ requiredPackages []PackageRequired
68+ channel * property.Channel
69+ replaces * Replaces
70+ semVersion * semver.Version
71+ bundlePath string
72+ mediaType string
73+ mu sync.RWMutex
7674}
7775
7876func NewBundleEntity (entity * input.Entity ) * BundleEntity {
@@ -121,14 +119,35 @@ func (b *BundleEntity) ChannelName() (string, error) {
121119 if err := b .loadChannelProperties (); err != nil {
122120 return "" , err
123121 }
124- return b .channelProperties .ChannelName , nil
122+ return b .channel .ChannelName , nil
125123}
126124
127- func (b * BundleEntity ) ChannelProperties () (* ChannelProperties , error ) {
125+ func (b * BundleEntity ) Channel () (* property. Channel , error ) {
128126 if err := b .loadChannelProperties (); err != nil {
129127 return nil , err
130128 }
131- return b .channelProperties , nil
129+ return b .channel , nil
130+ }
131+
132+ func (b * BundleEntity ) Replaces () (string , error ) {
133+ if err := b .loadReplaces (); err != nil {
134+ return "" , err
135+ }
136+ return b .replaces .Replaces , nil
137+ }
138+
139+ func (b * BundleEntity ) loadReplaces () error {
140+ b .mu .Lock ()
141+ defer b .mu .Unlock ()
142+ if b .replaces == nil {
143+ // TODO: move property name to constant
144+ replaces , err := loadFromEntity [Replaces ](b .Entity , "olm.replaces" , optional )
145+ if err != nil {
146+ return fmt .Errorf ("error determining replaces for entity '%s': %w" , b .ID , err )
147+ }
148+ b .replaces = & replaces
149+ }
150+ return nil
132151}
133152
134153func (b * BundleEntity ) BundlePath () (string , error ) {
@@ -228,12 +247,12 @@ func (b *BundleEntity) loadRequiredPackages() error {
228247func (b * BundleEntity ) loadChannelProperties () error {
229248 b .mu .Lock ()
230249 defer b .mu .Unlock ()
231- if b .channelProperties == nil {
232- channel , err := loadFromEntity [ChannelProperties ](b .Entity , property .TypeChannel , required )
250+ if b .channel == nil {
251+ channel , err := loadFromEntity [property. Channel ](b .Entity , property .TypeChannel , required )
233252 if err != nil {
234253 return fmt .Errorf ("error determining bundle channel properties for entity '%s': %w" , b .ID , err )
235254 }
236- b .channelProperties = & channel
255+ b .channel = & channel
237256 }
238257 return nil
239258}
@@ -255,6 +274,8 @@ func loadFromEntity[T interface{}](entity *input.Entity, propertyName string, re
255274 deserializedProperty := * new (T )
256275 propertyValue , ok := entity .Properties [propertyName ]
257276 if ok {
277+ // TODO: In order to avoid invalid properties we should use a decoder that only allows the properties we expect.
278+ // ie. decoder.DisallowUnknownFields()
258279 if err := json .Unmarshal ([]byte (propertyValue ), & deserializedProperty ); err != nil {
259280 return deserializedProperty , fmt .Errorf ("property '%s' ('%s') could not be parsed: %w" , propertyName , propertyValue , err )
260281 }
0 commit comments