Skip to content

Commit 0b737df

Browse files
committed
more review updates
Signed-off-by: grokspawn <jordan@nimblewidget.com>
1 parent e4cc4a8 commit 0b737df

File tree

8 files changed

+237
-197
lines changed

8 files changed

+237
-197
lines changed

alpha/declcfg/declcfg.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,26 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"strings"
89

10+
"github.com/blang/semver/v4"
911
"golang.org/x/text/cases"
1012
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1113
"k8s.io/apimachinery/pkg/util/sets"
1214

15+
"github.com/operator-framework/operator-registry/alpha/model"
1316
"github.com/operator-framework/operator-registry/alpha/property"
1417
prettyunmarshaler "github.com/operator-framework/operator-registry/pkg/prettyunmarshaler"
1518
)
1619

20+
// Re-export VersionRelease/Release types/functions from model package to make it possible for users to only include this package and avoid import cycles
21+
type (
22+
Release = model.Release
23+
VersionRelease = model.VersionRelease
24+
)
25+
26+
var NewRelease = model.NewRelease
27+
1728
const (
1829
SchemaPackage = "olm.package"
1930
SchemaChannel = "olm.channel"
@@ -206,3 +217,76 @@ func (destination *DeclarativeConfig) Merge(src *DeclarativeConfig) {
206217
destination.Others = append(destination.Others, src.Others...)
207218
destination.Deprecations = append(destination.Deprecations, src.Deprecations...)
208219
}
220+
221+
// order by version, then
222+
// release, if present
223+
func (b *Bundle) Compare(other *Bundle) int {
224+
if b.Name == other.Name {
225+
return 0
226+
}
227+
avr, err := b.VersionRelease()
228+
if err != nil {
229+
return 0
230+
}
231+
otherVr, err := other.VersionRelease()
232+
if err != nil {
233+
return 0
234+
}
235+
return avr.Compare(otherVr)
236+
}
237+
238+
// constructs a VersionRelease from the olm.package property of the bundle
239+
// this handles the cases where the property is present, missing, or duplicated
240+
// if a release field is present in the property, it is used as-is
241+
// if it is NOT present in the property, but the version field contains build metadata,
242+
// we attempt to convert the build metadata into a release and strip the build metadata from the version.
243+
// This is to support bundles that use the legacy approach of encoding release information in the build metadata field of the version
244+
func (b *Bundle) VersionRelease() (*VersionRelease, error) {
245+
var (
246+
vr *VersionRelease
247+
)
248+
// loop over all properties, and do not break if we find a package property, in order to check for duplicates
249+
for _, prop := range b.Properties {
250+
switch prop.Type {
251+
case property.TypePackage:
252+
var p property.Package
253+
254+
// if we encounter more than one olm.package property, return an error
255+
if vr != nil {
256+
return nil, fmt.Errorf("must be exactly one property of type %q", SchemaPackage)
257+
}
258+
259+
if err := json.Unmarshal(prop.Value, &p); err != nil {
260+
return nil, fmt.Errorf("unable to unmarshal \"olm.package\" property for bundle %q: %v", b.Name, err)
261+
}
262+
pv, err := semver.Parse(p.Version)
263+
if err != nil {
264+
return nil, fmt.Errorf("invalid semver version %q in \"olm.package\" property for bundle %q: %v", p.Version, b.Name, err)
265+
}
266+
pr, err := NewRelease(p.Release)
267+
if err != nil {
268+
return nil, fmt.Errorf("invalid release %q in \"olm.package\" property for bundle %q: %v", p.Release, b.Name, err)
269+
}
270+
vr = &VersionRelease{
271+
Version: pv,
272+
Release: pr,
273+
}
274+
}
275+
}
276+
if vr == nil {
277+
return nil, fmt.Errorf("no \"olm.package\" property found for bundle %q", b.Name)
278+
}
279+
280+
// if the bundle's release isn't provided, see if we can use the legacy build metadata release approach to identify a release
281+
// if successful, remove the build metadata from the version
282+
if len(vr.Release) == 0 && vr.Version.Build != nil {
283+
newrel, err := NewRelease(strings.Join(vr.Version.Build, "."))
284+
if err != nil {
285+
return nil, fmt.Errorf("unable to convert build metadata to release for bundle %q: %v", b.Name, err)
286+
}
287+
vr.Release = newrel
288+
vr.Version.Build = nil
289+
}
290+
291+
return vr, nil
292+
}

alpha/declcfg/declcfg_to_model.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,12 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
146146
}
147147

148148
// Parse release version from the package property.
149-
var relver semver.Version
149+
var relver model.Release
150150
if props.Packages[0].Release != "" {
151-
relver, err = semver.Parse(fmt.Sprintf("0.0.0-%s", props.Packages[0].Release))
151+
relver, err = model.NewRelease(props.Packages[0].Release)
152152
if err != nil {
153153
return nil, fmt.Errorf("error parsing bundle %q release version %q: %v", b.Name, props.Packages[0].Release, err)
154154
}
155-
// only need to check for build metadata since we are using explicit zero major, minor, and patch versions above
156-
if len(relver.Build) != 0 {
157-
return nil, fmt.Errorf("bundle %q release version %q cannot contain build metadata", b.Name, props.Packages[0].Release)
158-
}
159155
}
160156

161157
channelDefinedEntries[b.Package] = channelDefinedEntries[b.Package].Delete(b.Name)
@@ -170,7 +166,8 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
170166
mb.Objects = b.Objects
171167
mb.PropertiesP = props
172168
mb.Version = ver
173-
mb.Release = relver
169+
// TODO: Jordan: follow-up will evolve the internal types for more consistent use of VersionRelease
170+
mb.Release = semver.Version{Pre: relver}
174171
}
175172
}
176173
if !found {

alpha/declcfg/declcfg_to_model_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ func TestConvertToModel(t *testing.T) {
444444
},
445445
{
446446
name: "Error/InvalidReleaseVersion",
447-
assertion: hasError(`error parsing bundle "foo.v0.1.0" release version "!!!": Invalid character(s) found in prerelease "!!!"`),
447+
assertion: hasError(`error parsing bundle "foo.v0.1.0" release version "!!!": invalid release "!!!": segment 0: Invalid character(s) found in prerelease "!!!"`),
448448
cfg: DeclarativeConfig{
449449
Packages: []Package{newTestPackage("foo", "alpha", svgSmallCircle)},
450450
Channels: []Channel{newTestChannel("foo", "alpha", ChannelEntry{Name: testBundleName("foo", "0.1.0")})},

alpha/declcfg/versionrelease.go

Lines changed: 0 additions & 168 deletions
This file was deleted.

0 commit comments

Comments
 (0)