configcat 1.0.1 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f268b80ad6cfa72c12ca3a438d6fc8a896be9dcd324d5f7743274ea1b93935b8
4
- data.tar.gz: e9889a6887f63823adacfa9be12f1ede457f0f94d17a2920d6800b6c816a4f23
3
+ metadata.gz: dada53197ffe2d00bf8f4349bd643312f65d72b970e4de9bb774a490bf2f12c4
4
+ data.tar.gz: 0e656c1c42d3def92aa47013f8c22a555f0268b2dff5b8df37b79a0ac3952425
5
5
  SHA512:
6
- metadata.gz: 248a015959119f3629c42df5b6bb9d1b5105a452ea5d3d8054d0110b73fff508f2e551cf7e3ed591330f0037748adf487b7c6678a0385c47e5869613ca8b6d66
7
- data.tar.gz: 055ac0dd698e4bd3173ba64c299c9856ad8e2821bd92fd5b0a6e2f25197054ba1ff15bb0c931b6a1bd78ed6eb6ea369d2b08e637db5743154fd73a243b6f3876
6
+ metadata.gz: ace75c4e4f36cfb62447beca19786287026fa8be4409506fa54b58a693f4b996a9526acad14b9552012377a6c5e75b5fcd0073118e7cd2af403b1585eecc6e07
7
+ data.tar.gz: bd98ab5c116d6a4daf2d1f07a214e585bcc630d9f81b268febe9b0fead8f4fdc1cb86e7af4042f5d568c46e8692d8599db2f4e9b83a74fbec80312612c091c46
@@ -5,7 +5,7 @@ require 'logger'
5
5
 
6
6
  module ConfigCat
7
7
 
8
- @logger = Logger.new(STDOUT, level: Logger::INFO)
8
+ @logger = Logger.new(STDOUT, level: Logger::WARN)
9
9
  class << self
10
10
  attr_accessor :logger
11
11
  end
@@ -19,7 +19,16 @@ module ConfigCat
19
19
  return create_client_with_auto_poll(api_key)
20
20
  end
21
21
 
22
- def ConfigCat.create_client_with_auto_poll(api_key, poll_interval_seconds: 60, max_init_wait_time_seconds: 5, on_configuration_changed_callback: nil, config_cache_class: nil, base_url: nil)
22
+ def ConfigCat.create_client_with_auto_poll(api_key,
23
+ poll_interval_seconds: 60,
24
+ max_init_wait_time_seconds: 5,
25
+ on_configuration_changed_callback: nil,
26
+ config_cache_class: nil,
27
+ base_url: nil,
28
+ proxy_address:nil,
29
+ proxy_port:nil,
30
+ proxy_user:nil,
31
+ proxy_pass:nil)
23
32
  #
24
33
  # Create an instance of ConfigCatClient and setup Auto Poll mode with custom options
25
34
  #
@@ -30,6 +39,10 @@ module ConfigCat
30
39
  # :param config_cache_class: If you want to use custom caching instead of the client's default InMemoryConfigCache,
31
40
  # You can provide an implementation of ConfigCache.
32
41
  # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
42
+ # :param proxy_address: Proxy address
43
+ # :param proxy_port: Proxy port
44
+ # :param proxy_user: username for proxy authentication
45
+ # :param proxy_pass: password for proxy authentication
33
46
  #
34
47
  if api_key === nil
35
48
  raise ConfigCatClientException, "API Key is required."
@@ -46,10 +59,21 @@ module ConfigCat
46
59
  on_configuration_changed_callback: on_configuration_changed_callback,
47
60
  cache_time_to_live_seconds: 0,
48
61
  config_cache_class: config_cache_class,
49
- base_url: base_url)
62
+ base_url: base_url,
63
+ proxy_address: proxy_address,
64
+ proxy_port: proxy_port,
65
+ proxy_user: proxy_user,
66
+ proxy_pass: proxy_pass)
50
67
  end
51
68
 
52
- def ConfigCat.create_client_with_lazy_load(api_key, cache_time_to_live_seconds: 60, config_cache_class: nil, base_url: nil)
69
+ def ConfigCat.create_client_with_lazy_load(api_key,
70
+ cache_time_to_live_seconds: 60,
71
+ config_cache_class: nil,
72
+ base_url: nil,
73
+ proxy_address:nil,
74
+ proxy_port:nil,
75
+ proxy_user:nil,
76
+ proxy_pass:nil)
53
77
  #
54
78
  # Create an instance of ConfigCatClient and setup Lazy Load mode with custom options
55
79
  #
