Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Masterminds/semver #374

Merged
merged 3 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/v1alpha1/operator_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type OperatorSpec struct {
PackageName string `json:"packageName"`

//+kubebuilder:validation:MaxLength:=64
//+kubebuilder:validation:Pattern=^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$
//+kubebuilder:validation:Pattern=`^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$`
ncdc marked this conversation as resolved.
Show resolved Hide resolved
//+kubebuilder:Optional
// Version is an optional semver constraint on the package version. If not specified, the latest version available of the package will be installed.
// If specified, the specific version of the package will be installed so long as it is available in any of the content sources available.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ spec:
sources available. Examples: 1.2.3, 1.0.0-alpha, 1.0.0-rc.1 \n For
more information on semver, please see https://semver.org/"
maxLength: 64
pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$
pattern: ^(\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|[x|X|\*])(\.(0|[1-9]\d*|x|X|\*]))?(\.(0|[1-9]\d*|x|X|\*))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)((?:\s+|,\s*|\s*\|\|\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\^)\s*(v?(0|[1-9]\d*|x|X|\*])(\.(0|[1-9]\d*|x|X|\*))?(\.(0|[1-9]\d*|x|X|\*]))?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?)\s*)*$
type: string
required:
- packageName
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/operator-framework/operator-controller
go 1.20

