splitclient-rb 8.3.2.pre.rc2 → 8.4.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e0fe5d6b573015bd83ed8d8c9d2a50d61f312d436b36b166420e20fa4ea6541
4
- data.tar.gz: ab4003f1bb7ec13437da9804326075ae8d71ee0a613e6037c737076a3b8d45c1
3
+ metadata.gz: aa02c4845c625ae96b13d6a3733897c12d0eac182cac61b20b72b90d01730967
4
+ data.tar.gz: 202a40030091e69f3286c4c23e9c5b4d8d249284314049f1738911e66c618e96
5
5
  SHA512:
6
- metadata.gz: f8ccb4279ea5eef142f7d78633c98d7cd27b6d16823b4bfe821659766d34a09ed892e80f0e9037fe99b3305bb69a288b8ed83799e5811e6005d7a1d154b8db96
7
- data.tar.gz: f724d7499c992d3b21f106cac2f875abe746e1fe0e3d4a95753d1895069a13d4b521dd611d89c7b8dfc94e14ff6e3168192eb68385ede4b28ccb4228b475a085
6
+ metadata.gz: ff7e9b7d893d0011917677e4e71fcc549c5d034c00ac0d497a4d555d94bde90ee3f14127f5b20e8da41c26d921372993d832c458bdd8c331f9b8264a7a0a5a09
7
+ data.tar.gz: 85a8019fc7a76dc52bf0557bfca7de03e254f95a03fc9d7a0edea0c64641cff884954212b00499221591d5c69f29edc6c2518ef3d153a521653c2813c79270fb
data/CHANGES.txt CHANGED
@@ -1,5 +1,9 @@
1
1
  CHANGES
2
2
 
3
+ 8.4.0 (May 3, 2024)
4
+ - Fixed issue preventing Impressopns and Events posting if client.destroy is called before the post threads started
5
+ - Added support for targeting rules based on semantic versions (https://semver.org/).
6
+
3
7
  8.3.1 (Mar 22, 2024)
4
8
  - Fixed ruby process hanging due to failed thread.join command, when calling destroy and a http request still active.
5
9
  - Fixed streaming notification parser. Issue ref: https://github.com/splitio/ruby-client/issues/511
@@ -29,8 +29,9 @@ module SplitIoClient
29
29
  size: 100
30
30
  }
31
31
  ],
32
- label: "unsupported matcher type"
33
- }]
32
+ label: "targeting rule type unsupported by sdk"
33
+ }]
34
+
34
35
  def initialize(config, flag_sets_repository, flag_set_filter)
35
36
  super(config)
36
37
  @tt_cache = {}
@@ -10,6 +10,7 @@ module SplitIoClient
10
10
  end
11
11
 
12
12
  def get_api(url, api_key, params = {}, cache_control_headers = false)
13
+ api_client.options.params_encoder.sort_params = false
13
14
  api_client.get(url, params) do |req|
14
15
  req.headers = common_headers(api_key).merge('Accept-Encoding' => 'gzip')
15
16
  req.headers = req.headers.merge('Cache-Control' => 'no-cache') if cache_control_headers
@@ -29,7 +30,7 @@ module SplitIoClient
29
30
  req.headers = common_headers(api_key)
30
31
  .merge('Content-Type' => 'application/json')
31
32
  .merge(headers)
32
-
33
+
33
34
  machine_ip = @config.machine_ip
34
35
  machine_name = @config.machine_name
35
36
 
@@ -55,6 +56,7 @@ module SplitIoClient
55
56
  @api_client ||= Faraday.new do |builder|
56
57
  builder.use SplitIoClient::FaradayMiddleware::Gzip
57
58
  builder.adapter :net_http_persistent
59
+ builder.options.params_encoder = Faraday::FlatParamsEncoder
58
60
  end
59
61
  end
60
62
 
@@ -4,6 +4,7 @@ module SplitIoClient
4
4
  module Api
5
5
  # Retrieves split definitions from the Split Backend
6
6
  class Splits < Client
7
+
7
8
  def initialize(api_key, config, telemetry_runtime_producer)
8
9
  super(config)
9
10
  @api_key = api_key