@@ -58,6 +82,10 @@ module ConfigCat
58
82
  # :param config_cache_class: If you want to use custom caching instead of the client's default InMemoryConfigCache,
59
83
  # You can provide an implementation of ConfigCache.
60
84
  # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
85
+ # :param proxy_address: Proxy address
86
+ # :param proxy_port: Proxy port
87
+ # :param proxy_user: username for proxy authentication
88
+ # :param proxy_pass: password for proxy authentication
61
89
  #
62
90
  if api_key === nil
63
91
  raise ConfigCatClientException, "API Key is required."
@@ -71,10 +99,20 @@ module ConfigCat
71
99
  on_configuration_changed_callback: nil,
72
100
  cache_time_to_live_seconds: cache_time_to_live_seconds,
73
101
  config_cache_class: config_cache_class,
74
- base_url: base_url)
102
+ base_url: base_url,
103
+ proxy_address: proxy_address,
104
+ proxy_port: proxy_port,
105
+ proxy_user: proxy_user,
106
+ proxy_pass: proxy_pass)
75
107
  end
76
108
 
77
- def ConfigCat.create_client_with_manual_poll(api_key, config_cache_class: nil, base_url: nil)
109
+ def ConfigCat.create_client_with_manual_poll(api_key,
110
+ config_cache_class: nil,
111
+ base_url: nil,
112
+ proxy_address:nil,
113
+ proxy_port:nil,
114
+ proxy_user:nil,
115
+ proxy_pass:nil)
78
116
  #
79
117
  # Create an instance of ConfigCatClient and setup Manual Poll mode with custom options
80
118
  #
@@ -82,6 +120,10 @@ module ConfigCat
82
120
  # :param config_cache_class: If you want to use custom caching instead of the client's default InMemoryConfigCache,
83
121
  # You can provide an implementation of ConfigCache.
84
122
  # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
123
+ # :param proxy_address: Proxy address
124
+ # :param proxy_port: Proxy port
125
+ # :param proxy_user: username for proxy authentication
126
+ # :param proxy_pass: password for proxy authentication
85
127
  #
86
128
  if api_key === nil
87
129
  raise ConfigCatClientException, "API Key is required."
@@ -92,7 +134,11 @@ module ConfigCat
92
134
  on_configuration_changed_callback: nil,
93
135
  cache_time_to_live_seconds: 0,
94
136
  config_cache_class: config_cache_class,
95
- base_url: base_url)
137
+ base_url: base_url,
138
+ proxy_address: proxy_address,
139
+ proxy_port: proxy_port,
140
+ proxy_user: proxy_user,
141
+ proxy_pass: proxy_pass)
96
142
  end
97
143
 
98
144
  end
@@ -47,30 +47,38 @@ module ConfigCat
47
47
  end
48
48
 
49
49
  def force_refresh()
50
- begin
51
- @_lock.acquire_read_lock()
52
- old_configuration = @_config_cache.get()
53
- ensure
54
- @_lock.release_read_lock()
55
- end
56
50
  begin
57
51
  configuration = @_config_fetcher.get_configuration_json()
52
+
58
53
  begin
59
- @_lock.acquire_write_lock()
60
- @_config_cache.set(configuration)
61
- @_initialized = true
54
+ @_lock.acquire_read_lock()
55
+ old_configuration = @_config_cache.get()
62
56
  ensure
63
- @_lock.release_write_lock()
57
+ @_lock.release_read_lock()
64
58
  end
65
- begin
66
- if !@_on_configuration_changed_callback.equal?(nil) && configuration != old_configuration
67
- @_on_configuration_changed_callback.call()
59
+
60
+ if configuration != old_configuration
61
+ begin
62
+ @_lock.acquire_write_lock()
63
+ @_config_cache.set(configuration)
64
+ @_initialized = true
65
+ ensure
66
+ @_lock.release_write_lock()
67
+ end
68
+ begin
69
+ if !@_on_configuration_changed_callback.equal?(nil)
70
+ @_on_configuration_changed_callback.()
71
+ end
72
+ rescue Exception => e
73
+ ConfigCat.logger.error("Exception in on_configuration_changed_callback: #{e.class}:'#{e}'")
68
74
  end
69
- rescue Exception => e
70
- ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
71
- ConfigCat.logger.error "stacktrace: #{e.backtrace}"
72
75
  end
73
- rescue StandardError => e
76
+
77
+ if !@_initialized && !old_configuration.equal?(nil)
78
+ @_initialized = true
79
+ end
80
+ rescue Exception => e
81
+ ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
74
82
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
75
83
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
76
84
  end
@@ -14,7 +14,11 @@ module ConfigCat
14
14
  on_configuration_changed_callback:nil,