require (
github.com/Masterminds/semver/v3 v3.2.0
github.com/blang/semver/v4 v4.0.0
github.com/go-logr/logr v1.2.4
github.com/onsi/ginkgo/v2 v2.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
Expand Down
59 changes: 58 additions & 1 deletion internal/controllers/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ var _ = Describe("Operator Spec Validations", func() {
"1.2.3-pre+bad_metadata",
"1.2.-3",
".1.2.3",
"<<1.2.3",
">>1.2.3",
">~1.2.3",
"==1.2.3",
"=!1.2.3",
"!1.2.3",
"1.Y",
">1.2.3 && <2.3.4",
">1.2.3;<2.3.4",
"1.2.3 - 2.3.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth including the blang '!=' equivalent here? (e.g. "!1.2.3")

Copy link
Contributor Author

@tmshort tmshort Aug 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably.

}
for _, invalidSemver := range invalidSemvers {
err := cl.Create(ctx, operator(operatorsv1alpha1.OperatorSpec{
Expand All @@ -69,7 +79,54 @@ var _ = Describe("Operator Spec Validations", func() {
}))

Expect(err).To(HaveOccurred(), "expected error for invalid semver %q", invalidSemver)
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-(0|[1-9]\\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$'"))
// Don't need to include the whole regex, this should be enough to match the MasterMinds regex
Expect(err.Error()).To(ContainSubstring("spec.version in body should match '^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)"))
}
})
It("should pass if a valid semver range given", func() {
validSemvers := []string{
">=1.2.3",
"=>1.2.3",
">= 1.2.3",
">=v1.2.3",
">= v1.2.3",
"<=1.2.3",
"=<1.2.3",
"=1.2.3",
"!=1.2.3",
"<1.2.3",
">1.2.3",
"~1.2.2",
"~>1.2.3",
"^1.2.3",
"1.2.3",
"v1.2.3",
"1.x",
"1.X",
"1.*",
"1.2.x",
"1.2.X",
"1.2.*",
">=1.2.3 <2.3.4",
">=1.2.3,<2.3.4",
">=1.2.3, <2.3.4",
"<1.2.3||>2.3.4",
"<1.2.3|| >2.3.4",
"<1.2.3 ||>2.3.4",
"<1.2.3 || >2.3.4",
">1.0.0,<1.2.3 || >2.1.0",
"<1.2.3-abc >2.3.4-def",
"<1.2.3-abc+def >2.3.4-ghi+jkl",
}
for _, validSemver := range validSemvers {
op := operator(operatorsv1alpha1.OperatorSpec{
PackageName: "package",
Version: validSemver,
})
err := cl.Create(ctx, op)
Expect(err).NotTo(HaveOccurred(), "expected success for semver range '%q': %w", validSemver, err)
err = cl.Delete(ctx, op)
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting valid semver '%q': %w", validSemver, err)
}
})
It("should fail if an invalid channel name is given", func() {
Expand Down
4 changes: 2 additions & 2 deletions internal/controllers/validators/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package validators
import (
"fmt"

bsemver "github.com/blang/semver/v4"
mmsemver "github.com/Masterminds/semver/v3"

operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
)
Expand All @@ -18,7 +18,7 @@ func validateSemver(operator *operatorsv1alpha1.Operator) error {
if operator.Spec.Version == "" {
return nil
}
if _, err := bsemver.Parse(operator.Spec.Version); err != nil {
if _, err := mmsemver.NewConstraint(operator.Spec.Version); err != nil {
return fmt.Errorf("invalid .spec.version: %w", err)
}
return nil
Expand Down
10 changes: 9 additions & 1 deletion internal/resolution/entities/bundle_entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sync"

mmsemver "github.com/Masterminds/semver/v3"
bsemver "github.com/blang/semver/v4"
"github.com/operator-framework/deppy/pkg/deppy/input"
"github.com/operator-framework/operator-registry/alpha/property"
Expand Down Expand Up @@ -87,13 +88,20 @@ func (b *BundleEntity) PackageName() (string, error) {
return b.bundlePackage.PackageName, nil
}

func (b *BundleEntity) Version() (*bsemver.Version, error) {
func (b *BundleEntity) VersionBlang() (*bsemver.Version, error) {
if err := b.loadPackage(); err != nil {
return nil, err
}
return b.semVersion, nil
}

func (b *BundleEntity) VersionMasterminds() (*mmsemver.Version, error) {
if err := b.loadPackage(); err != nil {
return nil, err
}
return mmsemver.NewVersion(b.bundlePackage.Version)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the asymmetry of VersionBlang() stuff being parsed during b.loadPackage() and the masterminds version being parsed here every time is maybe a bit unexpected and feels a bit off?

Other potential options:

  • add a new sibling field to b.semVersion, parse both during loadPackage()
  • parse into a blang version and then just build a masterminds.Version struct (either here or in loadPackage) using the blang version fields (this might be nice because its one fewer error to handle)
  • have this Version() method just return a string and expect that caller to do the parsing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option: do the (option 2) conversion from blang version to masterminds version in the InMastermindsVersionRange() function.

Copy link
Contributor Author

@tmshort tmshort Aug 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR: this is what happens when you try to optimize code coverage!

  1. I had created a new field, but all errors occurred during blang code processing (since it's just a simple version), and subsequently the masterminds error handling code was never executed, lowering code coverage. I could get rid of the error handling code, but that's bad form.
  2. The Masterminds.Version struct has no user-accessible fields, so you can't create the structure that way. It actually makes more sense to do a blang.Version.String() and feed that into Masterminds.NewVersion(), but it's the same error handling problem as option 1.
  3. This causes the version string to be parsed all the time, also non-optimal, and worse performance than option 1.

EDIT: Using just one semver library would make this moot.
EDIT 2: Option 3 is probably the cleanest in terms of API cleanliness, but not efficiency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option: do the (option 2) conversion from blang version to masterminds version in the InMastermindsVersionRange() function.

AFAICT, this means passing an blang structure into a mastermind-named function, which seems bad form.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means passing an blang structure into a mastermind-named function, which seems bad form.

I don't think so.

func InMastermindsSemverRange(semverRange *mmsemver.Constraints) input.Predicate {
	return func(entity *input.Entity) bool {
		bundleEntity := olmentity.NewBundleEntity(entity)
		bundleVersion, err := bundleEntity.Version() // this is a blang version
		if err != nil {
			return false
		}
		return semverRange.Check(blangToMasterminds(bundleVersion))
	}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@tmshort tmshort Aug 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although option 3 might be the cleanest, it is changing the behavior of sortVersion().

Anything I do to try to fix the nit will negatively impact code coverage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, trying to cover every error path just leads to brittle tests that make refactoring hard. I think as long as we're covering the happy paths, and the coverage "regression" is only happening because of some refactoring of when/how errors are handled, we shouldn't spend time dealing in the 1s or .1s of coverage percentages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to specify a (minimum, err maximum? negative) threshold for CodeCov?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was thinking of this function: https://github.com/Masterminds/semver/blob/2f39fdc11c33c38e8b8b15b1f04334ba84e751f2/version.go#L214

Because of the pre and metadata fields, etc. it's just easier to do all conversions via .String().

}

func (b *BundleEntity) ProvidedGVKs() ([]GVK, error) {
if err := b.loadProvidedGVKs(); err != nil {
return nil, err
Expand Down
30 changes: 25 additions & 5 deletions internal/resolution/entities/bundle_entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"testing"

mmsemver "github.com/Masterminds/semver/v3"
bsemver "github.com/blang/semver/v4"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -48,19 +49,28 @@ var _ = Describe("BundleEntity", func() {
})

Describe("Version", func() {
It("should return the bundle version if present", func() {
It("should return the bundle blang version if present", func() {
entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.14.0\"}",
})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.Version()
version, err := bundleEntity.VersionBlang()
Expect(err).ToNot(HaveOccurred())
Expect(*version).To(Equal(bsemver.MustParse("0.14.0")))
})
It("should return the bundle Masterminds version if present", func() {
entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.14.0\"}",
})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.VersionMasterminds()
Expect(err).ToNot(HaveOccurred())
Expect(*version).To(Equal(*mmsemver.MustParse("0.14.0")))
})
It("should return an error if the property is not found", func() {
entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.Version()
version, err := bundleEntity.VersionBlang()
Expect(version).To(BeNil())
Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': required property 'olm.package' not found"))
})
Expand All @@ -69,7 +79,7 @@ var _ = Describe("BundleEntity", func() {
"olm.package": "badPackageStructure",
})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.Version()
version, err := bundleEntity.VersionBlang()
Expect(version).To(BeNil())
Expect(err.Error()).To(Equal("error determining package for entity 'operatorhub/prometheus/0.14.0': property 'olm.package' ('badPackageStructure') could not be parsed: invalid character 'b' looking for beginning of value"))
})
Expand All @@ -78,8 +88,18 @@ var _ = Describe("BundleEntity", func() {
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"badversion\"}",
})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.Version()
version, err := bundleEntity.VersionBlang()
Expect(version).To(BeNil())
Expect(err.Error()).To(Equal("could not parse semver (badversion) for entity 'operatorhub/prometheus/0.14.0': No Major.Minor.Patch elements found"))
})
It("should return error if the version is malformed", func() {
entity := input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"badversion\"}",
})
bundleEntity := olmentity.NewBundleEntity(entity)
version, err := bundleEntity.VersionMasterminds()
Expect(version).To(BeNil())
// This is still a blang error, as it does not get to the Masterminds code
Expect(err.Error()).To(Equal("could not parse semver (badversion) for entity 'operatorhub/prometheus/0.14.0': No Major.Minor.Patch elements found"))
})
})
Expand Down
16 changes: 14 additions & 2 deletions internal/resolution/util/predicates/predicates.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package predicates

import (
mmsemver "github.com/Masterminds/semver/v3"
bsemver "github.com/blang/semver/v4"
"github.com/operator-framework/deppy/pkg/deppy/input"

Expand All @@ -18,10 +19,21 @@ func WithPackageName(packageName string) input.Predicate {
}
}

func InSemverRange(semverRange bsemver.Range) input.Predicate {
func InMastermindsSemverRange(semverRange *mmsemver.Constraints) input.Predicate {
return func(entity *input.Entity) bool {
bundleEntity := olmentity.NewBundleEntity(entity)
bundleVersion, err := bundleEntity.Version()
bundleVersion, err := bundleEntity.VersionMasterminds()
if err != nil {
return false
}
return semverRange.Check(bundleVersion)
}
}

func InBlangSemverRange(semverRange bsemver.Range) input.Predicate {
return func(entity *input.Entity) bool {
bundleEntity := olmentity.NewBundleEntity(entity)
bundleVersion, err := bundleEntity.VersionBlang()
if err != nil {
return false
}
Expand Down
29 changes: 25 additions & 4 deletions internal/resolution/util/predicates/predicates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package predicates_test
import (
"testing"

mmsemver "github.com/Masterminds/semver/v3"
bsemver "github.com/blang/semver/v4"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -33,20 +34,40 @@ var _ = Describe("Predicates", func() {
})
})

Describe("InSemverRange", func() {
Describe("InMastermindsSemverRange", func() {
It("should return true when the entity has the has version in the right range", func() {
entity := input.NewEntity("test", map[string]string{
property.TypePackage: `{"packageName": "mypackage", "version": "1.0.0"}`,
})
inRange, err := mmsemver.NewConstraint(">=1.0.0")
Expect(err).NotTo(HaveOccurred())
notInRange, err := mmsemver.NewConstraint(">=2.0.0")
Expect(err).NotTo(HaveOccurred())
Expect(predicates.InMastermindsSemverRange(inRange)(entity)).To(BeTrue())
Expect(predicates.InMastermindsSemverRange(notInRange)(entity)).To(BeFalse())
})
It("should return false when the entity does not have a version", func() {
entity := input.NewEntity("test", map[string]string{})
inRange, err := mmsemver.NewConstraint(">=1.0.0")
Expect(err).NotTo(HaveOccurred())
Expect(predicates.InMastermindsSemverRange(inRange)(entity)).To(BeFalse())
})
})

Describe("InBlangSemverRange", func() {
It("should return true when the entity has the has version in the right range", func() {
entity := input.NewEntity("test", map[string]string{
property.TypePackage: `{"packageName": "mypackage", "version": "1.0.0"}`,
})
inRange := bsemver.MustParseRange(">=1.0.0")
notInRange := bsemver.MustParseRange(">=2.0.0")
Expect(predicates.InSemverRange(inRange)(entity)).To(BeTrue())
Expect(predicates.InSemverRange(notInRange)(entity)).To(BeFalse())
Expect(predicates.InBlangSemverRange(inRange)(entity)).To(BeTrue())
Expect(predicates.InBlangSemverRange(notInRange)(entity)).To(BeFalse())
})
It("should return false when the entity does not have a version", func() {
entity := input.NewEntity("test", map[string]string{})
inRange := bsemver.MustParseRange(">=1.0.0")
Expect(predicates.InSemverRange(inRange)(entity)).To(BeFalse())
Expect(predicates.InBlangSemverRange(inRange)(entity)).To(BeFalse())
})
})

Expand Down
4 changes: 2 additions & 2 deletions internal/resolution/util/sort/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ func channelOrder(e1, e2 *entities.BundleEntity) int {
}

func versionOrder(e1, e2 *entities.BundleEntity) int {
ver1, err1 := e1.Version()
ver2, err2 := e2.Version()
ver1, err1 := e1.VersionBlang()
ver2, err2 := e2.VersionBlang()
errComp := compareErrors(err1, err2)
if errComp != 0 {
// the sign gets inverted because version is sorted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (b *BundlesAndDepsVariableSource) getEntityDependencies(ctx context.Context
if err != nil {
return nil, err
}
packageDependencyBundles, err := entitySource.Filter(ctx, input.And(predicates.WithPackageName(requiredPackage.PackageName), predicates.InSemverRange(semverRange)))
packageDependencyBundles, err := entitySource.Filter(ctx, input.And(predicates.WithPackageName(requiredPackage.PackageName), predicates.InBlangSemverRange(semverRange)))
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/resolution/variablesources/required_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"

bsemver "github.com/blang/semver/v4"
mmsemver "github.com/Masterminds/semver/v3"
"github.com/operator-framework/deppy/pkg/deppy"
"github.com/operator-framework/deppy/pkg/deppy/input"

Expand All @@ -21,14 +21,14 @@ type RequiredPackageVariableSourceOption func(*RequiredPackageVariableSource) er
func InVersionRange(versionRange string) RequiredPackageVariableSourceOption {
return func(r *RequiredPackageVariableSource) error {
if versionRange != "" {
vr, err := bsemver.ParseRange(versionRange)
vr, err := mmsemver.NewConstraint(versionRange)
if err == nil {
r.versionRange = versionRange
r.predicates = append(r.predicates, predicates.InSemverRange(vr))
r.predicates = append(r.predicates, predicates.InMastermindsSemverRange(vr))
return nil
}

return fmt.Errorf("invalid version range '%s': %v", versionRange, err)
return fmt.Errorf("invalid version range '%s': %w", versionRange, err)
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var _ = Describe("RequiredPackageVariableSource", func() {
It("should filter by version range", func() {
// recreate source with version range option
var err error
rpvs, err = variablesources.NewRequiredPackageVariableSource(packageName, variablesources.InVersionRange(">=1.0.0 !2.0.0 <3.0.0"))
rpvs, err = variablesources.NewRequiredPackageVariableSource(packageName, variablesources.InVersionRange(">=1.0.0 !=2.0.0 <3.0.0"))
ncdc marked this conversation as resolved.
Show resolved Hide resolved
Expect(err).NotTo(HaveOccurred())

variables, err := rpvs.GetVariables(context.TODO(), mockEntitySource)
Expand Down