@@ -11,12 +12,12 @@ module SplitIoClient
11
12
  @flag_sets_filter = @config.flag_sets_filter
12
13
  end
13
14
 
14
- def since(since, fetch_options = { cache_control_headers: false, till: nil, sets: nil })
15
+ def since(since, fetch_options = { cache_control_headers: false, till: nil, sets: nil})
15
16
  start = Time.now
16
17
 
17
- params = { since: since }
18
- params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
18
+ params = { s: SplitIoClient::Spec::FeatureFlags::SPEC_VERSION, since: since }
19
19
  params[:sets] = @flag_sets_filter.join(",") unless @flag_sets_filter.empty?
20
+ params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
20
21
  @config.logger.debug("Fetching from splitChanges with #{params}: ")
21
22
  response = get_api("#{@config.base_uri}/splitChanges", @api_key, params, fetch_options[:cache_control_headers])
22
23
  if response.status == 414
@@ -14,7 +14,7 @@ module SplitIoClient
14
14
 
15
15
  def authenticate(api_key)
16
16
  start = Time.now
17
- response = @api_client.get_api(@config.auth_service_url, api_key)
17
+ response = @api_client.get_api("#{@config.auth_service_url}?s=#{SplitIoClient::Spec::FeatureFlags::SPEC_VERSION}", api_key)
18
18
 
19
19
  return process_success(response, start) if response.success?