15
15
  cache_time_to_live_seconds:60,
16
16
  config_cache_class:nil,
17
- base_url:nil)
17
+ base_url:nil,
18
+ proxy_address:nil,
19
+ proxy_port:nil,
20
+ proxy_user:nil,
21
+ proxy_pass:nil)
18
22
  if api_key === nil
19
23
  raise ConfigCatClientException, "API Key is required."
20
24
  end
@@ -27,14 +31,14 @@ module ConfigCat
27
31
  end
28
32
 
29
33
  if poll_interval_seconds > 0
30
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "p", base_url)
34
+ @_config_fetcher = CacheControlConfigFetcher.new(api_key, "p", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
31
35
  @_cache_policy = AutoPollingCachePolicy.new(@_config_fetcher, @_config_cache, poll_interval_seconds, max_init_wait_time_seconds, on_configuration_changed_callback)
32
36
  else
33
37
  if cache_time_to_live_seconds > 0
34
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "l", base_url)
38
+ @_config_fetcher = CacheControlConfigFetcher.new(api_key, "l", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
35
39
  @_cache_policy = LazyLoadingCachePolicy.new(@_config_fetcher, @_config_cache, cache_time_to_live_seconds)
36
40
  else
37
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "m", base_url)
41
+ @_config_fetcher = CacheControlConfigFetcher.new(api_key, "m", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
38
42
  @_cache_policy = ManualPollingCachePolicy.new(@_config_fetcher, @_config_cache)
39
43
  end
40
44
  end
@@ -7,10 +7,10 @@ require 'json'
7
7
  module ConfigCat
8
8
  BASE_URL = "https://cdn.configcat.com"
9
9
  BASE_PATH = "configuration-files/"
10
- BASE_EXTENSION = "/config_v2.json"
10
+ BASE_EXTENSION = "/config_v3.json"
11
11
 
12
12
  class CacheControlConfigFetcher < ConfigFetcher
13
- def initialize(api_key, mode, base_url=nil)
13
+ def initialize(api_key, mode, base_url=nil, proxy_address=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil)
14
14
  @_api_key = api_key
15
15
  @_etag = nil
16
16
  @_headers = {"User-Agent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "X-ConfigCat-UserAgent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "Content-Type" => "application/json"}
@@ -20,7 +20,7 @@ module ConfigCat
20
20
  @_base_url = BASE_URL
21
21
  end
22
22
  uri = URI.parse(@_base_url)
23
- @_http = Net::HTTP.new(uri.host, uri.port)
23
+ @_http = Net::HTTP.new(uri.host, uri.port, proxy_address, proxy_port, proxy_user, proxy_pass)
24
24
  @_http.use_ssl = true if uri.scheme == 'https'
25
25
  @_http.open_timeout = 10 # in seconds
26
26
  @_http.read_timeout = 30 # in seconds
@@ -49,6 +49,7 @@ module ConfigCat
49
49
  @_lock.release_write_lock()
50
50
  end
51
51
  rescue StandardError => e
52
+ ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
52
53
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
53
54
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
54
55
  end
@@ -29,6 +29,7 @@ module ConfigCat
29
29
  @_lock.release_write_lock()
30
30
  end
31
31
  rescue StandardError => e
32
+ ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
32
33
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
33
34
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
34
35
  end
@@ -1,71 +1,172 @@
1
1
  require 'configcat/user'
2
2
  require 'digest'
3
+ require 'semantic'
3
4
 
4
5
  module ConfigCat
5
6
  class RolloutEvaluator
7
+ COMPARATOR_TEXTS = ["IS ONE OF", "IS NOT ONE OF", "CONTAINS", "DOES NOT CONTAIN", "IS ONE OF (SemVer)", "IS NOT ONE OF (SemVer)", "< (SemVer)", "<= (SemVer)", "> (SemVer)", ">= (SemVer)", "= (Number)", "<> (Number)", "< (Number)", "<= (Number)", "> (Number)", ">= (Number)"]
8
+
9
+ VALUE = "v"
10
+ COMPARATOR = "t"
11
+ COMPARISON_ATTRIBUTE = "a"
12
+ COMPARISON_VALUE = "c"
13
+ ROLLOUT_PERCENTAGE_ITEMS = "p"
14
+ PERCENTAGE = "p"
15
+ ROLLOUT_RULES = "r"
6
16
 
7
17
  def self.evaluate(key, user, default_value, config)
8
- if !user.equal?(nil) && !user.class.equal?(User)
9
- ConfigCat.logger.warn "User parameter is not an instance of User type."
10
- user = nil
11
- end
18
+ ConfigCat.logger.info("Evaluating get_value('%s')." % key)
19
+
12
20
  setting_descriptor = config.fetch(key, nil)
13
21
  if setting_descriptor === nil
14
- ConfigCat.logger.warn "Could not find setting by key, returning default value. Key: #{key}"
22
+ ConfigCat.logger.error("Evaluating get_value('%s') failed. Value not found for key '%s' Returning default_value: [%s]. Here are the available keys: %s" % [key, key, default_value.to_s, config.to_a.join(", ")])
15
23
  return default_value
16
24
  end
25
+
26
+ rollout_rules = setting_descriptor.fetch(ROLLOUT_RULES, [])
27
+ rollout_percentage_items = setting_descriptor.fetch(ROLLOUT_PERCENTAGE_ITEMS, [])
28
+
29
+ if !user.equal?(nil) && !user.class.equal?(User)
30
+ ConfigCat.logger.warn("Evaluating get_value('%s'). User Object is not an instance of User type." % key)
31
+ user = nil
32
+ end
17
33
  if user === nil
18
- return setting_descriptor.fetch("Value", default_value)
34
+ if rollout_rules.size > 0 || rollout_percentage_items.size > 0
35
+ ConfigCat.logger.warn("Evaluating get_value('%s'). UserObject missing! You should pass a UserObject to get_value(), in order to make targeting work properly. Read more: https://configcat.com/docs/advanced/user-object/" % key)
36
+ end
37
+ return_value = setting_descriptor.fetch(VALUE, default_value)
38
+ ConfigCat.logger.info("Returning [%s]" % return_value.to_s)
39
+ return return_value
19
40
  end
20
- rollout_rules = setting_descriptor.fetch("RolloutRules", [])
41
+
42
+ ConfigCat.logger.info("User object:\n%s" % user.to_s)
43
+
44
+ # Evaluate targeting rules
21
45
  for rollout_rule in rollout_rules
22
- comparison_attribute = rollout_rule.fetch("ComparisonAttribute")
46
+ comparison_attribute = rollout_rule.fetch(COMPARISON_ATTRIBUTE)
47
+ comparison_value = rollout_rule.fetch(COMPARISON_VALUE, nil)
48
+ comparator = rollout_rule.fetch(COMPARATOR, nil)
49
+
23
50
  user_value = user.get_attribute(comparison_attribute)
24
51
  if user_value === nil || !user_value
52
+ ConfigCat.logger.info(format_no_match_rule(comparison_attribute, comparator, comparison_value))
25
53
  next
26
54
  end
27
- comparison_value = rollout_rule.fetch("ComparisonValue", nil)
28
- comparator = rollout_rule.fetch("Comparator", nil)
29
- value = rollout_rule.fetch("Value", nil)
55
+
56
+ value = rollout_rule.fetch(VALUE, nil)
57
+
58
+ # IS ONE OF
30
59
  if comparator == 0
31
60
  if comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
61
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
62
+ return value
63
+ end
64
+ # IS NOT ONE OF
65
+ elsif comparator == 1
66
+ if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
67
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
32
68
  return value
33
69
  end
34
- else
35
- if comparator == 1
36
- if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
70
+ # CONTAINS
71
+ elsif comparator == 2
72
+ if user_value.to_s.include?(comparison_value.to_s)
73
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
74
+ return value
75
+ end
76
+ # DOES NOT CONTAIN
77
+ elsif comparator == 3
78
+ if !user_value.to_s.include?(comparison_value.to_s)
79
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
80
+ return value
81
+ end
82
+ # IS ONE OF, IS NOT ONE OF (Semantic version)
83
+ elsif (4 <= comparator) && (comparator <= 5)
84
+ begin
85
+ match = false
86
+ user_value_version = Semantic::Version.new(user_value.to_s.strip())
87
+ ((comparison_value.to_s.split(",").map { |x| x.strip() }).reject { |c| c.empty? }).each { |x|
88
+ version = Semantic::Version.new(x)
89
+ match = (user_value_version == version) || match
90
+ }
91
+ if match && comparator == 4 || !match && comparator == 5
92
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
37
93
  return value
38
94
  end
39
- else
40
- if comparator == 2
41
- if user_value.to_s.include?(comparison_value.to_s)
42
- return value
43
- end
44
- else
45
- if comparator == 3
46
- if !user_value.to_s.include?(comparison_value.to_s)
47
- return value
48
- end
49
- end
95
+ rescue ArgumentError => e
96
+ ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, comparator, comparison_value, e.to_s))
97
+ next
98
+ end
99
+ # LESS THAN, LESS THAN OR EQUALS TO, GREATER THAN, GREATER THAN OR EQUALS TO (Semantic version)
100
+ elsif (6 <= comparator) && (comparator <= 9)
101
+ begin
102
+ user_value_version = Semantic::Version.new(user_value.to_s.strip())
103
+ comparison_value_version = Semantic::Version.new(comparison_value.to_s.strip())
104
+ if (comparator == 6 && user_value_version < comparison_value_version) ||
105
+ (comparator == 7 && user_value_version <= comparison_value_version) ||
106
+ (comparator == 8 && user_value_version > comparison_value_version) ||
107
+ (comparator == 9 && user_value_version >= comparison_value_version)
108
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
109
+ return value
50
110
  end
