mattermost-community-enterp.../vendor/github.com/splitio/go-split-commons/v7/engine/grammar/semver.go
Claude ec1f89217a Merge: Complete Mattermost Server with Community Enterprise
Full Mattermost server source with integrated Community Enterprise features.
Includes vendor directory for offline/air-gapped builds.

Structure:
- enterprise-impl/: Enterprise feature implementations
- enterprise-community/: Init files that register implementations
- enterprise/: Bridge imports (community_imports.go)
- vendor/: All dependencies for offline builds

Build (online):
  go build ./cmd/mattermost

Build (offline/air-gapped):
  go build -mod=vendor ./cmd/mattermost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 23:59:07 +09:00

263 lines
8.2 KiB
Go

package grammar
import (
"fmt"
"github.com/splitio/go-split-commons/v7/engine/grammar/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
}
// 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()))
return false
}
asString, ok := matchingKey.(string)
if !ok {
e.logger.Error("EqualToSemverMatcher: Error type-asserting string")
return false
}
semver, err := datatypes.BuildSemver(asString)
if err != nil {
e.logger.Error("EqualToSemverMatcher: Error parsing semver")
return false
}
result := semver.Version() == e.semver.Version()
e.logger.Debug(fmt.Sprintf("%s == %s | Result: %t", semver.Version(), e.semver.Version(), result))
return result
}
// NewEqualToSemverMatcher returns a pointer to a new instance of EqualToSemverMatcher
func NewEqualToSemverMatcher(cmpVal string, negate bool, attributeName *string, logger logging.LoggerInterface) *EqualToSemverMatcher {
semver, err := datatypes.BuildSemver(cmpVal)
if err != nil {
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,
}
}
// GreaterThanOrEqualToSemverMatcher struct to hold the semver to compare
type GreaterThanOrEqualToSemverMatcher struct {
Matcher
semver *datatypes.Semver
}
// Match compares the semver of the key with the semver in the feature flag
func (g *GreaterThanOrEqualToSemverMatcher) Match(key string, attributes map[string]interface{}, bucketingKey *string) bool {
if g.semver == nil {
return false
}
matchingKey, err := g.matchingKey(key, attributes)
if err != nil {
g.logger.Warning(fmt.Sprintf("GreaterThanOrEqualToSemverMatcher: %s", err.Error()))
return false
}
asString, ok := matchingKey.(string)
if !ok {
g.logger.Error("GreaterThanOrEqualToSemverMatcher: Error type-asserting string")
return false
}
semver, err := datatypes.BuildSemver(asString)
if err != nil {
g.logger.Error("GreaterThanOrEqualToSemverMatcher: Error parsing semver")
return false
}
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, logger logging.LoggerInterface) *GreaterThanOrEqualToSemverMatcher {
semver, err := datatypes.BuildSemver(compareTo)
if err != nil {
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,
}
}
// LessThanOrEqualToSemverMatcher struct to hold the semver to compare
type LessThanOrEqualToSemverMatcher struct {
Matcher
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()))
return false
}
asString, ok := matchingKey.(string)
if !ok {
l.logger.Error("LessThanOrEqualToSemverMatcher: Error type-asserting string")
return false
}
semver, err := datatypes.BuildSemver(asString)
if err != nil {
l.logger.Error("LessThanOrEqualToSemverMatcher: Error parsing semver")
return false
}
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, logger logging.LoggerInterface) *LessThanOrEqualToSemverMatcher {
semver, err := datatypes.BuildSemver(compareTo)
if err != nil {
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,
}
}
// BetweenSemverMatcher struct to hold the semver to compare
type BetweenSemverMatcher struct {
Matcher
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()))
return false
}
asString, ok := matchingKey.(string)
if !ok {
b.logger.Error("BetweenSemverMatcher: Error type-asserting string")
return false
}
semver, err := datatypes.BuildSemver(asString)
if err != nil {
b.logger.Error("BetweenSemverMatcher: Error parsing semver")
return false
}
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, logger logging.LoggerInterface) *BetweenSemverMatcher {
startSemver, err := datatypes.BuildSemver(startVal)
if err != nil {
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 {
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,
}
}
// InListSemverMatcher struct to hold the semver to compare
type InListSemverMatcher struct {
Matcher
semvers *set.ThreadUnsafeSet
}
// 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()))
return false
}
asString, ok := matchingKey.(string)
if !ok {
i.logger.Error("InListSemverMatcher: Error type-asserting string")
return false
}
semver, err := datatypes.BuildSemver(asString)
if err != nil {
i.logger.Error("InListSemverMatcher: Error parsing semver")
return false
}
return i.semvers.Has(semver.Version())
}
// NewInListSemverMatcher returns a pointer to a new instance of InListSemverMatcher
func NewInListSemverMatcher(setVersions []string, negate bool, attributeName *string, logger logging.LoggerInterface) *InListSemverMatcher {
semvers := set.NewSet()
for _, version := range setVersions {
semver, err := datatypes.BuildSemver(version)
if err == nil {
semvers.Add(semver.Version())
} else {
logger.Error(fmt.Sprintf("couldnt't build semver %s for IN_LIST_SEMVER matcher, ignoring: %s", version, err.Error()))
}
}
return &InListSemverMatcher{
Matcher: Matcher{
negate: negate,
attributeName: attributeName,
},
semvers: semvers,
}
}