rollout 2.4.3 → 2.4.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![
|
6
|
-
[![
|
7
|
-
[![
|
8
|
-
[![
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/rollout.svg)](https://badge.fury.io/rb/rollout)
|
6
|
+
[![CircleCI](https://circleci.com/gh/fetlife/rollout.svg?style=svg)](https://circleci.com/gh/fetlife/rollout)
|
7
|
+
[![Code Climate](https://codeclimate.com/github/FetLife/rollout/badges/gpa.svg)](https://codeclimate.com/github/FetLife/rollout)
|
8
|
+
[![Test Coverage](https://codeclimate.com/github/FetLife/rollout/badges/coverage.svg)](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