@@ -25,26 +25,27 @@ type DefaultChannel struct {
2525	DefaultChannel  string  `json:"defaultchannel"` 
2626}
2727
28- type  BundleSource  struct  {
29- 	// possibly extend with support for other types of sources 
30- 	Path  string  `json:"bundlepath,omitempty"` 
31- }
32- 
33- const  TypeDefaultChannel  =  "olm.package.defaultchannel" 
34- const  TypeBundleSource  =  "olm.bundle.path" 
28+ const  (
29+ 	TypeDefaultChannel  =  "olm.package.defaultChannel" 
30+ 	TypeBundleSource    =  "olm.bundle.path" 
31+ 	TypeLabel           =  "olm.label" 
32+ 	TypeLabelRequired   =  "olm.label.required" 
33+ )
3534
36- func  entityFromBundle (catsrcID  string , pkg  * catalogsourceapi.Package , bundle  * catalogsourceapi.Bundle ) (* input.Entity , error ) {
35+ func  EntityFromBundle (catsrcID  string , pkg  * catalogsourceapi.Package , bundle  * catalogsourceapi.Bundle ) (* input.Entity , error ) {
3736	properties  :=  map [string ]string {}
3837	var  errs  []error 
3938
40- 	// All properties are json encoded lists of values, regarless of property type. 
41- 	// They can all be handled by unmarshalling into an (interface{}) - deppy does not need to know how to handle different types of properties. 
42- 	propsList  :=  map [string ]map [string ]struct {}{
43- 		property .TypeGVK :         {},
44- 		property .TypeGVKRequired : {},
45- 		//		property.TypePackage:         {}, 
46- 		property .TypePackageRequired : {},
47- 		//		property.TypeChannel:         {}, 
39+ 	// Multivalue properties 
40+ 	propsList  :=  map [string ]map [string ]struct {}{}
41+ 
42+ 	setPropertyValue  :=  func (key , value  string ) {
43+ 		if  _ , ok  :=  propsList [key ]; ! ok  {
44+ 			propsList [key ] =  map [string ]struct {}{}
45+ 		}
46+ 		if  _ , ok  :=  propsList [key ][value ]; ! ok  {
47+ 			propsList [key ][value ] =  struct {}{}
48+ 		}
4849	}
4950
5051	for  _ , prvAPI  :=  range  bundle .ProvidedApis  {
@@ -53,7 +54,7 @@ func entityFromBundle(catsrcID string, pkg *catalogsourceapi.Package, bundle *ca
5354			errs  =  append (errs , err )
5455			continue 
5556		}
56- 		propsList [ property .TypeGVK ][ string (apiValue )]  =   struct {}{} 
57+ 		setPropertyValue ( property .TypeGVK ,  string (apiValue )) 
5758	}
5859
5960	for  _ , reqAPI  :=  range  bundle .RequiredApis  {
@@ -62,72 +63,31 @@ func entityFromBundle(catsrcID string, pkg *catalogsourceapi.Package, bundle *ca
6263			errs  =  append (errs , err )
6364			continue 
6465		}
65- 		propsList [ property .TypeGVKRequired ][ string (apiValue )]  =   struct {}{} 
66+ 		setPropertyValue ( property .TypeGVKRequired ,  string (apiValue )) 
6667	}
6768
6869	for  _ , reqAPI  :=  range  bundle .Dependencies  {
69- 		propsList [property.TypeGVKRequired ][reqAPI.Value ] =  struct {}{}
70+ 		switch  reqAPI .Type  {
71+ 		case  property .TypeGVK :
72+ 			setPropertyValue (property .TypeGVKRequired , reqAPI .Value )
73+ 		case  property .TypePackage :
74+ 			setPropertyValue (property .TypePackageRequired , reqAPI .Value )
75+ 		case  TypeLabel : // legacy property 
76+ 			setPropertyValue (TypeLabelRequired , reqAPI .Value )
77+ 		default :
78+ 			setPropertyValue (reqAPI .Type , reqAPI .Value )
79+ 		}
7080	}
7181
72- 	pkgValue , err  :=  util .JSONMarshal (property.Package {
73- 		PackageName : bundle .PackageName ,
74- 		Version :     bundle .Version ,
75- 	})
76- 	if  err  !=  nil  {
77- 		errs  =  append (errs , err )
78- 	} else  {
79- 		properties [property .TypePackage ] =  string (pkgValue )
80- 		//		propsList[property.TypePackage][string(pkgValue)] = struct{}{} 
82+ 	ignoredProperties  :=  map [string ]struct {}{
83+ 		property .TypeBundleObject : {},
8184	}
8285
83- 	upValue , err  :=  util .JSONMarshal (UpgradeEdge {
84- 		Channel : property.Channel {
85- 			ChannelName : bundle .ChannelName ,
86- 		},
87- 		Replaces :  bundle .Replaces ,
88- 		Skips :     bundle .Skips ,
89- 		SkipRange : bundle .SkipRange ,
90- 		//		Version:   bundle.Version, 
91- 	})
92- 	if  err  !=  nil  {
93- 		errs  =  append (errs , err )
94- 	} else  {
95- 		properties [property .TypeChannel ] =  string (upValue )
96- 		//		propsList[property.TypeChannel][string(upValue)] = struct{}{} 
97- 	}
98- 
99- 	defaultValue , err  :=  util .JSONMarshal (DefaultChannel {
100- 		DefaultChannel : pkg .DefaultChannelName ,
101- 	})
102- 	if  err  !=  nil  {
103- 		errs  =  append (errs , err )
104- 	} else  {
105- 		propsList [TypeDefaultChannel ] =  map [string ]struct {}{string (defaultValue ): {}}
106- 	}
107- 
108- 	//sourceValue, err := util.JSONMarshal(BundleSource{ 
109- 	//	Path: bundle.BundlePath, 
110- 	//}) 
111- 	//if err != nil { 
112- 	//	errs = append(errs, err) 
113- 	//} else { 
114- 	//	propsList[TypeBundleSource] = map[string]struct{}{string(sourceValue): {}} 
115- 	//} 
116- 	properties [TypeBundleSource ] =  bundle .BundlePath 
117- 
11886	for  _ , p  :=  range  bundle .Properties  {
119- 		if  p .Type  ==  property .TypeChannel  ||  p .Type  ==  property .TypePackage  ||  p .Type  ==  TypeDefaultChannel  {
120- 			// avoid duplicates 
87+ 		if  _ , ok  :=  ignoredProperties [p .Type ]; ok  {
12188			continue 
12289		}
123- 		//if p.Type == property.TypePackage { 
124- 		//	// override the inferred package if explicitly specified in bundle properties 
125- 		//	propsList[p.Type] = map[string]struct{}{p.Value: {}} 
126- 		//} 
127- 		if  _ , ok  :=  propsList [p .Type ]; ! ok  {
128- 			propsList [p .Type ] =  map [string ]struct {}{}
129- 		}
130- 		propsList [p.Type ][p.Value ] =  struct {}{}
90+ 		setPropertyValue (p .Type , p .Value )
13191	}
13292
13393	for  pType , pValues  :=  range  propsList  {
@@ -157,10 +117,45 @@ func entityFromBundle(catsrcID string, pkg *catalogsourceapi.Package, bundle *ca
157117		}
158118		properties [pType ] =  string (pValue )
159119	}
120+ 
121+ 	// Singleton properties. 
122+ 	// `olm.package`, `olm.channel`, `olm.defaultChannel` 
123+ 	pkgValue , err  :=  util .JSONMarshal (property.Package {
124+ 		PackageName : bundle .PackageName ,
125+ 		Version :     bundle .Version ,
126+ 	})
127+ 	if  err  !=  nil  {
128+ 		errs  =  append (errs , err )
129+ 	} else  {
130+ 		properties [property .TypePackage ] =  string (pkgValue )
131+ 	}
132+ 
133+ 	upValue , err  :=  util .JSONMarshal (UpgradeEdge {
134+ 		Channel : property.Channel {
135+ 			ChannelName : bundle .ChannelName ,
136+ 		},
137+ 		Replaces :  bundle .Replaces ,
138+ 		Skips :     bundle .Skips ,
139+ 		SkipRange : bundle .SkipRange ,
140+ 		//		Version:   bundle.Version, 
141+ 	})
142+ 	if  err  !=  nil  {
143+ 		errs  =  append (errs , err )
144+ 	} else  {
145+ 		properties [property .TypeChannel ] =  string (upValue )
146+ 	}
147+ 
148+ 	properties [TypeDefaultChannel ] =  pkg .DefaultChannelName 
149+ 	properties [TypeBundleSource ] =  bundle .BundlePath 
150+ 
160151	if  len (errs ) >  0  {
161152		return  nil , fmt .Errorf ("failed to parse properties for bundle %s/%s in %s: %v" , bundle .GetPackageName (), bundle .GetVersion (), catsrcID , errors .NewAggregate (errs ))
162153	}
163154
164- 	entityID  :=  deppy .Identifier (fmt .Sprintf ("%s/%s/%s/%s" , catsrcID , bundle .PackageName , bundle .ChannelName , bundle .Version ))
165- 	return  input .NewEntity (entityID , properties ), nil 
155+ 	// Since multiple instances of bundle may exist for different channels, entityID must include reference to channel 
156+ 	entityIDFromBundle  :=  func (catsrcID  string , bundle  * catalogsourceapi.Bundle ) deppy.Identifier  {
157+ 		return  deppy .Identifier (fmt .Sprintf ("%s/%s/%s/%s" , catsrcID , bundle .PackageName , bundle .ChannelName , bundle .Version ))
158+ 	}
159+ 
160+ 	return  input .NewEntity (entityIDFromBundle (catsrcID , bundle ), properties ), nil 
166161}
0 commit comments