20
20
 
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class BetweenSemverMatcher < Matcher
5
+ MATCHER_TYPE = 'BETWEEN_SEMVER'
6
+
7
+ attr_reader :attribute
8
+
9
+ def initialize(attribute, start_value, end_value, logger, validator)
10
+ super(logger)
11
+ @validator = validator
12
+ @attribute = attribute
13
+ @semver_start = SplitIoClient::Semver.build(start_value, logger)
14
+ @semver_end = SplitIoClient::Semver.build(end_value, logger)
15
+ @logger = logger
16
+ end
17
+
18
+ def match?(args)
19
+ return false unless verify_semver_arg?(args, 'BetweenSemverMatcher')
20
+
21
+ value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
22
+ if value_to_match.nil? || @semver_start.nil? || @semver_end.nil?
23
+ @logger.error('betweenStringMatcherData is required for BETWEEN_SEMVER matcher type')
24
+ return false
25
+
26
+ end
27
+ matches = ([0, -1].include?(@semver_start.compare(value_to_match)) &&
28
+ [0, 1].include?(@semver_end.compare(value_to_match)))
29
+ @logger.debug("[BetweenMatcher] #{value_to_match} matches -> #{matches}")
30
+ matches
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class EqualToSemverMatcher < Matcher
5
+ MATCHER_TYPE = 'EQUAL_TO_SEMVER'
6
+
7
+ attr_reader :attribute
8
+
9
+ def initialize(attribute, string_value, logger, validator)
10
+ super(logger)
11
+ @validator = validator
12
+ @attribute = attribute
13
+ @semver = SplitIoClient::Semver.build(string_value, logger)
14
+ @logger = logger
15
+ end
16
+
17
+ def match?(args)
18
+ return false unless verify_semver_arg?(args, 'EqualsToSemverMatcher')
19
+
20
+ value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21
+ return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22
+
23
+ matches = (@semver.version == value_to_match.version)
24
+ @logger.debug("[EqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25
+ matches
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class GreaterThanOrEqualToSemverMatcher < Matcher
5
+ MATCHER_TYPE = 'GREATER_THAN_OR_EQUAL_TO_SEMVER'
6
+
7
+ attr_reader :attribute
8
+
9
+ def initialize(attribute, string_value, logger, validator)
10
+ super(logger)
11
+ @validator = validator
12
+ @attribute = attribute
13
+ @semver = SplitIoClient::Semver.build(string_value, logger)
14
+ @logger = logger
15
+ end
16
+
17
+ def match?(args)
18
+ return false unless verify_semver_arg?(args, 'GreaterThanOrEqualsToSemverMatcher')
19
+
20
+ value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21
+ return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22
+
23
+ matches = [0, 1].include?(value_to_match.compare(@semver))
24
+ @logger.debug("[GreaterThanOrEqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25
+ matches
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class InListSemverMatcher < Matcher
5
+ MATCHER_TYPE = 'IN_LIST_SEMVER'
6
+
7
+ attr_reader :attribute
8
+
9
+ def initialize(attribute, list_value, logger, validator)
10
+ super(logger)
11
+ @validator = validator
12
+ @attribute = attribute
13
+ @semver_list = []
14
+
15
+ list_value.map do |item|
16
+ version = SplitIoClient::Semver.build(item, logger)
17
+ @semver_list << version unless version.nil?
18
+ end
19
+ @logger = logger
20
+ end
21
+
22
+ def match?(args)
23
+ return false if @semver_list.empty? || !verify_semver_arg?(args, 'InListSemverMatcher')
24
+
25
+ value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
26
+ if value_to_match.nil?
27
+ @logger.error('whitelistMatcherData is required for IN_LIST_SEMVER matcher type')
28
+ return false
29
+
30
+ end
31
+ matches = (@semver_list.map { |item| item.version == value_to_match.version }).any? { |item| item == true }
32
+ @logger.debug("[InListSemverMatcher] #{value_to_match} matches -> #{matches}")
33
+ matches
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class LessThanOrEqualToSemverMatcher < Matcher
5
+ MATCHER_TYPE = 'LESS_THAN_OR_EQUAL_TO_SEMVER'
6
+
7
+ attr_reader :attribute
8
+
9
+ def initialize(attribute, string_value, logger, validator)
10
+ super(logger)
11
+ @validator = validator
12
+ @attribute = attribute
13
+ @semver = SplitIoClient::Semver.build(string_value, logger)
14
+ @logger = logger
15
+ end
16
+
17
+ def match?(args)
18
+ return false unless verify_semver_arg?(args, 'LessThanOrEqualsToSemverMatcher')
19
+
20
+ value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21
+ return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22
+
23
+ matches = [0, -1].include?(value_to_match.compare(@semver))
24
+ @logger.debug("[LessThanOrEqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25
+ matches
26
+ end
27
+ end
28
+ end
@@ -30,5 +30,23 @@ module SplitIoClient
30
30
  def string_type?
31
31
  false
32
32
  end
33
+
34
+ private
35
+
36
+ def verify_semver_arg?(args, matcher_name)
37
+ @logger.debug("[#{matcher_name}] evaluating value and attributes.")
38
+ return false unless @validator.valid_matcher_arguments(args)
39
+
40
+ true
41
+ end
42
+
43
+ def check_semver_value_to_match(value_to_match, matcher_spec_name)
44
+ if value_to_match.nil? || @semver.nil?
45
+ @logger.error("stringMatcherData is required for #{matcher_spec_name} matcher type")
46
+ return false
47
+
48
+ end
49
+ true
50
+ end
33
51
  end
34
52
  end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class Semver
5
+ METADATA_DELIMITER = '+'
6
+ PRE_RELEASE_DELIMITER = '-'
7
+ VALUE_DELIMITER = '.'
8
+
9
+ attr_reader :major, :minor, :patch, :pre_release, :is_stable, :version
10
+
11
+ def initialize(version)
12
+ @major = 0
13
+ @minor = 0
14
+ @patch = 0
15
+ @pre_release = []
16
+ @is_stable = false
17
+ @version = ''
18
+ @metadata = ''
19
+ parse(version)
20
+ end
21
+
22
+ #
23
+ # Class builder
24
+ #
25
+ # @param version [String] raw version as read from splitChanges response.
26
+ #
27
+ # @return [type] Semver instance
28
+ def self.build(version, logger)
29
+ new(version)
30
+ rescue NoMethodError => e
31
+ logger.error("Failed to parse Semver data, incorrect data type: #{e}")
32
+ nil
33
+ rescue StandardError => e
34
+ logger.error("Failed to parse Semver data: #{e}")
35
+ nil
36
+ end
37
+
38
+ #
39
+ # Check if there is any metadata characters in version.
40
+ #
41
+ # @return [type] String semver without the metadata
42
+ #
43
+ def remove_metadata_if_exists(old_version)
44
+ index = old_version.index(METADATA_DELIMITER)
45
+ return old_version if index.nil?
46
+
47
+ @metadata = old_version[index + 1, old_version.length]
48
+ old_version[0, index]
49
+ end
50
+
51
+ # Compare the current Semver object to a given Semver object, return:
52
+ # 0: if self == passed
53
+ # 1: if self > passed
54
+ # -1: if self < passed
55
+ #
56
+ # @param to_compare [trype] splitio.models.grammar.matchers.semver.Semver object
57
+ #
58
+ # @returns [Integer] based on comparison
59
+ def compare(to_compare)
60
+ return 0 if @version == to_compare.version
61
+
62
+ # Compare major, minor, and patch versions numerically
63
+ result = compare_attributes(to_compare)
64
+ return result if result != 0
65
+
66
+ # Compare pre-release versions lexically
67
+ compare_pre_release(to_compare)
68
+ end
69
+
70
+ private
71
+
72
+ def integer?(value)
73
+ !!value.match(/^(\d)+$/)
74
+ end
75
+
76
+ #
77
+ # Parse the string in version to update the other internal variables
78
+ #
79
+ def parse(old_version)
80
+ without_metadata = remove_metadata_if_exists(old_version)
81
+
82
+ index = without_metadata.index(PRE_RELEASE_DELIMITER)
83
+ if index.nil?
84
+ @is_stable = true
85
+ else
86
+ pre_release_data = without_metadata[index + 1..-1]
87
+ without_metadata = without_metadata[0, index]
88
+ @pre_release = pre_release_data.split(VALUE_DELIMITER)
89
+ end
90
+ assign_major_minor_and_patch(without_metadata)
91
+ end
92
+
93
+ #
94
+ # Set the major, minor and patch internal variables based on string passed.
95
+ #
96
+ # @param version [String] raw version containing major.minor.patch numbers.
97
+ def assign_major_minor_and_patch(version)
98
+ parts = version.split(VALUE_DELIMITER)
99
+ if parts.length != 3 ||
100
+ !(integer?(parts[0]) &&
101
+ integer?(parts[1]) &&
102
+ integer?(parts[2]))
103
+ raise "Unable to convert to Semver, incorrect format: #{version}"
104
+ end
105
+
106
+ @major = parts[0].to_i
107
+ @minor = parts[1].to_i
108
+ @patch = parts[2].to_i
109
+ @version = "#{@major}#{VALUE_DELIMITER}#{@minor}#{VALUE_DELIMITER}#{@patch}"
110
+ @version += parse_pre_release
111
+ @version += "#{METADATA_DELIMITER}#{@metadata}" unless @metadata.empty?
112
+ end
113
+
114
+ def parse_pre_release
115
+ return '' if @pre_release.empty?
116
+
117
+ pre_parsed = []
118
+ @pre_release.each do |pre_digit|
119
+ pre_digit = pre_digit.to_i if integer?(pre_digit)
120
+ pre_parsed << pre_digit
121
+ end
122
+ "#{PRE_RELEASE_DELIMITER}#{pre_parsed.join('.')}"
123
+ end
124
+
125
+ #
126
+ # Compare 2 variables and return int as follows:
127
+ # 0: if var1 == var2
128
+ # 1: if var1 > var2
129
+ # -1: if var1 < var2
130
+ #
131
+ # @param var1 [type] String/Integer object that accept ==, < or > operators
132
+ # @param var2 [type] String/Integer object that accept ==, < or > operators
133
+ #
134
+ # @returns [Integer] based on comparison
135
+ def compare_vars(var1, var2)
136
+ return 0 if var1 == var2
137
+
138
+ return 1 if var1 > var2
139
+
140
+ -1
141
+ end
142
+
143
+ # Compare the current Semver object's major, minor, patch and is_stable attributes to a given Semver object, return:
144
+ # 0: if self == passed
145
+ # 1: if self > passed
146
+ # -1: if self < passed
147
+ #
148
+ # @param to_compare [trype] splitio.models.grammar.matchers.semver.Semver object
149
+ #
150
+ # @returns [Integer] based on comparison
151
+ def compare_attributes(to_compare)
152
+ result = compare_vars(@major, to_compare.major)
153
+ return result if result != 0
154
+
155
+ result = compare_vars(@minor, to_compare.minor)
156
+ return result if result != 0
157
+
158
+ result = compare_vars(@patch, to_compare.patch)
159
+ return result if result != 0
160
+
161
+ return -1 if !@is_stable && to_compare.is_stable
162
+
163
+ return 1 if @is_stable && !to_compare.is_stable
164
+
165
+ 0
166
+ end
167
+
168
+ # Compare the current Semver object's pre_release attribute to a given Semver object, return:
169
+ # 0: if self == passed
170
+ # 1: if self > passed
171
+ # -1: if self < passed
172
+ #
173
+ # @param to_compare [trype] splitio.models.grammar.matchers.semver.Semver object
174
+ #
175
+ # @returns [Integer] based on comparison
176
+ def compare_pre_release(to_compare)
177
+ min_length = get_pre_min_length(to_compare)
178
+ 0.upto(min_length - 1) do |i|
179
+ next if @pre_release[i] == to_compare.pre_release[i]
180
+
181
+ if integer?(@pre_release[i]) && integer?(to_compare.pre_release[i])
182
+ return compare_vars(@pre_release[i].to_i, to_compare.pre_release[i].to_i)
183
+
184
+ end
185
+
186
+ return compare_vars(@pre_release[i], to_compare.pre_release[i])
187
+ end
188
+ # Compare lengths of pre-release versions
189
+ compare_vars(@pre_release.length, to_compare.pre_release.length)
190
+ end
191
+
192
+ # Get minimum of current Semver object's pre_release attributes length to a given Semver object
193
+ #
194
+ # @param to_compare [trype] splitio.models.grammar.matchers.semver.Semver object
195
+ #
196
+ # @returns [Integer]
197
+ def get_pre_min_length(to_compare)
198
+ [@pre_release.length, to_compare.pre_release.length].min
199
+ end
200
+ end
201
+ end
@@ -189,6 +189,47 @@ module SplitIoClient
189
189
  )
190
190
  end
191
191
 
192
+ def matcher_equal_to_semver(params)
193
+ EqualToSemverMatcher.new(
194
+ params[:matcher][:keySelector][:attribute],
195
+ params[:matcher][:stringMatcherData],
196
+ @config.split_logger, @config.split_validator
197
+ )
198
+ end
199
+
200
+ def matcher_greater_than_or_equal_to_semver(params)
201
+ GreaterThanOrEqualToSemverMatcher.new(
202
+ params[:matcher][:keySelector][:attribute],
203
+ params[:matcher][:stringMatcherData],
204
+ @config.split_logger, @config.split_validator
205
+ )
206
+ end
207
+
208
+ def matcher_less_than_or_equal_to_semver(params)
209
+ LessThanOrEqualToSemverMatcher.new(
210
+ params[:matcher][:keySelector][:attribute],
211
+ params[:matcher][:stringMatcherData],
212
+ @config.split_logger, @config.split_validator
213
+ )
214
+ end
215
+
216
+ def matcher_between_semver(params)
217
+ BetweenSemverMatcher.new(
218
+ params[:matcher][:keySelector][:attribute],
219
+ params[:matcher][:betweenStringMatcherData][:start],
220
+ params[:matcher][:betweenStringMatcherData][:end],
221
+ @config.split_logger, @config.split_validator
222
+ )
223
+ end
224
+
225
+ def matcher_in_list_semver(params)
226
+ InListSemverMatcher.new(
227
+ params[:matcher][:keySelector][:attribute],
228
+ params[:matcher][:whitelistMatcherData][:whitelist],
229
+ @config.split_logger, @config.split_validator
230
+ )
231
+ end
232
+
192
233
  #
193
234
  # @return [object] the negate value for this condition
194
235
  def negate
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Spec
5
+ class FeatureFlags
6
+ SPEC_VERSION = "1.1"
7
+ end
8
+ end
9
+ end
@@ -11,5 +11,13 @@ module SplitIoClient
11
11
  def log_if_transport(message)
12
12
  @config.logger.debug(message) if @config.transport_debug_enabled
13
13
  end
14
+
15
+ def error(message)
16
+ @config.logger.error(message)
17
+ end
18
+
19
+ def debug(message)
20
+ @config.logger.debug(message) if @config.debug_enabled
21
+ end
14
22
  end
15
23
  end
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '8.3.2.pre.rc2'
2
+ VERSION = '8.4.0.pre.rc1'
3
3
  end
@@ -90,6 +90,12 @@ require 'splitclient-rb/engine/matchers/dependency_matcher'
90
90
  require 'splitclient-rb/engine/matchers/equal_to_boolean_matcher'
91
91
  require 'splitclient-rb/engine/matchers/equal_to_matcher'
92
92
  require 'splitclient-rb/engine/matchers/matches_string_matcher'
93
+ require 'splitclient-rb/engine/matchers/semver'
94
+ require 'splitclient-rb/engine/matchers/equal_to_semver_matcher'
95
+ require 'splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher'
96
+ require 'splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher'
97
+ require 'splitclient-rb/engine/matchers/between_semver_matcher'
98
+ require 'splitclient-rb/engine/matchers/in_list_semver_matcher'
93
99
  require 'splitclient-rb/engine/evaluator/splitter'
94
100
  require 'splitclient-rb/engine/impressions/noop_unique_keys_tracker'
95
101
  require 'splitclient-rb/engine/impressions/unique_keys_tracker'
@@ -105,6 +111,8 @@ require 'splitclient-rb/engine/sync_manager'
105
111
  require 'splitclient-rb/engine/synchronizer'
106
112
  require 'splitclient-rb/utilitites'
107
113
 
114
+ require 'splitclient-rb/spec.rb'
115
+
108
116
  # SSE
109
117
  require 'splitclient-rb/sse/event_source/client'
110
118
  require 'splitclient-rb/sse/event_source/event_parser'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.3.2.pre.rc2
4
+ version: 8.4.0.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-25 00:00:00.000000000 Z
11
+ date: 2024-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -489,6 +489,7 @@ files:
489
489
  - lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb
490
490
  - lib/splitclient-rb/engine/matchers/all_keys_matcher.rb
491
491
  - lib/splitclient-rb/engine/matchers/between_matcher.rb
492
+ - lib/splitclient-rb/engine/matchers/between_semver_matcher.rb
492
493
  - lib/splitclient-rb/engine/matchers/combiners.rb
493
494
  - lib/splitclient-rb/engine/matchers/combining_matcher.rb
494
495
  - lib/splitclient-rb/engine/matchers/contains_all_matcher.rb
@@ -498,13 +499,18 @@ files:
498
499
  - lib/splitclient-rb/engine/matchers/ends_with_matcher.rb
499
500
  - lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb
500
501
  - lib/splitclient-rb/engine/matchers/equal_to_matcher.rb
502
+ - lib/splitclient-rb/engine/matchers/equal_to_semver_matcher.rb
501
503
  - lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb
502
504
  - lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb
505
+ - lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher.rb
506
+ - lib/splitclient-rb/engine/matchers/in_list_semver_matcher.rb
503
507
  - lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb
508
+ - lib/splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher.rb
504
509
  - lib/splitclient-rb/engine/matchers/matcher.rb
505
510
  - lib/splitclient-rb/engine/matchers/matches_string_matcher.rb
506
511
  - lib/splitclient-rb/engine/matchers/negation_matcher.rb
507
512
  - lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb
513
+ - lib/splitclient-rb/engine/matchers/semver.rb
508
514
  - lib/splitclient-rb/engine/matchers/set_matcher.rb
509
515
  - lib/splitclient-rb/engine/matchers/starts_with_matcher.rb
510
516
  - lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb
@@ -526,6 +532,7 @@ files:
526
532
  - lib/splitclient-rb/helpers/thread_helper.rb
527
533
  - lib/splitclient-rb/helpers/util.rb
528
534
  - lib/splitclient-rb/managers/split_manager.rb
535
+ - lib/splitclient-rb/spec.rb
529
536
  - lib/splitclient-rb/split_config.rb
530
537
  - lib/splitclient-rb/split_factory.rb
531
538
  - lib/splitclient-rb/split_factory_builder.rb