unleash 3.2.0 → 3.2.4
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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +13 -7
- data/.travis.yml +3 -4
- data/README.md +3 -3
- data/examples/simple.rb +2 -2
- data/lib/unleash/activation_strategy.rb +16 -3
- data/lib/unleash/client.rb +11 -3
- data/lib/unleash/constraint.rb +26 -0
- data/lib/unleash/context.rb +18 -5
- data/lib/unleash/feature_toggle.rb +44 -17
- data/lib/unleash/strategy/flexible_rollout.rb +55 -0
- data/lib/unleash/strategy/gradual_rollout_sessionid.rb +1 -1
- data/lib/unleash/strategy/gradual_rollout_userid.rb +2 -2
- data/lib/unleash/toggle_fetcher.rb +2 -1
- data/lib/unleash/version.rb +1 -1
- data/lib/unleash.rb +1 -1
- data/unleash-client.gemspec +7 -7
- metadata +19 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cf913a6af33742c1001e328f96a5382eb0666b99280d008d6960e105681ded2
|
4
|
+
data.tar.gz: e6cbc6db182f1212e4580e8781b7ac6444b12f26116dc922a4568d728299399a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6499b2f136c8dcf6b7f115b29ad762a336a3e8eac669f4f87577f542242cc9a2cdcb41b36101d9483111217274afc6e07a01d3217393fc7fcd76854866fd74d
|
7
|
+
data.tar.gz: e3d5d385c49552035aa9700db64ccb44320e3265cb415d03f9a1d135ab09d126bb10bb0834b72e3b9d7fec4a5340f612d63024e7259ca85d0024684eedd6230f
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# inherit_from: .rubocop_todo.yml
|
2
2
|
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.5
|
5
|
+
|
3
6
|
Naming/PredicateName:
|
4
|
-
|
7
|
+
AllowedMethods:
|
5
8
|
- is_enabled?
|
6
9
|
|
7
10
|
Metrics/ClassLength:
|
8
11
|
Max: 120
|
9
|
-
|
12
|
+
Layout/LineLength:
|
10
13
|
Max: 140
|
11
14
|
Metrics/MethodLength:
|
12
15
|
Max: 20
|
@@ -19,9 +22,9 @@ Metrics/BlockLength:
|
|
19
22
|
Metrics/AbcSize:
|
20
23
|
Max: 25
|
21
24
|
Metrics/CyclomaticComplexity:
|
22
|
-
Max:
|
25
|
+
Max: 9
|
23
26
|
Metrics/PerceivedComplexity:
|
24
|
-
Max:
|
27
|
+
Max: 9
|
25
28
|
|
26
29
|
Style/Documentation:
|
27
30
|
Enabled: false
|
@@ -42,9 +45,12 @@ Style/FrozenStringLiteralComment:
|
|
42
45
|
Style/GuardClause:
|
43
46
|
MinBodyLength: 8
|
44
47
|
|
45
|
-
Style/
|
46
|
-
|
47
|
-
|
48
|
+
Style/HashEachMethods:
|
49
|
+
Enabled: true
|
50
|
+
Style/HashTransformKeys:
|
51
|
+
Enabled: true
|
52
|
+
Style/HashTransformValues:
|
53
|
+
Enabled: true
|
48
54
|
|
49
55
|
Style/IfInsideElse:
|
50
56
|
Exclude:
|
data/.travis.yml
CHANGED
@@ -2,14 +2,13 @@ sudo: false
|
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
4
|
- jruby
|
5
|
+
- 3.0
|
5
6
|
- 2.7
|
6
7
|
- 2.6
|
7
8
|
- 2.5
|
8
|
-
- 2.4
|
9
9
|
before_install:
|
10
|
-
- gem install bundler -v 2.
|
11
|
-
- git clone --depth 5 --branch v3.
|
12
|
-
client-specification
|
10
|
+
- gem install bundler -v 2.1.4
|
11
|
+
- git clone --depth 5 --branch v3.3.0 https://github.com/Unleash/client-specification.git client-specification
|
13
12
|
|
14
13
|
notifications:
|
15
14
|
slack:
|
data/README.md
CHANGED
@@ -10,10 +10,10 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
|
|
10
10
|
|
11
11
|
## Supported Ruby Interpreters
|
12
12
|
|
13
|
+
* MRI 3.0
|
13
14
|
* MRI 2.7
|
14
15
|
* MRI 2.6
|
15
16
|
* MRI 2.5
|
16
|
-
* MRI 2.4
|
17
17
|
* jruby
|
18
18
|
|
19
19
|
## Installation
|
@@ -21,7 +21,7 @@ Leverage the [Unleash Server](https://github.com/Unleash/unleash) for powerful f
|
|
21
21
|
Add this line to your application's Gemfile:
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
gem 'unleash', '~> 3.2.
|
24
|
+
gem 'unleash', '~> 3.2.4'
|
25
25
|
```
|
26
26
|
|
27
27
|
And then execute:
|
@@ -66,7 +66,7 @@ Argument | Description | Required? | Type | Default Value|
|
|
66
66
|
`disable_metrics` | Disables sending metrics to Unleash server. | N | Boolean | `false` |
|
67
67
|
`custom_http_headers` | Custom headers to send to Unleash. | N | Hash | {} |
|
68
68
|
`timeout` | How long to wait for the connection to be established or wait in reading state (open_timeout/read_timeout) | N | Integer | 30 |
|
69
|
-
`retry_limit` | How many consecutive failures in connecting to the Unleash server are allowed before giving up. | N |
|
69
|
+
`retry_limit` | How many consecutive failures in connecting to the Unleash server are allowed before giving up. Use `Float::INFINITY` if you would like it to never give up. | N | Numeric | 5 |
|
70
70
|
`backup_file` | Filename to store the last known state from the Unleash server. Best to not change this from the default. | N | String | `Dir.tmpdir + "/unleash-#{app_name}-repo.json` |
|
71
71
|
`logger` | Specify a custom `Logger` class to handle logs for the Unleash client. | N | Class | `Logger.new(STDOUT)` |
|
72
72
|
`log_level` | Change the log level for the `Logger` class. Constant from `Logger::Severity`. | N | Constant | `Logger::ERROR` |
|
data/examples/simple.rb
CHANGED
@@ -17,13 +17,13 @@ puts ">> START simple.rb"
|
|
17
17
|
# or:
|
18
18
|
|
19
19
|
@unleash = Unleash::Client.new(
|
20
|
-
url: '
|
20
|
+
url: 'https://app.unleash-hosted.com/demo/api',
|
21
21
|
app_name: 'simple-test',
|
22
22
|
instance_id: 'local-test-cli',
|
23
23
|
refresh_interval: 2,
|
24
24
|
metrics_interval: 2,
|
25
25
|
retry_limit: 2,
|
26
|
-
|
26
|
+
custom_http_headers: {'Authorization': '943ca9171e2c884c545c5d82417a655fb77cec970cc3b78a8ff87f4406b495d0'},
|
27
27
|
)
|
28
28
|
|
29
29
|
# feature_name = "AwesomeFeature"
|
@@ -1,16 +1,29 @@
|
|
1
1
|
module Unleash
|
2
2
|
class ActivationStrategy
|
3
|
-
attr_accessor :name, :params
|
3
|
+
attr_accessor :name, :params, :constraints
|
4
4
|
|
5
|
-
def initialize(name, params)
|
5
|
+
def initialize(name, params, constraints = [])
|
6
6
|
self.name = name
|
7
7
|
|
8
8
|
if params.is_a?(Hash)
|
9
9
|
self.params = params
|
10
|
+
elsif params.nil?
|
11
|
+
self.params = {}
|
10
12
|
else
|
11
|
-
Unleash.logger.warn "Invalid params provided for ActivationStrategy
|
13
|
+
Unleash.logger.warn "Invalid params provided for ActivationStrategy (params:#{params})"
|
12
14
|
self.params = {}
|
13
15
|
end
|
16
|
+
|
17
|
+
if constraints.is_a?(Array) && constraints.each{ |c| c.is_a?(Constraint) }
|
18
|
+
self.constraints = constraints
|
19
|
+
else
|
20
|
+
Unleash.logger.warn "Invalid constraints provided for ActivationStrategy (contraints: #{constraints})"
|
21
|
+
self.constraints = []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def matches_context?(context)
|
26
|
+
self.constraints.any?{ |c| c.matches_context? context }
|
14
27
|
end
|
15
28
|
end
|
16
29
|
end
|
data/lib/unleash/client.rb
CHANGED
@@ -60,7 +60,7 @@ module Unleash
|
|
60
60
|
Unleash.logger.debug "Unleash::Client.get_variant for feature: #{feature} with context #{context}"
|
61
61
|
|
62
62
|
if Unleash.configuration.disable_client
|
63
|
-
Unleash.logger.debug "unleash_client is disabled! Always returning #{
|
63
|
+
Unleash.logger.debug "unleash_client is disabled! Always returning #{fallback_variant} for feature #{feature}!"
|
64
64
|
return fallback_variant || Unleash::FeatureToggle.disabled_variant
|
65
65
|
end
|
66
66
|
|
@@ -116,7 +116,11 @@ module Unleash
|
|
116
116
|
|
117
117
|
def start_toggle_fetcher
|
118
118
|
Unleash.toggle_fetcher = Unleash::ToggleFetcher.new
|
119
|
-
self.fetcher_scheduled_executor = Unleash::ScheduledExecutor.new(
|
119
|
+
self.fetcher_scheduled_executor = Unleash::ScheduledExecutor.new(
|
120
|
+
'ToggleFetcher',
|
121
|
+
Unleash.configuration.refresh_interval,
|
122
|
+
Unleash.configuration.retry_limit
|
123
|
+
)
|
120
124
|
self.fetcher_scheduled_executor.run do
|
121
125
|
Unleash.toggle_fetcher.fetch
|
122
126
|
end
|
@@ -125,7 +129,11 @@ module Unleash
|
|
125
129
|
def start_metrics
|
126
130
|
Unleash.toggle_metrics = Unleash::Metrics.new
|
127
131
|
Unleash.reporter = Unleash::MetricsReporter.new
|
128
|
-
self.metrics_scheduled_executor = Unleash::ScheduledExecutor.new(
|
132
|
+
self.metrics_scheduled_executor = Unleash::ScheduledExecutor.new(
|
133
|
+
'MetricsReporter',
|
134
|
+
Unleash.configuration.metrics_interval,
|
135
|
+
Unleash.configuration.retry_limit
|
136
|
+
)
|
129
137
|
self.metrics_scheduled_executor.run do
|
130
138
|
Unleash.reporter.send
|
131
139
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Unleash
|
2
|
+
class Constraint
|
3
|
+
attr_accessor :context_name, :operator, :values
|
4
|
+
|
5
|
+
VALID_OPERATORS = ['IN', 'NOT_IN'].freeze
|
6
|
+
|
7
|
+
def initialize(context_name, operator, values = [])
|
8
|
+
raise ArgumentError, "context_name is not a String" unless context_name.is_a?(String)
|
9
|
+
raise ArgumentError, "operator does not hold a valid value:" + VALID_OPERATORS unless VALID_OPERATORS.include? operator
|
10
|
+
raise ArgumentError, "values does not hold an Array" unless values.is_a?(Array)
|
11
|
+
|
12
|
+
self.context_name = context_name
|
13
|
+
self.operator = operator
|
14
|
+
self.values = values
|
15
|
+
end
|
16
|
+
|
17
|
+
def matches_context?(context)
|
18
|
+
Unleash.logger.debug "Unleash::Constraint matches_context? values: #{self.values} context.get_by_name(#{self.context_name})" \
|
19
|
+
" #{context.get_by_name(self.context_name)} "
|
20
|
+
|
21
|
+
is_included = self.values.include? context.get_by_name(self.context_name)
|
22
|
+
|
23
|
+
operator == 'IN' ? is_included : !is_included
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/unleash/context.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Unleash
|
2
2
|
class Context
|
3
|
-
|
3
|
+
ATTRS = [:app_name, :environment, :user_id, :session_id, :remote_address].freeze
|
4
|
+
|
5
|
+
attr_accessor(*[ATTRS, :properties].flatten)
|
4
6
|
|
5
7
|
def initialize(params = {})
|
6
8
|
raise ArgumentError, "Unleash::Context must be initialized with a hash." unless params.is_a?(Hash)
|
@@ -12,18 +14,29 @@ module Unleash
|
|
12
14
|
self.remote_address = value_for('remoteAddress', params)
|
13
15
|
|
14
16
|
properties = value_for('properties', params)
|
15
|
-
self.properties = properties.is_a?(Hash) ? properties : {}
|
17
|
+
self.properties = properties.is_a?(Hash) ? properties.transform_keys(&:to_sym) : {}
|
16
18
|
end
|
17
19
|
|
18
20
|
def to_s
|
19
|
-
"<Context: user_id=#{
|
21
|
+
"<Context: user_id=#{@user_id},session_id=#{@session_id},remote_address=#{@remote_address},properties=#{@properties}" \
|
22
|
+
",app_name=#{@app_name},environment=#{@environment}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_by_name(name)
|
26
|
+
normalized_name = underscore(name).to_sym
|
27
|
+
|
28
|
+
if ATTRS.include? normalized_name
|
29
|
+
self.send(normalized_name)
|
30
|
+
else
|
31
|
+
self.properties.fetch(normalized_name)
|
32
|
+
end
|
20
33
|
end
|
21
34
|
|
22
35
|
private
|
23
36
|
|
24
37
|
# Method to fetch values from hash for two types of keys: string in camelCase and symbol in snake_case
|
25
|
-
def value_for(key, params, default_value =
|
26
|
-
params.values_at(key, underscore(key).to_sym).compact.first || default_value
|
38
|
+
def value_for(key, params, default_value = nil)
|
39
|
+
params.values_at(key, key.to_sym, underscore(key), underscore(key).to_sym).compact.first || default_value
|
27
40
|
end
|
28
41
|
|
29
42
|
# converts CamelCase to snake_case
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'unleash/activation_strategy'
|
2
|
+
require 'unleash/constraint'
|
2
3
|
require 'unleash/variant_definition'
|
3
4
|
require 'unleash/variant'
|
4
5
|
require 'unleash/strategy/util'
|
@@ -13,20 +14,9 @@ module Unleash
|
|
13
14
|
|
14
15
|
self.name = params.fetch('name', nil)
|
15
16
|
self.enabled = params.fetch('enabled', false)
|
16
|
-
self.strategies = params.fetch('strategies', [])
|
17
|
-
.select{ |s| s.has_key?('name') && Unleash::STRATEGIES.has_key?(s['name'].to_sym) }
|
18
|
-
.map{ |s| ActivationStrategy.new(s['name'], s['parameters'] || {}) } || []
|
19
17
|
|
20
|
-
self.
|
21
|
-
|
22
|
-
.map do |v|
|
23
|
-
VariantDefinition.new(
|
24
|
-
v.fetch('name', ''),
|
25
|
-
v.fetch('weight', 0),
|
26
|
-
v.fetch('payload', nil),
|
27
|
-
v.fetch('overrides', [])
|
28
|
-
)
|
29
|
-
end || []
|
18
|
+
self.strategies = initialize_strategies(params)
|
19
|
+
self.variant_definitions = initialize_variant_definitions(params)
|
30
20
|
end
|
31
21
|
|
32
22
|
def to_s
|
@@ -64,23 +54,29 @@ module Unleash
|
|
64
54
|
result =
|
65
55
|
if self.enabled
|
66
56
|
self.strategies.empty? ||
|
67
|
-
self.strategies.any?
|
57
|
+
self.strategies.any? do |s|
|
58
|
+
strategy_enabled?(s, context) && strategy_constraint_matches?(s, context)
|
59
|
+
end
|
68
60
|
else
|
69
61
|
default_result
|
70
62
|
end
|
71
63
|
|
72
|
-
Unleash.logger.debug "FeatureToggle (enabled:#{self.enabled} default_result:#{default_result} " \
|
73
|
-
"and Strategies combined returned #{result})"
|
64
|
+
Unleash.logger.debug "Unleash::FeatureToggle (enabled:#{self.enabled} default_result:#{default_result} " \
|
65
|
+
"and Strategies combined with contraints returned #{result})"
|
74
66
|
|
75
67
|
result
|
76
68
|
end
|
77
69
|
|
78
70
|
def strategy_enabled?(strategy, context)
|
79
71
|
r = Unleash::STRATEGIES.fetch(strategy.name.to_sym, :unknown).is_enabled?(strategy.params, context)
|
80
|
-
Unleash.logger.debug "Strategy #{strategy.name} returned #{r} with context: #{context}"
|
72
|
+
Unleash.logger.debug "Unleash::FeatureToggle.strategy_enabled? Strategy #{strategy.name} returned #{r} with context: #{context}"
|
81
73
|
r
|
82
74
|
end
|
83
75
|
|
76
|
+
def strategy_constraint_matches?(strategy, context)
|
77
|
+
strategy.constraints.empty? || strategy.constraints.all?{ |c| c.matches_context?(context) }
|
78
|
+
end
|
79
|
+
|
84
80
|
def disabled_variant
|
85
81
|
Unleash::Variant.new(name: 'disabled', enabled: false)
|
86
82
|
end
|
@@ -127,5 +123,36 @@ module Unleash
|
|
127
123
|
end
|
128
124
|
context
|
129
125
|
end
|
126
|
+
|
127
|
+
def initialize_strategies(params)
|
128
|
+
params.fetch('strategies', [])
|
129
|
+
.select{ |s| s.has_key?('name') && Unleash::STRATEGIES.has_key?(s['name'].to_sym) }
|
130
|
+
.map do |s|
|
131
|
+
ActivationStrategy.new(
|
132
|
+
s['name'],
|
133
|
+
s['parameters'],
|
134
|
+
(s['constraints'] || []).map do |c|
|
135
|
+
Constraint.new(
|
136
|
+
c.fetch('contextName'),
|
137
|
+
c.fetch('operator'),
|
138
|
+
c.fetch('values')
|
139
|
+
)
|
140
|
+
end
|
141
|
+
)
|
142
|
+
end || []
|
143
|
+
end
|
144
|
+
|
145
|
+
def initialize_variant_definitions(params)
|
146
|
+
(params.fetch('variants', []) || [])
|
147
|
+
.select{ |v| v.is_a?(Hash) && v.has_key?('name') }
|
148
|
+
.map do |v|
|
149
|
+
VariantDefinition.new(
|
150
|
+
v.fetch('name', ''),
|
151
|
+
v.fetch('weight', 0),
|
152
|
+
v.fetch('payload', nil),
|
153
|
+
v.fetch('overrides', [])
|
154
|
+
)
|
155
|
+
end || []
|
156
|
+
end
|
130
157
|
end
|
131
158
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'unleash/strategy/util'
|
2
|
+
|
3
|
+
module Unleash
|
4
|
+
module Strategy
|
5
|
+
class FlexibleRollout < Base
|
6
|
+
def name
|
7
|
+
'flexibleRollout'
|
8
|
+
end
|
9
|
+
|
10
|
+
# need: params['percentage']
|
11
|
+
def is_enabled?(params = {}, context = nil)
|
12
|
+
return false unless params.is_a?(Hash)
|
13
|
+
return false unless context.class.name == 'Unleash::Context'
|
14
|
+
|
15
|
+
stickiness = params.fetch('stickiness', 'default')
|
16
|
+
stickiness_id = resolve_stickiness(stickiness, context)
|
17
|
+
|
18
|
+
begin
|
19
|
+
percentage = Integer(params.fetch('rollout', 0))
|
20
|
+
percentage = 0 if percentage > 100 || percentage.negative?
|
21
|
+
rescue ArgumentError
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
|
25
|
+
group_id = params.fetch('groupId', '')
|
26
|
+
normalized_number = Util.get_normalized_number(stickiness_id, group_id)
|
27
|
+
|
28
|
+
return false if stickiness_id.nil?
|
29
|
+
|
30
|
+
(percentage.positive? && normalized_number <= percentage)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def random
|
36
|
+
Random.rand(0..100)
|
37
|
+
end
|
38
|
+
|
39
|
+
def resolve_stickiness(stickiness, context)
|
40
|
+
case stickiness
|
41
|
+
when 'userId'
|
42
|
+
context.user_id
|
43
|
+
when 'sessionId'
|
44
|
+
context.session_id
|
45
|
+
when 'random'
|
46
|
+
random
|
47
|
+
when 'default'
|
48
|
+
context.user_id || context.session_id || random
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -11,7 +11,7 @@ module Unleash
|
|
11
11
|
def is_enabled?(params = {}, context = nil)
|
12
12
|
return false unless params.is_a?(Hash) && params.has_key?('percentage')
|
13
13
|
return false unless context.class.name == 'Unleash::Context'
|
14
|
-
return false if context.session_id.empty?
|
14
|
+
return false if context.session_id.nil? || context.session_id.empty?
|
15
15
|
|
16
16
|
percentage = Integer(params['percentage'] || 0)
|
17
17
|
(percentage.positive? && Util.get_normalized_number(context.session_id, params['groupId'] || "") <= percentage)
|
@@ -8,10 +8,10 @@ module Unleash
|
|
8
8
|
end
|
9
9
|
|
10
10
|
# need: params['percentage'], params['groupId'], context.user_id,
|
11
|
-
def is_enabled?(params = {}, context = nil)
|
11
|
+
def is_enabled?(params = {}, context = nil, _constraints = [])
|
12
12
|
return false unless params.is_a?(Hash) && params.has_key?('percentage')
|
13
13
|
return false unless context.class.name == 'Unleash::Context'
|
14
|
-
return false if context.user_id.empty?
|
14
|
+
return false if context.user_id.nil? || context.user_id.empty?
|
15
15
|
|
16
16
|
percentage = Integer(params['percentage'] || 0)
|
17
17
|
(percentage.positive? && Util.get_normalized_number(context.user_id, params['groupId'] || "") <= percentage)
|
@@ -48,7 +48,7 @@ module Unleash
|
|
48
48
|
self.etag = response['ETag']
|
49
49
|
response_hash = JSON.parse(response.body)
|
50
50
|
|
51
|
-
if response_hash['version']
|
51
|
+
if response_hash['version'] >= 1
|
52
52
|
features = response_hash['features']
|
53
53
|
else
|
54
54
|
raise NotImplemented, "Version of features provided by unleash server" \
|
@@ -71,6 +71,7 @@ module Unleash
|
|
71
71
|
self.toggle_lock.synchronize do
|
72
72
|
file = File.open(backup_file_tmp, "w")
|
73
73
|
file.write(self.toggle_cache.to_json)
|
74
|
+
file.close
|
74
75
|
File.rename(backup_file_tmp, backup_file)
|
75
76
|
end
|
76
77
|
rescue StandardError => e
|
data/lib/unleash/version.rb
CHANGED
data/lib/unleash.rb
CHANGED
@@ -5,7 +5,7 @@ require 'unleash/context'
|
|
5
5
|
require 'unleash/client'
|
6
6
|
require 'logger'
|
7
7
|
|
8
|
-
Gem.find_files('unleash/strategy/**/*.rb').each{ |path| require path }
|
8
|
+
Gem.find_files('unleash/strategy/**/*.rb').each{ |path| require path unless path.end_with? '_spec.rb' }
|
9
9
|
|
10
10
|
module Unleash
|
11
11
|
TIME_RESOLUTION = 3
|
data/unleash-client.gemspec
CHANGED
@@ -21,16 +21,16 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.bindir = 'bin'
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/unleash}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
|
-
spec.required_ruby_version = "
|
24
|
+
spec.required_ruby_version = ">= 2.5"
|
25
25
|
|
26
26
|
spec.add_dependency "murmurhash3", "~> 0.1.6"
|
27
27
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 2.
|
29
|
-
spec.add_development_dependency "rake", "~>
|
30
|
-
spec.add_development_dependency "rspec", "~> 3.
|
31
|
-
spec.add_development_dependency "rspec-json_expectations", "~> 2.
|
32
|
-
spec.add_development_dependency "webmock", "~> 3.
|
28
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
29
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
31
|
+
spec.add_development_dependency "rspec-json_expectations", "~> 2.2"
|
32
|
+
spec.add_development_dependency "webmock", "~> 3.8"
|
33
33
|
|
34
34
|
spec.add_development_dependency "coveralls", "~> 0.8"
|
35
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
35
|
+
spec.add_development_dependency "rubocop", "~> 0.80"
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unleash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Renato Arruda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: murmurhash3
|
@@ -30,70 +30,70 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2.
|
33
|
+
version: '2.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2.
|
40
|
+
version: '2.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '12.3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '12.3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3.
|
61
|
+
version: '3.9'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '3.
|
68
|
+
version: '3.9'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec-json_expectations
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '2.
|
75
|
+
version: '2.2'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '2.
|
82
|
+
version: '2.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: webmock
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '3.
|
89
|
+
version: '3.8'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '3.
|
96
|
+
version: '3.8'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: coveralls
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
117
|
+
version: '0.80'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
124
|
+
version: '0.80'
|
125
125
|
description: |-
|
126
126
|
This is the ruby client for Unleash, a powerful feature toggle system
|
127
127
|
that gives you a great overview over all feature toggles across all your applications and services.
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/unleash/activation_strategy.rb
|
149
149
|
- lib/unleash/client.rb
|
150
150
|
- lib/unleash/configuration.rb
|
151
|
+
- lib/unleash/constraint.rb
|
151
152
|
- lib/unleash/context.rb
|
152
153
|
- lib/unleash/feature_toggle.rb
|
153
154
|
- lib/unleash/metrics.rb
|
@@ -156,6 +157,7 @@ files:
|
|
156
157
|
- lib/unleash/strategy/application_hostname.rb
|
157
158
|
- lib/unleash/strategy/base.rb
|
158
159
|
- lib/unleash/strategy/default.rb
|
160
|
+
- lib/unleash/strategy/flexible_rollout.rb
|
159
161
|
- lib/unleash/strategy/gradual_rollout_random.rb
|
160
162
|
- lib/unleash/strategy/gradual_rollout_sessionid.rb
|
161
163
|
- lib/unleash/strategy/gradual_rollout_userid.rb
|
@@ -179,16 +181,16 @@ require_paths:
|
|
179
181
|
- lib
|
180
182
|
required_ruby_version: !ruby/object:Gem::Requirement
|
181
183
|
requirements:
|
182
|
-
- - "
|
184
|
+
- - ">="
|
183
185
|
- !ruby/object:Gem::Version
|
184
|
-
version: '2.
|
186
|
+
version: '2.5'
|
185
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
188
|
requirements:
|
187
189
|
- - ">="
|
188
190
|
- !ruby/object:Gem::Version
|
189
191
|
version: '0'
|
190
192
|
requirements: []
|
191
|
-
rubygems_version: 3.
|
193
|
+
rubygems_version: 3.2.3
|
192
194
|
signing_key:
|
193
195
|
specification_version: 4
|
194
196
|
summary: Unleash feature toggle client.
|