Skip to content

Commit

Permalink
Apply changes in new matchers to return a matcher with a nil semver
Browse files Browse the repository at this point in the history
  • Loading branch information
nmayorsplit committed May 9, 2024
1 parent 2bb3312 commit a002876
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 97 deletions.
20 changes: 13 additions & 7 deletions engine/grammar/matchers/datatypes/semver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datatypes

import (
"errors"
"fmt"
"strconv"

"strings"
Expand Down Expand Up @@ -46,10 +47,10 @@ func BuildSemver(version string) (*Semver, error) {
return nil, err
}

version, preReleaseClean := processVersion(major, minor, patch, preRelease, metadata)
version, preRelease = processVersion(major, minor, patch, preRelease, metadata)
return &Semver{
metadata: metadata,
preRelease: preReleaseClean,
preRelease: preRelease,
major: major,
minor: minor,
patch: patch,
Expand Down Expand Up @@ -125,13 +126,10 @@ func processComponents(version string) (int64, int64, int64, error) {
}

func processVersion(major int64, minor int64, patch int64, preRelease []string, metadata string) (string, []string) {
toReturnVersion := strconv.FormatInt(major, 10) + valueDelimiter + strconv.FormatInt(minor, 10) + valueDelimiter + strconv.FormatInt(patch, 10)
toReturnVersion := fmt.Sprintf("%d.%d.%d", major, minor, patch)
if len(preRelease) != 0 {
for i, _ := range preRelease {
preReleaseNumeric, err := strconv.ParseInt(preRelease[i], 10, 64)
if err == nil {
preRelease[i] = strconv.FormatInt(preReleaseNumeric, 10)
}
preRelease = sanitizeIntStr(preRelease, i)
}
toReturnVersion = toReturnVersion + preReleaseDelimiter + strings.Join(preRelease, valueDelimiter)
}
Expand All @@ -141,6 +139,14 @@ func processVersion(major int64, minor int64, patch int64, preRelease []string,
return toReturnVersion, preRelease
}

func sanitizeIntStr(preRelease []string, i int) []string {
preReleaseNumeric, err := strconv.ParseInt(preRelease[i], 10, 64)
if err == nil {
preRelease[i] = strconv.FormatInt(preReleaseNumeric, 10)
}
return preRelease
}

// Compare compares two semver versions
func (s *Semver) Compare(toCompare Semver) int {
if s.version == toCompare.version {
Expand Down
11 changes: 0 additions & 11 deletions engine/grammar/matchers/datatypes/semvererrors.go

This file was deleted.

40 changes: 10 additions & 30 deletions engine/grammar/matchers/matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/splitio/go-split-commons/v5/dtos"
"github.com/splitio/go-split-commons/v5/engine/grammar/matchers/datatypes"

"github.com/splitio/go-toolkit/v5/injection"
"github.com/splitio/go-toolkit/v5/logging"
Expand Down Expand Up @@ -361,15 +360,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L
"Building EqualToSemverMatcher with negate=%t, regex=%s, attributeName=%v",
dto.Negate, *dto.String, attributeName,
))
matcherSemver, err := NewEqualToSemverMatcher(
matcher = NewEqualToSemverMatcher(
*dto.String,
dto.Negate,
attributeName,
logger,
)
if err != nil {
return nil, err
}
matcher = matcherSemver
case MatcherTypeGreaterThanOrEqualToSemver:
if dto.String == nil {
return nil, ErrInvalidGTOESemver
Expand All @@ -378,15 +374,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L
"Building GreaterThanOrEqualToSemverMatcher with negate=%t, semver=%s, attributeName=%v",
dto.Negate, *dto.String, attributeName,
))
matcherSemver, err := NewGreaterThanOrEqualToSemverMatcher(
matcher = NewGreaterThanOrEqualToSemverMatcher(
dto.Negate,
*dto.String,
attributeName,
logger,
)
if err != nil {
return nil, err
}
matcher = matcherSemver
case MatcherTypeLessThanOrEqualToSemver:
if dto.String == nil {
return nil, ErrInvalidLTOESemver
Expand All @@ -395,15 +388,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L
"Building LessThanOrEqualToSemverMatcher with negate=%t, regex=%s, attributeName=%v",
dto.Negate, *dto.String, attributeName,
))
matcherSemver, err := NewLessThanOrEqualToSemverMatcher(
matcher = NewLessThanOrEqualToSemverMatcher(
*dto.String,
dto.Negate,
attributeName,
logger,
)
if err != nil {
return nil, err
}
matcher = matcherSemver
case MatcherTypeBetweenSemver:
if dto.BetweenString.Start == nil || dto.BetweenString.End == nil {
return nil, ErrInvalidLBetweenSemver
Expand All @@ -412,16 +402,13 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L
"Building BetweenSemverMatcher with negate=%t, regexStart=%s, regexEnd=%s, attributeName=%v",
dto.Negate, *dto.BetweenString.Start, *dto.BetweenString.End, attributeName,
))
matcherSemver, err := NewBetweenSemverMatcher(
matcher = NewBetweenSemverMatcher(
*dto.BetweenString.Start,
*dto.BetweenString.End,
dto.Negate,
attributeName,
logger,
)
if err != nil {
return nil, err
}
matcher = matcherSemver
case MatcherTypeInListSemver:
if dto.Whitelist == nil {
return nil, ErrInvalidLInListSemver
Expand All @@ -430,19 +417,12 @@ func BuildMatcher(dto *dtos.MatcherDTO, ctx *injection.Context, logger logging.L
"Building ErrInvalidLInListSemver with negate=%t, regex=%v, attributeName=%v",
dto.Negate, dto.Whitelist.Whitelist, attributeName,
))
matcherSemver, warnings := NewInListSemverMatcher(
matcher = NewInListSemverMatcher(
dto.Whitelist.Whitelist,
dto.Negate,
attributeName,
logger,
)
if len(warnings) != 0 {
for _, err := range warnings {
if errType, ok := err.(datatypes.SemverValidatonError); ok {
logger.Warning(errType.Message)
}
}
}
matcher = matcherSemver
default:
return nil, errors.New("Matcher not found")
}
Expand Down
76 changes: 44 additions & 32 deletions engine/grammar/matchers/semver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import (

"github.com/splitio/go-split-commons/v5/engine/grammar/matchers/datatypes"
"github.com/splitio/go-toolkit/v5/datastructures/set"
"github.com/splitio/go-toolkit/v5/logging"
)

// EqualToSemverMatcher struct to hold the semver to compare
type EqualToSemverMatcher struct {
Matcher
semver datatypes.Semver
semver *datatypes.Semver
}

// Match will match if the comparisonValue is equal to the matchingValue
func (e *EqualToSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
if e.semver == nil {
return false
}
matchingKey, err := e.matchingKey(key, attributes)
if err != nil {
e.logger.Warning(fmt.Sprintf("EqualToSemverMatcher: %s", err.Error()))
Expand All @@ -39,24 +43,24 @@ func (e *EqualToSemverMatcher) Match(key string, attributes map[string]interface
}

// NewEqualToSemverMatcher returns a pointer to a new instance of EqualToSemverMatcher
func NewEqualToSemverMatcher(cmpVal string, negate bool, attributeName *string) (*EqualToSemverMatcher, error) {
func NewEqualToSemverMatcher(cmpVal string, negate bool, attributeName *string, logger logging.LoggerInterface) *EqualToSemverMatcher {
semver, err := datatypes.BuildSemver(cmpVal)
if err != nil {
return nil, err
logger.Error(fmt.Sprintf("couldnt't build semver %s for EQUAL_TO_SEMVER matcher: %s", cmpVal, err.Error()))
}
return &EqualToSemverMatcher{
Matcher: Matcher{
negate: negate,
attributeName: attributeName,
},
semver: *semver,
}, nil
semver: semver,
}
}

// GreaterThanOrEqualToSemverMatcher struct to hold the semver to compare
type GreaterThanOrEqualToSemverMatcher struct {
Matcher
semver datatypes.Semver
semver *datatypes.Semver
}

// Match compares the semver of the key with the semver in the feature flag
Expand All @@ -79,34 +83,37 @@ func (g *GreaterThanOrEqualToSemverMatcher) Match(key string, attributes map[str
return false
}

result := semver.Compare(g.semver) >= 0
result := semver.Compare(*g.semver) >= 0
g.logger.Debug(fmt.Sprintf("%s >= %s | Result: %t", semver.Version(), g.semver.Version(), result))
return result
}

// NewGreaterThanOrEqualToSemverMatcher returns an instance of GreaterThanOrEqualToSemverMatcher
func NewGreaterThanOrEqualToSemverMatcher(negate bool, compareTo string, attributeName *string) (*GreaterThanOrEqualToSemverMatcher, error) {
func NewGreaterThanOrEqualToSemverMatcher(negate bool, compareTo string, attributeName *string, logger logging.LoggerInterface) *GreaterThanOrEqualToSemverMatcher {
semver, err := datatypes.BuildSemver(compareTo)
if err != nil {
return nil, err
logger.Error(fmt.Sprintf("couldnt't build semver %s for GREATER_THAN_OR_EQUAL_TO_SEMVER matcher: %s", compareTo, err.Error()))
}
return &GreaterThanOrEqualToSemverMatcher{
Matcher: Matcher{
negate: negate,
attributeName: attributeName,
},
semver: *semver,
}, nil
semver: semver,
}
}

// LessThanOrEqualToSemverMatcher struct to hold the semver to compare
type LessThanOrEqualToSemverMatcher struct {
Matcher
semver datatypes.Semver
semver *datatypes.Semver
}

// Match will match if the comparisonValue is less or equal to the matchingValue
func (l *LessThanOrEqualToSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
if l.semver == nil {
return false
}
matchingKey, err := l.matchingKey(key, attributes)
if err != nil {
l.logger.Warning(fmt.Sprintf("LessThanOrEqualToSemverMatcher: %s", err.Error()))
Expand All @@ -125,35 +132,38 @@ func (l *LessThanOrEqualToSemverMatcher) Match(key string, attributes map[string
return false
}

result := semver.Compare(l.semver) <= 0
result := semver.Compare(*l.semver) <= 0
l.logger.Debug(fmt.Sprintf("%s >= %s | Result: %t", semver.Version(), l.semver.Version(), result))
return result
}

// NewLessThanOrEqualToSemverMatcher returns a pointer to a new instance of LessThanOrEqualToSemverMatcher
func NewLessThanOrEqualToSemverMatcher(compareTo string, negate bool, attributeName *string) (*LessThanOrEqualToSemverMatcher, error) {
func NewLessThanOrEqualToSemverMatcher(compareTo string, negate bool, attributeName *string, logger logging.LoggerInterface) *LessThanOrEqualToSemverMatcher {
semver, err := datatypes.BuildSemver(compareTo)
if err != nil {
return nil, err
logger.Error(fmt.Sprintf("couldnt't build semver %s for LESS_THAN_OR_EQUAL_TO_SEMVER matcher: %s", compareTo, err.Error()))
}
return &LessThanOrEqualToSemverMatcher{
Matcher: Matcher{
negate: negate,
attributeName: attributeName,
},
semver: *semver,
}, nil
semver: semver,
}
}

// BetweenSemverMatcher struct to hold the semver to compare
type BetweenSemverMatcher struct {
Matcher
startSemver datatypes.Semver
endSemver datatypes.Semver
startSemver *datatypes.Semver
endSemver *datatypes.Semver
}

// Match will match if the comparisonValue is between to the matchingValue
func (b *BetweenSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
if b.startSemver == nil || b.endSemver == nil {
return false
}
matchingKey, err := b.matchingKey(key, attributes)
if err != nil {
b.logger.Warning(fmt.Sprintf("BetweenSemverMatcher: %s", err.Error()))
Expand All @@ -172,29 +182,29 @@ func (b *BetweenSemverMatcher) Match(key string, attributes map[string]interface
return false
}

result := semver.Compare(b.startSemver) >= 0 && semver.Compare(b.endSemver) <= 0
result := semver.Compare(*b.startSemver) >= 0 && semver.Compare(*b.endSemver) <= 0
b.logger.Debug(fmt.Sprintf("%s between %s and %s | Result: %t", semver.Version(), b.startSemver.Version(), b.endSemver.Version(), result))
return result
}

// NewBetweenSemverMatcher returns a pointer to a new instance of BetweenSemverMatcher
func NewBetweenSemverMatcher(startVal string, endVal string, negate bool, attributeName *string) (*BetweenSemverMatcher, error) {
func NewBetweenSemverMatcher(startVal string, endVal string, negate bool, attributeName *string, logger logging.LoggerInterface) *BetweenSemverMatcher {
startSemver, err := datatypes.BuildSemver(startVal)
if err != nil {
return nil, err
logger.Error(fmt.Sprintf("couldnt't build semver %s for BETWEEN_SEMVER matcher, ignoring: %s", startVal, err.Error()))
}
endSemver, err := datatypes.BuildSemver(endVal)
if err != nil {
return nil, err
logger.Error(fmt.Sprintf("couldnt't build semver %s for BETWEEN_SEMVER matcher, ignoring: %s", endVal, err.Error()))
}
return &BetweenSemverMatcher{
Matcher: Matcher{
negate: negate,
attributeName: attributeName,
},
startSemver: *startSemver,
endSemver: *endSemver,
}, nil
startSemver: startSemver,
endSemver: endSemver,
}
}

// InListSemverMatcher struct to hold the semver to compare
Expand All @@ -205,6 +215,9 @@ type InListSemverMatcher struct {

// Match will match if the comparisonValue is in list to the matchingValue
func (i *InListSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
if i.semvers.IsEmpty() {
return false
}
matchingKey, err := i.matchingKey(key, attributes)
if err != nil {
i.logger.Warning(fmt.Sprintf("InListSemverMatcher: %s", err.Error()))
Expand All @@ -226,15 +239,14 @@ func (i *InListSemverMatcher) Match(key string, attributes map[string]interface{
}

// NewInListSemverMatcher returns a pointer to a new instance of InListSemverMatcher
func NewInListSemverMatcher(cmpList []string, negate bool, attributeName *string) (*InListSemverMatcher, []error) {
func NewInListSemverMatcher(setVersions []string, negate bool, attributeName *string, logger logging.LoggerInterface) *InListSemverMatcher {
semvers := set.NewSet()
var errs []error
for _, str := range cmpList {
semver, err := datatypes.BuildSemver(str)
for _, version := range setVersions {
semver, err := datatypes.BuildSemver(version)
if err == nil {
semvers.Add(semver.Version())
} else {
errs = append(errs, err)
logger.Error(fmt.Sprintf("couldnt't build semver %s for IN_LIST_SEMVER matcher, ignoring: %s", version, err.Error()))
}
}
return &InListSemverMatcher{
Expand All @@ -243,5 +255,5 @@ func NewInListSemverMatcher(cmpList []string, negate bool, attributeName *string
attributeName: attributeName,
},
semvers: semvers,
}, errs
}
}
Loading

0 comments on commit a002876

Please sign in to comment.