rollout 2.4.3 → 2.4.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 +5 -5
- data/.circleci/config.yml +80 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +5 -5
- data/Gemfile +3 -1
- data/Gemfile.lock +44 -35
- data/README.md +10 -6
- data/Rakefile +5 -7
- data/lib/rollout.rb +71 -70
- data/lib/rollout/version.rb +3 -1
- data/rollout.gemspec +27 -23
- data/spec/spec_helper.rb +13 -10
- metadata +40 -43
- data/.document +0 -5
- data/Appraisals +0 -7
- data/gemfiles/redis_3.gemfile +0 -13
- data/gemfiles/redis_4.gemfile +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2f9fd3e63d0d90aef2e2731d02bc6009a14572e9c2599f6a9c6f2431c229f072
|
4
|
+
data.tar.gz: cb11d12f34818d24533717e55e8b46947be12e46ed85db05151e0a5fba5effac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f16756f6a5e15d301060999c6529d7a1ebad0e1f4d4ed01ba06008c1843518b0df887bcf124832591b7673aba48e121d5886efb083509ed910f13aebade88fa2
|
7
|
+
data.tar.gz: fbd41cf3de15894d26f311f4c7d3d84c08c40d4600b63fa767e8b8af9d06ee068ee9d8b8912c7de5e3475dbe636bc58562efa484304b05d4074c4afe649738c0
|
@@ -0,0 +1,80 @@
|
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
workflows:
|
4
|
+
main:
|
5
|
+
jobs:
|
6
|
+
- ruby26
|
7
|
+
- ruby25
|
8
|
+
- ruby24
|
9
|
+
- ruby23
|
10
|
+
|
11
|
+
executors:
|
12
|
+
ruby26:
|
13
|
+
docker:
|
14
|
+
- image: circleci/ruby:2.6
|
15
|
+
ruby25:
|
16
|
+
docker:
|
17
|
+
- image: circleci/ruby:2.5
|
18
|
+
ruby24:
|
19
|
+
docker:
|
20
|
+
- image: circleci/ruby:2.4
|
21
|
+
ruby23:
|
22
|
+
docker:
|
23
|
+
- image: circleci/ruby:2.3
|
24
|
+
|
25
|
+
commands:
|
26
|
+
test:
|
27
|
+
steps:
|
28
|
+
- restore_cache:
|
29
|
+
keys:
|
30
|
+
- bundler-{{ checksum "Gemfile.lock" }}
|
31
|
+
|
32
|
+
- run:
|
33
|
+
name: Bundle Install
|
34
|
+
command: bundle check --path vendor/bundle || bundle install --deployment
|
35
|
+
|
36
|
+
- save_cache:
|
37
|
+
key: bundler-{{ checksum "Gemfile.lock" }}
|
38
|
+
paths:
|
39
|
+
- vendor/bundle
|
40
|
+
|
41
|
+
- run:
|
42
|
+
name: Run rspec
|
43
|
+
command: |
|
44
|
+
bundle exec rspec --format documentation --format RspecJunitFormatter --out test_results/rspec.xml
|
45
|
+
|
46
|
+
jobs:
|
47
|
+
ruby26:
|
48
|
+
executor: ruby26
|
49
|
+
steps:
|
50
|
+
- checkout
|
51
|
+
- test
|
52
|
+
|
53
|
+
- run:
|
54
|
+
name: Report Test Coverage
|
55
|
+
command: |
|
56
|
+
wget https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 -O cc-test-reporter
|
57
|
+
chmod +x cc-test-reporter
|
58
|
+
./cc-test-reporter format-coverage -t simplecov -o coverage/codeclimate.json coverage/.resultset.json
|
59
|
+
./cc-test-reporter upload-coverage -i coverage/codeclimate.json
|
60
|
+
|
61
|
+
- store_test_results:
|
62
|
+
path: test_results
|
63
|
+
|
64
|
+
ruby25:
|
65
|
+
executor: ruby25
|
66
|
+
steps:
|
67
|
+
- checkout
|
68
|
+
- test
|
69
|
+
|
70
|
+
ruby24:
|
71
|
+
executor: ruby24
|
72
|
+
steps:
|
73
|
+
- checkout
|
74
|
+
- test
|
75
|
+
|
76
|
+
ruby23:
|
77
|
+
executor: ruby23
|
78
|
+
steps:
|
79
|
+
- checkout
|
80
|
+
- test
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,56 +1,65 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rollout (2.4.
|
4
|
+
rollout (2.4.4)
|
5
|
+
redis (~> 4.0)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
9
|
-
|
10
|
-
bundler
|
11
|
-
rake
|
12
|
-
thor (>= 0.14.0)
|
13
|
-
codeclimate-test-reporter (1.0.8)
|
14
|
-
simplecov (<= 0.13)
|
10
|
+
ast (2.4.0)
|
15
11
|
diff-lcs (1.3)
|
16
|
-
docile (1.
|
17
|
-
fakeredis (0.
|
18
|
-
redis (
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rspec
|
27
|
-
rspec-
|
28
|
-
|
12
|
+
docile (1.3.2)
|
13
|
+
fakeredis (0.7.0)
|
14
|
+
redis (>= 3.2, < 5.0)
|
15
|
+
jaro_winkler (1.5.3)
|
16
|
+
json (2.2.0)
|
17
|
+
parallel (1.17.0)
|
18
|
+
parser (2.6.3.0)
|
19
|
+
ast (~> 2.4.0)
|
20
|
+
rainbow (3.0.0)
|
21
|
+
redis (4.1.2)
|
22
|
+
rspec (3.8.0)
|
23
|
+
rspec-core (~> 3.8.0)
|
24
|
+
rspec-expectations (~> 3.8.0)
|
25
|
+
rspec-mocks (~> 3.8.0)
|
26
|
+
rspec-core (3.8.2)
|
27
|
+
rspec-support (~> 3.8.0)
|
28
|
+
rspec-expectations (3.8.4)
|
29
29
|
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
-
rspec-support (~> 3.
|
31
|
-
rspec-mocks (3.
|
30
|
+
rspec-support (~> 3.8.0)
|
31
|
+
rspec-mocks (3.8.1)
|
32
32
|
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
-
rspec-support (~> 3.
|
34
|
-
rspec-support (3.
|
35
|
-
|
36
|
-
|
33
|
+
rspec-support (~> 3.8.0)
|
34
|
+
rspec-support (3.8.2)
|
35
|
+
rspec_junit_formatter (0.4.1)
|
36
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
37
|
+
rubocop (0.72.0)
|
38
|
+
jaro_winkler (~> 1.5.1)
|
39
|
+
parallel (~> 1.10)
|
40
|
+
parser (>= 2.6)
|
41
|
+
rainbow (>= 2.2.2, < 4.0)
|
42
|
+
ruby-progressbar (~> 1.7)
|
43
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
44
|
+
ruby-progressbar (1.10.1)
|
45
|
+
simplecov (0.16.1)
|
46
|
+
docile (~> 1.1)
|
37
47
|
json (>= 1.8, < 3)
|
38
48
|
simplecov-html (~> 0.10.0)
|
39
|
-
simplecov-html (0.10.
|
40
|
-
|
49
|
+
simplecov-html (0.10.2)
|
50
|
+
unicode-display_width (1.6.0)
|
41
51
|
|
42
52
|
PLATFORMS
|
43
53
|
ruby
|
44
54
|
|
45
55
|
DEPENDENCIES
|
46
|
-
|
47
|
-
bundler (>= 1.0.0)
|
48
|
-
codeclimate-test-reporter
|
56
|
+
bundler (~> 1.17)
|
49
57
|
fakeredis
|
50
|
-
redis
|
51
58
|
rollout!
|
52
|
-
rspec
|
53
|
-
|
59
|
+
rspec (~> 3.0)
|
60
|
+
rspec_junit_formatter (~> 0.4)
|
61
|
+
rubocop (~> 0.71)
|
62
|
+
simplecov (~> 0.16)
|
54
63
|
|
55
64
|
BUNDLED WITH
|
56
|
-
1.
|
65
|
+
1.17.2
|
data/README.md
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
Fast feature flags based on Redis.
|
4
4
|
|
5
|
-
[](https://badge.fury.io/rb/rollout)
|
6
|
+
[](https://circleci.com/gh/fetlife/rollout)
|
7
|
+
[](https://codeclimate.com/github/FetLife/rollout)
|
8
|
+
[](https://codeclimate.com/github/FetLife/rollout/coverage)
|
9
9
|
|
10
10
|
## Install it
|
11
11
|
|
@@ -20,7 +20,7 @@ Initialize a rollout object. I assign it to a global var.
|
|
20
20
|
```ruby
|
21
21
|
require 'redis'
|
22
22
|
|
23
|
-
$redis
|
23
|
+
$redis = Redis.new
|
24
24
|
$rollout = Rollout.new($redis)
|
25
25
|
```
|
26
26
|
|
@@ -71,6 +71,9 @@ Deactivate groups like this:
|
|
71
71
|
$rollout.deactivate_group(:chat, :all)
|
72
72
|
```
|
73
73
|
|
74
|
+
Groups need to be defined every time your app starts. The logic is not persisted
|
75
|
+
anywhere.
|
76
|
+
|
74
77
|
## Specific Users
|
75
78
|
|
76
79
|
You might want to let a specific user into a beta test or something. If that
|
@@ -98,7 +101,7 @@ $rollout.activate_percentage(:chat, 20)
|
|
98
101
|
The algorithm for determining which users get let in is this:
|
99
102
|
|
100
103
|
```ruby
|
101
|
-
CRC32(user.id)
|
104
|
+
CRC32(user.id) < (2**32 - 1) / 100.0 * percentage
|
102
105
|
```
|
103
106
|
|
104
107
|
So, for 20%, users 0, 1, 10, 11, 20, 21, etc would be allowed in. Those users
|
@@ -176,6 +179,7 @@ This example would use the "development:feature:chat:groups" key.
|
|
176
179
|
* Python: https://github.com/asenchi/proclaim
|
177
180
|
* PHP: https://github.com/opensoft/rollout
|
178
181
|
* Clojure: https://github.com/yeller/shoutout
|
182
|
+
* Perl: https://metacpan.org/pod/Toggle
|
179
183
|
|
180
184
|
|
181
185
|
## Contributors
|
data/Rakefile
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
require "rspec/core/rake_task"
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require 'rspec/core/rake_task'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task default: :spec
|
data/lib/rollout.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rollout/version'
|
4
|
+
require 'zlib'
|
5
|
+
require 'set'
|
6
|
+
require 'json'
|
5
7
|
|
6
8
|
class Rollout
|
7
9
|
RAND_BASE = (2**32 - 1) / 100.0
|
8
|
-
|
10
|
+
|
9
11
|
class Feature
|
10
12
|
attr_accessor :groups, :users, :percentage, :data
|
11
13
|
attr_reader :name, :options
|
@@ -15,7 +17,7 @@ class Rollout
|
|
15
17
|
@name = name
|
16
18
|
|
17
19
|
if string
|
18
|
-
raw_percentage,raw_users,raw_groups,raw_data = string.split('|', 4)
|
20
|
+
raw_percentage, raw_users, raw_groups, raw_data = string.split('|', 4)
|
19
21
|
@percentage = raw_percentage.to_f
|
20
22
|
@users = users_from_string(raw_users)
|
21
23
|
@groups = groups_from_string(raw_groups)
|
@@ -26,7 +28,7 @@ class Rollout
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def serialize
|
29
|
-
"#{@percentage}|#{@users.to_a.join(
|
31
|
+
"#{@percentage}|#{@users.to_a.join(',')}|#{@groups.to_a.join(',')}|#{serialize_data}"
|
30
32
|
end
|
31
33
|
|
32
34
|
def add_user(user)
|
@@ -47,8 +49,8 @@ class Rollout
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def clear
|
50
|
-
@groups = groups_from_string(
|
51
|
-
@users = users_from_string(
|
52
|
+
@groups = groups_from_string('')
|
53
|
+
@users = users_from_string('')
|
52
54
|
@percentage = 0
|
53
55
|
@data = {}
|
54
56
|
end
|
@@ -58,7 +60,7 @@ class Rollout
|
|
58
60
|
id = user_id(user)
|
59
61
|
user_in_percentage?(id) ||
|
60
62
|
user_in_active_users?(id) ||
|
61
|
-
|
63
|
+
user_in_active_group?(user, rollout)
|
62
64
|
else
|
63
65
|
@percentage == 100
|
64
66
|
end
|
@@ -77,65 +79,66 @@ class Rollout
|
|
77
79
|
end
|
78
80
|
|
79
81
|
private
|
80
|
-
def user_id(user)
|
81
|
-
if user.is_a?(Integer) || user.is_a?(String)
|
82
|
-
user.to_s
|
83
|
-
else
|
84
|
-
user.send(id_user_by).to_s
|
85
|
-
end
|
86
|
-
end
|
87
82
|
|
88
|
-
|
89
|
-
|
83
|
+
def user_id(user)
|
84
|
+
if user.is_a?(Integer) || user.is_a?(String)
|
85
|
+
user.to_s
|
86
|
+
else
|
87
|
+
user.send(id_user_by).to_s
|
90
88
|
end
|
89
|
+
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
def id_user_by
|
92
|
+
@options[:id_user_by] || :id
|
93
|
+
end
|
94
|
+
|
95
|
+
def user_in_percentage?(user)
|
96
|
+
Zlib.crc32(user_id_for_percentage(user)) < RAND_BASE * @percentage
|
97
|
+
end
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
99
|
+
def user_id_for_percentage(user)
|
100
|
+
if @options[:randomize_percentage]
|
101
|
+
user_id(user).to_s + @name.to_s
|
102
|
+
else
|
103
|
+
user_id(user)
|
102
104
|
end
|
105
|
+
end
|
103
106
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
107
|
+
def user_in_active_group?(user, rollout)
|
108
|
+
@groups.any? do |g|
|
109
|
+
rollout.active_in_group?(g, user)
|
108
110
|
end
|
111
|
+
end
|
109
112
|
|
110
|
-
|
111
|
-
|
113
|
+
def serialize_data
|
114
|
+
return '' unless @data.is_a? Hash
|
112
115
|
|
113
|
-
|
114
|
-
|
116
|
+
@data.to_json
|
117
|
+
end
|
115
118
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
119
|
+
def users_from_string(raw_users)
|
120
|
+
users = (raw_users || '').split(',').map(&:to_s)
|
121
|
+
if @options[:use_sets]
|
122
|
+
users.to_set
|
123
|
+
else
|
124
|
+
users
|
123
125
|
end
|
126
|
+
end
|
124
127
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
128
|
+
def groups_from_string(raw_groups)
|
129
|
+
groups = (raw_groups || '').split(',').map(&:to_sym)
|
130
|
+
if @options[:use_sets]
|
131
|
+
groups.to_set
|
132
|
+
else
|
133
|
+
groups
|
132
134
|
end
|
135
|
+
end
|
133
136
|
end
|
134
137
|
|
135
138
|
def initialize(storage, opts = {})
|
136
139
|
@storage = storage
|
137
140
|
@options = opts
|
138
|
-
@groups = { all:
|
141
|
+
@groups = { all: ->(_user) { true } }
|
139
142
|
end
|
140
143
|
|
141
144
|
def activate(feature)
|
@@ -145,15 +148,13 @@ class Rollout
|
|
145
148
|
end
|
146
149
|
|
147
150
|
def deactivate(feature)
|
148
|
-
with_feature(feature)
|
149
|
-
f.clear
|
150
|
-
end
|
151
|
+
with_feature(feature, &:clear)
|
151
152
|
end
|
152
153
|
|
153
154
|
def delete(feature)
|
154
|
-
features = (@storage.get(features_key) ||
|
155
|
+
features = (@storage.get(features_key) || '').split(',')
|
155
156
|
features.delete(feature.to_s)
|
156
|
-
@storage.set(features_key, features.join(
|
157
|
+
@storage.set(features_key, features.join(','))
|
157
158
|
@storage.del(key(feature))
|
158
159
|
end
|
159
160
|
|
@@ -193,20 +194,20 @@ class Rollout
|
|
193
194
|
|
194
195
|
def activate_users(feature, users)
|
195
196
|
with_feature(feature) do |f|
|
196
|
-
users.each{|user| f.add_user(user)}
|
197
|
+
users.each { |user| f.add_user(user) }
|
197
198
|
end
|
198
199
|
end
|
199
200
|
|
200
201
|
def deactivate_users(feature, users)
|
201
202
|
with_feature(feature) do |f|
|
202
|
-
users.each{|user| f.remove_user(user)}
|
203
|
+
users.each { |user| f.remove_user(user) }
|
203
204
|
end
|
204
205
|
end
|
205
206
|
|
206
207
|
def set_users(feature, users)
|
207
208
|
with_feature(feature) do |f|
|
208
209
|
f.users = []
|
209
|
-
users.each{|user| f.add_user(user)}
|
210
|
+
users.each { |user| f.add_user(user) }
|
210
211
|
end
|
211
212
|
end
|
212
213
|
|
@@ -242,7 +243,7 @@ class Rollout
|
|
242
243
|
|
243
244
|
def active_in_group?(group, user)
|
244
245
|
f = @groups[group.to_sym]
|
245
|
-
f
|
246
|
+
f&.call(user)
|
246
247
|
end
|
247
248
|
|
248
249
|
def get(feature)
|
@@ -263,29 +264,29 @@ class Rollout
|
|
263
264
|
end
|
264
265
|
|
265
266
|
def multi_get(*features)
|
266
|
-
feature_keys = features.map{ |feature| key(feature) }
|
267
|
+
feature_keys = features.map { |feature| key(feature) }
|
267
268
|
@storage.mget(*feature_keys).map.with_index { |string, index| Feature.new(features[index], string, @options) }
|
268
269
|
end
|
269
270
|
|
270
271
|
def features
|
271
|
-
(@storage.get(features_key) ||
|
272
|
+
(@storage.get(features_key) || '').split(',').map(&:to_sym)
|
272
273
|
end
|
273
274
|
|
274
275
|
def feature_states(user = nil)
|
275
|
-
features.each_with_object({}) do |f, hash|
|
276
|
-
hash[f] = active?(
|
276
|
+
multi_get(*features).each_with_object({}) do |f, hash|
|
277
|
+
hash[f.name] = f.active?(self, user)
|
277
278
|
end
|
278
279
|
end
|
279
280
|
|
280
281
|
def active_features(user = nil)
|
281
|
-
features.select do |f|
|
282
|
-
active?(
|
283
|
-
end
|
282
|
+
multi_get(*features).select do |f|
|
283
|
+
f.active?(self, user)
|
284
|
+
end.map(&:name)
|
284
285
|
end
|
285
286
|
|
286
287
|
def clear!
|
287
288
|
features.each do |feature|
|
288
|
-
with_feature(feature
|
289
|
+
with_feature(feature, &:clear)
|
289
290
|
@storage.del(key(feature))
|
290
291
|
end
|
291
292
|
|
@@ -303,7 +304,7 @@ class Rollout
|
|
303
304
|
end
|
304
305
|
|
305
306
|
def features_key
|
306
|
-
|
307
|
+
'feature:__features__'
|
307
308
|
end
|
308
309
|
|
309
310
|
def with_feature(feature)
|
@@ -314,6 +315,6 @@ class Rollout
|
|
314
315
|
|
315
316
|
def save(feature)
|
316
317
|
@storage.set(key(feature.name), feature.serialize)
|
317
|
-
@storage.set(features_key, (features | [feature.name.to_sym]).join(
|
318
|
+
@storage.set(features_key, (features | [feature.name.to_sym]).join(','))
|
318
319
|
end
|
319
320
|
end
|
data/lib/rollout/version.rb
CHANGED
data/rollout.gemspec
CHANGED
@@ -1,27 +1,31 @@
|
|
1
|
-
#
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "rollout/version"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
s.version = Rollout::VERSION
|
8
|
-
s.authors = ["James Golick"]
|
9
|
-
s.email = ["jamesgolick@gmail.com"]
|
10
|
-
s.description = "Feature flippers with redis."
|
11
|
-
s.summary = "Feature flippers with redis."
|
12
|
-
s.homepage = "https://github.com/FetLife/rollout"
|
13
|
-
s.license = "MIT"
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
require 'rollout/version'
|
14
5
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rollout'
|
8
|
+
spec.version = Rollout::VERSION
|
9
|
+
spec.authors = ['James Golick']
|
10
|
+
spec.email = ['jamesgolick@gmail.com']
|
11
|
+
spec.description = 'Feature flippers with redis.'
|
12
|
+
spec.summary = 'Feature flippers with redis.'
|
13
|
+
spec.homepage = 'https://github.com/FetLife/rollout'
|
14
|
+
spec.license = 'MIT'
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.3'
|
22
|
+
|
23
|
+
spec.add_dependency 'redis', '~> 4.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.17'
|
26
|
+
spec.add_development_dependency 'fakeredis'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 0.71'
|
30
|
+
spec.add_development_dependency 'simplecov', '~> 0.16'
|
27
31
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require
|
5
|
-
require "rspec"
|
6
|
-
require ENV["USE_REAL_REDIS"] == "true" ? "redis" : "fakeredis"
|
3
|
+
require 'simplecov'
|
7
4
|
|
8
|
-
SimpleCov.start
|
9
|
-
formatter SimpleCov::Formatter::MultiFormatter.new([
|
10
|
-
SimpleCov::Formatter::HTMLFormatter,
|
11
|
-
])
|
12
|
-
end
|
5
|
+
SimpleCov.start
|
13
6
|
|
7
|
+
require 'bundler/setup'
|
8
|
+
require ENV["USE_REAL_REDIS"] == "true" ? "redis" : "fakeredis"
|
14
9
|
require "rollout"
|
15
10
|
|
16
11
|
RSpec.configure do |config|
|
12
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
13
|
+
|
14
|
+
# config.disable_monkey_patching!
|
15
|
+
|
16
|
+
config.expect_with :rspec do |c|
|
17
|
+
c.syntax = :expect
|
18
|
+
end
|
19
|
+
|
17
20
|
config.before { Redis.new.flushdb }
|
18
21
|
end
|
metadata
CHANGED
@@ -1,113 +1,113 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rollout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Golick
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.17'
|
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: '
|
40
|
+
version: '1.17'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: fakeredis
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '0'
|
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: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '3.0'
|
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: '0'
|
68
|
+
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rspec_junit_formatter
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '0.4'
|
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: '0'
|
82
|
+
version: '0.4'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '0.71'
|
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: '0'
|
96
|
+
version: '0.71'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
103
|
+
version: '0.16'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
110
|
+
version: '0.16'
|
111
111
|
description: Feature flippers with redis.
|
112
112
|
email:
|
113
113
|
- jamesgolick@gmail.com
|
@@ -115,18 +115,16 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
-
- ".
|
118
|
+
- ".circleci/config.yml"
|
119
119
|
- ".gitignore"
|
120
120
|
- ".rspec"
|
121
|
+
- ".rubocop.yml"
|
121
122
|
- ".travis.yml"
|
122
|
-
- Appraisals
|
123
123
|
- Gemfile
|
124
124
|
- Gemfile.lock
|
125
125
|
- LICENSE
|
126
126
|
- README.md
|
127
127
|
- Rakefile
|
128
|
-
- gemfiles/redis_3.gemfile
|
129
|
-
- gemfiles/redis_4.gemfile
|
130
128
|
- lib/rollout.rb
|
131
129
|
- lib/rollout/version.rb
|
132
130
|
- rollout.gemspec
|
@@ -144,15 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
142
|
requirements:
|
145
143
|
- - ">="
|
146
144
|
- !ruby/object:Gem::Version
|
147
|
-
version: '
|
145
|
+
version: '2.3'
|
148
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
147
|
requirements:
|
150
148
|
- - ">="
|
151
149
|
- !ruby/object:Gem::Version
|
152
150
|
version: '0'
|
153
151
|
requirements: []
|
154
|
-
|
155
|
-
rubygems_version: 2.6.12
|
152
|
+
rubygems_version: 3.0.3
|
156
153
|
signing_key:
|
157
154
|
specification_version: 4
|
158
155
|
summary: Feature flippers with redis.
|
data/.document
DELETED
data/Appraisals
DELETED
data/gemfiles/redis_3.gemfile
DELETED