111
+ rescue ArgumentError => e
112
+ ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, comparator, comparison_value, e.to_s))
113
+ next
114
+ end
115
+ elsif (10 <= comparator) && (comparator <= 15)
116
+ begin
117
+ user_value_float = Float(user_value.to_s.gsub(",", "."))
118
+ comparison_value_float = Float(comparison_value.to_s.gsub(",", "."))
119
+ if (comparator == 10 && user_value_float == comparison_value_float) ||
120
+ (comparator == 11 && user_value_float != comparison_value_float) ||
121
+ (comparator == 12 && user_value_float < comparison_value_float) ||
122
+ (comparator == 13 && user_value_float <= comparison_value_float) ||
123
+ (comparator == 14 && user_value_float > comparison_value_float) ||
124
+ (comparator == 15 && user_value_float >= comparison_value_float)
125
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, comparator, comparison_value, value))
126
+ return value
127
+ end
128
+ rescue Exception => e
129
+ ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, comparator, comparison_value, e.to_s))
130
+ next
51
131
  end
52
132
  end
133
+
134
+ ConfigCat.logger.info(format_no_match_rule(comparison_attribute, comparator, comparison_value))
53
135
  end
54
- rollout_percentage_items = setting_descriptor.fetch("RolloutPercentageItems", [])
136
+
55
137
  if rollout_percentage_items.size > 0
