splitclient-rb 1.0.2.wip → 8.11.1.pre.rc1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/CODEOWNERS +1 -0
- data/.github/pull_request_template.md +9 -0
- data/.github/workflows/ci.yml +90 -0
- data/.github/workflows/update-license-year.yml +45 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +76 -0
- data/.simplecov +1 -0
- data/CHANGES.txt +361 -2
- data/CONTRIBUTORS-GUIDE.md +49 -0
- data/Gemfile +2 -0
- data/LICENSE +3 -36
- data/NOTICE.txt +5 -0
- data/README.md +59 -127
- data/Rakefile +27 -3
- data/ext/murmurhash/MurmurHash3.java +302 -0
- data/gemfiles/faraday_after_0.13.gemfile +7 -0
- data/gemfiles/faraday_before_0.13.gemfile +8 -0
- data/lib/murmurhash/base.rb +58 -0
- data/lib/murmurhash/murmurhash.jar +0 -0
- data/lib/murmurhash/murmurhash_mri.rb +3 -0
- data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +130 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapter.rb +12 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +137 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +53 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +178 -0
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +83 -0
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +70 -0
- data/lib/splitclient-rb/cache/filter/bloom_filter.rb +67 -0
- data/lib/splitclient-rb/cache/filter/filter_adapter.rb +32 -0
- data/lib/splitclient-rb/cache/filter/flag_set_filter.rb +40 -0
- data/lib/splitclient-rb/cache/hashers/impression_hasher.rb +34 -0
- data/lib/splitclient-rb/cache/observers/impression_observer.rb +22 -0
- data/lib/splitclient-rb/cache/observers/noop_impression_observer.rb +10 -0
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +45 -0
- data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +35 -0
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +61 -0
- data/lib/splitclient-rb/cache/repositories/flag_sets/memory_repository.rb +40 -0
- data/lib/splitclient-rb/cache/repositories/flag_sets/redis_repository.rb +49 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +56 -0
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +57 -0
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +23 -0
- data/lib/splitclient-rb/cache/repositories/repository.rb +24 -0
- data/lib/splitclient-rb/cache/repositories/rule_based_segments_repository.rb +136 -0
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +124 -0
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +296 -0
- data/lib/splitclient-rb/cache/routers/impression_router.rb +60 -0
- data/lib/splitclient-rb/cache/senders/events_sender.rb +42 -0
- data/lib/splitclient-rb/cache/senders/impressions_adapter/memory_sender.rb +71 -0
- data/lib/splitclient-rb/cache/senders/impressions_adapter/redis_sender.rb +69 -0
- data/lib/splitclient-rb/cache/senders/impressions_count_sender.rb +43 -0
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +95 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +52 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender_adapter.rb +21 -0
- data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +47 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +95 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +110 -0
- data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
- data/lib/splitclient-rb/clients/split_client.rb +530 -0
- data/lib/splitclient-rb/constants.rb +16 -0
- data/lib/splitclient-rb/engine/api/client.rb +87 -0
- data/lib/splitclient-rb/engine/api/events.rb +57 -0
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +58 -0
- data/lib/splitclient-rb/engine/api/impressions.rb +79 -0
- data/lib/splitclient-rb/engine/api/segments.rb +78 -0
- data/lib/splitclient-rb/engine/api/splits.rb +139 -0
- data/lib/splitclient-rb/engine/api/telemetry_api.rb +47 -0
- data/lib/splitclient-rb/engine/auth_api_client.rb +100 -0
- data/lib/splitclient-rb/engine/back_off.rb +26 -0
- data/lib/splitclient-rb/engine/common/impressions_counter.rb +45 -0
- data/lib/splitclient-rb/engine/common/impressions_manager.rb +165 -0
- data/lib/splitclient-rb/engine/common/noop_impressions_counter.rb +27 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/evaluator/splitter.rb +35 -22
- data/lib/splitclient-rb/engine/events/events_delivery.rb +20 -0
- data/lib/splitclient-rb/engine/events/events_manager.rb +194 -0
- data/lib/splitclient-rb/engine/events/events_manager_config.rb +96 -0
- data/lib/splitclient-rb/engine/events/events_task.rb +50 -0
- data/lib/splitclient-rb/engine/events/noop_events_queue.rb +13 -0
- data/lib/splitclient-rb/engine/fallback_treatment_calculator.rb +48 -0
- data/lib/splitclient-rb/engine/impressions/noop_unique_keys_tracker.rb +17 -0
- data/lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb +144 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/all_keys_matcher.rb +10 -21
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +47 -0
- data/lib/splitclient-rb/engine/matchers/between_semver_matcher.rb +33 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/combiners.rb +4 -6
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +80 -0
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +16 -0
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +42 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +37 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +44 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +16 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/in_list_semver_matcher.rb +36 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +43 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/matcher.rb +52 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +29 -0
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +47 -0
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +22 -0
- data/lib/splitclient-rb/engine/matchers/prerequisites_matcher.rb +31 -0
- data/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +78 -0
- data/lib/splitclient-rb/engine/matchers/semver.rb +201 -0
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +27 -0
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +40 -0
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +66 -0
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +66 -0
- data/lib/splitclient-rb/engine/models/evaluation_options.rb +9 -0
- data/lib/splitclient-rb/engine/models/event_active_subscriptions.rb +14 -0
- data/lib/splitclient-rb/engine/models/events_metadata.rb +10 -0
- data/lib/splitclient-rb/engine/models/fallback_treatment.rb +11 -0
- data/lib/splitclient-rb/engine/models/fallback_treatments_configuration.rb +36 -0
- data/lib/splitclient-rb/engine/models/label.rb +10 -0
- data/lib/splitclient-rb/engine/models/sdk_event.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_event_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event.rb +8 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +16 -0
- data/lib/splitclient-rb/engine/models/segment_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/split.rb +17 -0
- data/lib/splitclient-rb/engine/models/split_http_response.rb +19 -0
- data/lib/splitclient-rb/engine/models/treatment.rb +3 -0
- data/lib/splitclient-rb/engine/models/valid_sdk_event.rb +14 -0
- data/lib/splitclient-rb/engine/parser/condition.rb +271 -0
- data/lib/splitclient-rb/engine/parser/evaluator.rb +112 -0
- data/lib/{splitclient-engine → splitclient-rb/engine}/parser/partition.rb +2 -4
- data/lib/splitclient-rb/engine/push_manager.rb +66 -0
- data/lib/splitclient-rb/engine/status_manager.rb +39 -0
- data/lib/splitclient-rb/engine/sync_manager.rb +183 -0
- data/lib/splitclient-rb/engine/synchronizer.rb +231 -0
- data/lib/splitclient-rb/exceptions.rb +26 -0
- data/lib/splitclient-rb/helpers/decryption_helper.rb +25 -0
- data/lib/splitclient-rb/helpers/evaluator_helper.rb +37 -0
- data/lib/splitclient-rb/helpers/repository_helper.rb +61 -0
- data/lib/splitclient-rb/helpers/thread_helper.rb +24 -0
- data/lib/splitclient-rb/helpers/util.rb +26 -0
- data/lib/splitclient-rb/managers/split_manager.rb +121 -0
- data/lib/splitclient-rb/spec.rb +9 -0
- data/lib/splitclient-rb/split_config.rb +591 -47
- data/lib/splitclient-rb/split_factory.rb +284 -0
- data/lib/splitclient-rb/split_factory_builder.rb +7 -0
- data/lib/splitclient-rb/split_factory_registry.rb +63 -0
- data/lib/splitclient-rb/split_logger.rb +23 -0
- data/lib/splitclient-rb/sse/event_source/client.rb +264 -0
- data/lib/splitclient-rb/sse/event_source/event_parser.rb +65 -0
- data/lib/splitclient-rb/sse/event_source/event_types.rb +15 -0
- data/lib/splitclient-rb/sse/event_source/stream_data.rb +22 -0
- data/lib/splitclient-rb/sse/notification_manager_keeper.rb +84 -0
- data/lib/splitclient-rb/sse/notification_processor.rb +48 -0
- data/lib/splitclient-rb/sse/sse_handler.rb +44 -0
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +62 -0
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +153 -0
- data/lib/splitclient-rb/telemetry/domain/constants.rb +48 -0
- data/lib/splitclient-rb/telemetry/domain/structs.rb +35 -0
- data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
- data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +119 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +87 -0
- data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +213 -0
- data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
- data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
- data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +27 -0
- data/lib/splitclient-rb/telemetry/runtime_consumer.rb +25 -0
- data/lib/splitclient-rb/telemetry/runtime_producer.rb +25 -0
- data/lib/splitclient-rb/telemetry/storages/memory.rb +159 -0
- data/lib/splitclient-rb/telemetry/sync_task.rb +36 -0
- data/lib/splitclient-rb/telemetry/synchronizer.rb +33 -0
- data/lib/splitclient-rb/utilitites.rb +49 -0
- data/lib/splitclient-rb/validators.rb +361 -0
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +177 -25
- data/sonar-project.properties +6 -0
- data/splitclient-rb.gemspec +53 -26
- data/tasks/benchmark_get_treatment.rake +31 -17
- data/tasks/irb.rake +6 -0
- metadata +411 -86
- data/NEWS +0 -9
- data/lib/splitclient-cache/local_store.rb +0 -45
- data/lib/splitclient-engine/impressions/impressions.rb +0 -79
- data/lib/splitclient-engine/matchers/between_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/combining_matcher.rb +0 -94
- data/lib/splitclient-engine/matchers/equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/greater_than_or_equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/less_than_or_equal_to_matcher.rb +0 -48
- data/lib/splitclient-engine/matchers/negation_matcher.rb +0 -54
- data/lib/splitclient-engine/matchers/user_defined_segment_matcher.rb +0 -61
- data/lib/splitclient-engine/matchers/whitelist_matcher.rb +0 -64
- data/lib/splitclient-engine/metrics/binary_search_latency_tracker.rb +0 -122
- data/lib/splitclient-engine/metrics/metrics.rb +0 -158
- data/lib/splitclient-engine/parser/condition.rb +0 -143
- data/lib/splitclient-engine/parser/segment.rb +0 -84
- data/lib/splitclient-engine/parser/segment_parser.rb +0 -46
- data/lib/splitclient-engine/parser/split.rb +0 -68
- data/lib/splitclient-engine/parser/split_adapter.rb +0 -433
- data/lib/splitclient-engine/parser/split_parser.rb +0 -139
- data/lib/splitclient-engine/partitions/treatments.rb +0 -40
- data/lib/splitclient-rb/split_client.rb +0 -156
- data/lib/splitclient-rb_utilitites.rb +0 -26
- data/tasks/console.rake +0 -4
- data/tasks/rspec.rake +0 -3
|
@@ -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,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class EqualToSetMatcher < SetMatcher
|
|
5
|
+
MATCHER_TYPE = 'EQUAL_TO_SET'
|
|
6
|
+
|
|
7
|
+
attr_reader :attribute
|
|
8
|
+
|
|
9
|
+
def match?(args)
|
|
10
|
+
set = local_set(args[:attributes], @attribute)
|
|
11
|
+
matches = set == @remote_set
|
|
12
|
+
@logger.log_if_debug("[EqualsToSetMatcher] #{set} equals to #{@remote_set} -> #{matches}")
|
|
13
|
+
matches
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class GreaterThanOrEqualToMatcher < Matcher
|
|
5
|
+
MATCHER_TYPE = 'GREATER_THAN_OR_EQUAL_TO'
|
|
6
|
+
|
|
7
|
+
attr_reader :attribute
|
|
8
|
+
|
|
9
|
+
def initialize(attribute_hash, logger, validator)
|
|
10
|
+
super(logger)
|
|
11
|
+
@validator = validator
|
|
12
|
+
@attribute = attribute_hash[:attribute]
|
|
13
|
+
@data_type = attribute_hash[:data_type]
|
|
14
|
+
@value = formatted_value(attribute_hash[:value], true)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?(args)
|
|
18
|
+
@logger.log_if_debug('[GreaterThanOrEqualToMatcher] evaluating value and attributes.')
|
|
19
|
+
|
|
20
|
+
return false unless @validator.valid_matcher_arguments(args)
|
|
21
|
+
|
|
22
|
+
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
|
23
|
+
|
|
24
|
+
matches = value.is_a?(Integer) ? (value >= @value) : false
|
|
25
|
+
@logger.log_if_debug("[GreaterThanOrEqualToMatcher] #{value} greater than or equal to #{@value} -> #{matches}")
|
|
26
|
+
matches
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def formatted_value(value, sdk_data = false)
|
|
32
|
+
case @data_type
|
|
33
|
+
when 'NUMBER'
|
|
34
|
+
value
|
|
35
|
+
when 'DATETIME'
|
|
36
|
+
value /= 1000 if sdk_data # sdk returns already miliseconds, turning to seconds to do a correct zero_hour
|
|
37
|
+
SplitIoClient::Utilities.to_milis_zero_out_from_seconds(value)
|
|
38
|
+
else
|
|
39
|
+
@logger.error('Invalid data type')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
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,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class LessThanOrEqualToMatcher < Matcher
|
|
5
|
+
MATCHER_TYPE = 'LESS_THAN_OR_EQUAL_TO'
|
|
6
|
+
|
|
7
|
+
attr_reader :attribute
|
|
8
|
+
|
|
9
|
+
def initialize(attribute_hash, logger, validator)
|
|
10
|
+
super(logger)
|
|
11
|
+
@validator = validator
|
|
12
|
+
@attribute = attribute_hash[:attribute]
|
|
13
|
+
@data_type = attribute_hash[:data_type]
|
|
14
|
+
@value = formatted_value(attribute_hash[:value], true)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?(args)
|
|
18
|
+
@logger.log_if_debug('[LessThanOrEqualToMatcher] evaluating value and attributes.')
|
|
19
|
+
|
|
20
|
+
return false unless @validator.valid_matcher_arguments(args)
|
|
21
|
+
|
|
22
|
+
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
|
23
|
+
|
|
24
|
+
matches = value.is_a?(Integer) ? (value <= @value) : false
|
|
25
|
+
@logger.log_if_debug("[LessThanOrEqualToMatcher] #{value} less than or equal to #{@value} -> #{matches}")
|
|
26
|
+
matches
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def formatted_value(value, sdk_data = false)
|
|
32
|
+
case @data_type
|
|
33
|
+
when 'NUMBER'
|
|
34
|
+
value
|
|
35
|
+
when 'DATETIME'
|
|
36
|
+
value /= 1000 if sdk_data # sdk returns already miliseconds, turning to seconds to do a correct zero_hour
|
|
37
|
+
SplitIoClient::Utilities.to_milis_zero_out_from_seconds(value)
|
|
38
|
+
else
|
|
39
|
+
@logger.error('Invalid data type')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
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
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
#
|
|
5
|
+
# class to implement the all keys matcher
|
|
6
|
+
#
|
|
7
|
+
class Matcher
|
|
8
|
+
def initialize(logger)
|
|
9
|
+
@logger = logger
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# evaluates if the given object equals the matcher
|
|
14
|
+
#
|
|
15
|
+
# @param obj [object] object to be evaluated
|
|
16
|
+
#
|
|
17
|
+
# @return [boolean] true if obj equals the matcher
|
|
18
|
+
def equals?(obj)
|
|
19
|
+
if obj.nil?
|
|
20
|
+
false
|
|
21
|
+
elsif !obj.instance_of?(self.class)
|
|
22
|
+
false
|
|
23
|
+
elsif equal?(obj)
|
|
24
|
+
true
|
|
25
|
+
else
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def string_type?
|
|
31
|
+
false
|
|
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
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class MatchesStringMatcher
|
|
5
|
+
MATCHER_TYPE = 'MATCHES_STRING'
|
|
6
|
+
|
|
7
|
+
attr_reader :attribute
|
|
8
|
+
|
|
9
|
+
def initialize(attribute, regexp_string, logger)
|
|
10
|
+
@attribute = attribute
|
|
11
|
+
@regexp_string = @regexp_string.is_a?(Regexp) ? regexp_string : Regexp.new(regexp_string)
|
|
12
|
+
@logger = logger
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def match?(args)
|
|
16
|
+
value = args[:value] || args[:attributes].fetch(@attribute) do |a|
|
|
17
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
matches = !(value =~ @regexp_string).nil?
|
|
21
|
+
@logger.log_if_debug("[MatchesStringMatcher] #{value} matches #{@regexp_string} -> #{matches}")
|
|
22
|
+
matches
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def string_type?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
#
|
|
5
|
+
# class to implement the negation of a matcher
|
|
6
|
+
#
|
|
7
|
+
class NegationMatcher < Matcher
|
|
8
|
+
MATCHER_TYPE = 'NEGATION_MATCHER'
|
|
9
|
+
|
|
10
|
+
def initialize(logger, matcher = nil)
|
|
11
|
+
super(logger)
|
|
12
|
+
@matcher = matcher
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# evaluates if the key matches the negation of the matcher
|
|
17
|
+
#
|
|
18
|
+
# @param key [string] key value to be matched
|
|
19
|
+
#
|
|
20
|
+
# @return [boolean] evaluation of the negation matcher
|
|
21
|
+
def match?(args)
|
|
22
|
+
matches = !@matcher.match?(args)
|
|
23
|
+
@logger.log_if_debug("[NegationMatcherMatcher] Matcher #{@matcher} Arguments #{args} -> #{matches}")
|
|
24
|
+
matches
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def respond_to?(method)
|
|
28
|
+
@matcher.respond_to? method
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def attribute
|
|
32
|
+
@matcher.attribute
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def string_type?
|
|
36
|
+
@matcher.string_type?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# function to print string value for this matcher
|
|
41
|
+
#
|
|
42
|
+
# @return [string] string value of this matcher
|
|
43
|
+
def to_s
|
|
44
|
+
"not #{@matcher}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class PartOfSetMatcher < SetMatcher
|
|
5
|
+
MATCHER_TYPE = 'PART_OF_SET'
|
|
6
|
+
|
|
7
|
+
attr_reader :attribute
|
|
8
|
+
|
|
9
|
+
def match?(args)
|
|
10
|
+
@local_set = local_set(args[:attributes], @attribute)
|
|
11
|
+
|
|
12
|
+
if @local_set.empty?
|
|
13
|
+
@logger.log_if_debug('[PartOfSetMatcher] Local Set is empty.')
|
|
14
|
+
return false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
matches = @local_set.subset? @remote_set
|
|
18
|
+
@logger.log_if_debug("[PartOfSetMatcher] Local Set #{@local_set} is a subset of #{@remote_set} -> #{matches}")
|
|
19
|
+
matches
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class PrerequisitesMatcher
|
|
5
|
+
def initialize(prerequisites, logger)
|
|
6
|
+
@prerequisites = prerequisites
|
|
7
|
+
@logger = logger
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def match?(args)
|
|
11
|
+
keys = { matching_key: args[:matching_key], bucketing_key: args[:bucketing_key] }
|
|
12
|
+
|
|
13
|
+
match = true
|
|
14
|
+
@prerequisites.each do |prerequisite|
|
|
15
|
+
evaluate = args[:evaluator].evaluate_feature_flag(keys, prerequisite[:n], args[:attributes])
|
|
16
|
+
next if prerequisite[:ts].include?(evaluate[:treatment])
|
|
17
|
+
|
|
18
|
+
@logger.log_if_debug("[PrerequisitesMatcher] feature flag #{prerequisite[:n]} evaluated to #{evaluate[:treatment]} \
|
|
19
|
+
that does not exist in prerequisited treatments.")
|
|
20
|
+
match = false
|
|
21
|
+
break
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
match
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def string_type?
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
#
|
|
5
|
+
# class to implement the user defined matcher
|
|
6
|
+
#
|
|
7
|
+
class RuleBasedSegmentMatcher < Matcher
|
|
8
|
+
MATCHER_TYPE = 'IN_RULE_BASED_SEGMENT'
|
|
9
|
+
|
|
10
|
+
def initialize(segments_repository, rule_based_segments_repository, segment_name, config)
|
|
11
|
+
super(config.logger)
|
|
12
|
+
@rule_based_segments_repository = rule_based_segments_repository
|
|
13
|
+
@segments_repository = segments_repository
|
|
14
|
+
@segment_name = segment_name
|
|
15
|
+
@config = config
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# evaluates if the key matches the matcher
|
|
20
|
+
#
|
|
21
|
+
# @param key [string] key value to be matched
|
|
22
|
+
#
|
|
23
|
+
# @return [boolean] evaluation of the key against the segment
|
|
24
|
+
def match?(args)
|
|
25
|
+
rule_based_segment = @rule_based_segments_repository.get_rule_based_segment(@segment_name)
|
|
26
|
+
return false if rule_based_segment.nil?
|
|
27
|
+
|
|
28
|
+
key = update_key(args)
|
|
29
|
+
return false if rule_based_segment[:excluded][:keys].include?(key)
|
|
30
|
+
|
|
31
|
+
return false unless check_excluded_segments(rule_based_segment, key, args)
|
|
32
|
+
|
|
33
|
+
matched = false
|
|
34
|
+
rule_based_segment[:conditions].each do |c|
|
|
35
|
+
condition = SplitIoClient::Condition.new(c, @config)
|
|
36
|
+
next if condition.empty?
|
|
37
|
+
|
|
38
|
+
matched = Helpers::EvaluatorHelper.matcher_type(condition, @segments_repository, @rule_based_segments_repository).match?(args)
|
|
39
|
+
|
|
40
|
+
break if matched
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@config.logger.debug("[InRuleSegmentMatcher] #{@segment_name} is in rule based segment -> #{matched}") if @config.debug_enabled
|
|
44
|
+
matched
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def check_excluded_segments(rule_based_segment, key, args)
|
|
50
|
+
rule_based_segment[:excluded][:segments].each do |segment|
|
|
51
|
+
if segment[:type] == SplitIoClient::Engine::Models::SegmentType::STANDARD &&
|
|
52
|
+
@segments_repository.in_segment?(segment[:name], key)
|
|
53
|
+
return false
|
|
54
|
+
end
|
|
55
|
+
return false if segment[:type] == SplitIoClient::Engine::Models::SegmentType::RULE_BASED_SEGMENT && match_rbs(
|
|
56
|
+
@rule_based_segments_repository.get_rule_based_segment(segment[:name]), args
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def update_key(args)
|
|
63
|
+
if args[:value].nil? || args[:value].empty?
|
|
64
|
+
args[:matching_key]
|
|
65
|
+
else
|
|
66
|
+
args[:value]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def match_rbs(rule_based_segment, args)
|
|
71
|
+
rbs_matcher = RuleBasedSegmentMatcher.new(@segments_repository, @rule_based_segments_repository,
|
|
72
|
+
rule_based_segment[:name], @config)
|
|
73
|
+
rbs_matcher.match?(matching_key: args[:matching_key],
|
|
74
|
+
bucketing_key: args[:value],
|
|
75
|
+
attributes: args[:attributes])
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
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
|