56
138
  user_key = user.get_identifier()
57
139
  hash_candidate = ("%s%s" % [key, user_key]).encode("utf-8")
58
140
  hash_val = Digest::SHA1.hexdigest(hash_candidate)[0...7].to_i(base=16) % 100
59
141
  bucket = 0
60
142
  for rollout_percentage_item in rollout_percentage_items || []
61
- bucket += rollout_percentage_item.fetch("Percentage", 0)
143
+ bucket += rollout_percentage_item.fetch(PERCENTAGE, 0)
62
144
  if hash_val < bucket
63
- return rollout_percentage_item.fetch("Value", nil)
145
+ percentage_value = rollout_percentage_item.fetch(VALUE, nil)
146
+ ConfigCat.logger.info("Evaluating %% options. Returning %s" % percentage_value)
147
+ return percentage_value
64
148
  end
65
149
  end
66
150
  end
67
- return setting_descriptor.fetch("Value", default_value)
151
+ def_value = setting_descriptor.fetch(VALUE, default_value)
152
+ ConfigCat.logger.info("Returning %s" % def_value)
153
+ return def_value
68
154
  end
155
+
156
+ private
157
+
158
+ def self.format_match_rule(comparison_attribute, comparator, comparison_value, value)
159
+ return "Evaluating rule: [%s] [%s] [%s] => match, returning: %s" % [comparison_attribute, COMPARATOR_TEXTS[comparator], comparison_value, value]
160
+ end
161
+
162
+ def self.format_no_match_rule(comparison_attribute, comparator, comparison_value)
163
+ return "Evaluating rule: [%s] [%s] [%s] => no match" % [comparison_attribute, COMPARATOR_TEXTS[comparator], comparison_value]
164
+ end
165
+
166
+ def self.format_validation_error_rule(comparison_attribute, comparator, comparison_value, error)
167
+ return "Evaluating rule: [%s] [%s] [%s] => SKIP rule. Validation error: %s" % [comparison_attribute, COMPARATOR_TEXTS[comparator], comparison_value, error]
168
+ end
169
+
69
170
  end
70
171
 
71
172
  end
@@ -1,3 +1,3 @@
1
1
  module ConfigCat
2
- VERSION = "1.0.1"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configcat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ConfigCat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-14 00:00:00.000000000 Z
11
+ date: 2019-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: semantic
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: coveralls
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  description: ConfigCat is a configuration as a service that lets you manage your features
56
84
  and configurations without actually deploying new code.
57
85
  email: