flipper 0.20.4 → 0.21.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +9 -1
- data/Changelog.md +11 -1
- data/Gemfile +1 -0
- data/README.md +68 -42
- data/docs/Adapters.md +1 -0
- data/docs/Gates.md +74 -74
- data/examples/basic.rb +1 -12
- data/examples/configuring_default.rb +1 -2
- data/examples/dsl.rb +13 -24
- data/examples/enabled_for_actor.rb +8 -15
- data/examples/group.rb +3 -6
- data/examples/group_dynamic_lookup.rb +5 -19
- data/examples/group_with_members.rb +4 -14
- data/examples/importing.rb +1 -1
- data/examples/individual_actor.rb +2 -5
- data/examples/instrumentation.rb +1 -2
- data/examples/memoizing.rb +1 -2
- data/examples/percentage_of_actors.rb +6 -16
- data/examples/percentage_of_actors_enabled_check.rb +7 -10
- data/examples/percentage_of_actors_group.rb +5 -18
- data/examples/percentage_of_time.rb +3 -6
- data/lib/flipper.rb +1 -0
- data/lib/flipper/configuration.rb +6 -6
- data/lib/flipper/errors.rb +2 -3
- data/lib/flipper/identifier.rb +17 -0
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/configuration_spec.rb +5 -2
- data/spec/flipper/identifier_spec.rb +14 -0
- data/spec/flipper/middleware/memoizer_spec.rb +1 -1
- data/spec/flipper/middleware/setup_env_spec.rb +0 -16
- data/spec/flipper_spec.rb +0 -1
- data/spec/support/spec_helpers.rb +3 -0
- data/test/test_helper.rb +1 -0
- metadata +7 -5
- data/examples/example_setup.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04567e721e7189ed3a5a28c91833caa438e89c8dc412708c1d5487ebcf43e09e
|
4
|
+
data.tar.gz: c31948ae275a36a986352ae8d53e858d63e67590a1cae3831013530446008608
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30e3b27356e2a24948cb4136c59be5a7a0d0b21631102999affa01c3e969dc037e6ff524df3da4ffc0c39ecd8ffbbb1798bda4593fca21f33aeebefb0236caff
|
7
|
+
data.tar.gz: 7cb046ca418ff31219b9d786cd22c0f81de6c37c9efc38a718e9ddcf2c97027de0d1a351ddeeae1a24adf1db081dcb364e0751f4d2881ef126e2a98ff0212b63
|
data/.github/workflows/ci.yml
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
name: CI
|
2
|
-
on:
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches: [master]
|
5
|
+
pull_request:
|
3
6
|
jobs:
|
4
7
|
build:
|
5
8
|
runs-on: ubuntu-latest
|
@@ -19,6 +22,7 @@ jobs:
|
|
19
22
|
RAILS_VERSION: 6.0.0
|
20
23
|
SQLITE3_VERSION: 1.4.1
|
21
24
|
REDIS_URL: redis://localhost:6379/0
|
25
|
+
CI: true
|
22
26
|
steps:
|
23
27
|
- name: Setup memcached
|
24
28
|
uses: KeisukeYamashita/memcached-actions@v1
|
@@ -47,3 +51,7 @@ jobs:
|
|
47
51
|
run: bundle install --jobs 4 --retry 3
|
48
52
|
- name: Run Rake
|
49
53
|
run: bundle exec rake
|
54
|
+
- name: Run Examples
|
55
|
+
env:
|
56
|
+
FLIPPER_CLOUD_TOKEN: ${{ secrets.FLIPPER_CLOUD_TOKEN }}
|
57
|
+
run: script/examples
|
data/Changelog.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
##
|
1
|
+
## 0.21.0
|
2
|
+
|
3
|
+
### Additions/Changes
|
4
|
+
|
5
|
+
* Default to using memory adapter (https://github.com/jnunemaker/flipper/pull/501)
|
6
|
+
* Adapters now configured on require when possible (https://github.com/jnunemaker/flipper/pull/502)
|
7
|
+
* Added cloud recommendation to flipper-ui. Can be disabled with `Flipper::UI.configure { |config| config.cloud_recommendation = false }`. Just want to raise awareness that more is available if people want it (https://github.com/jnunemaker/flipper/pull/504)
|
8
|
+
* Added default `flipper_id` implementation via `Flipper::Identifier` and automatically included it in ActiveRecord and Sequel models (https://github.com/jnunemaker/flipper/pull/505)
|
9
|
+
* Deprecate superflous sync_method setting (https://github.com/jnunemaker/flipper/pull/511)
|
10
|
+
|
11
|
+
## 0.20.4
|
2
12
|
|
3
13
|
### Additions/Changes
|
4
14
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,14 @@
|
|
2
2
|
|
3
3
|
# Flipper
|
4
4
|
|
5
|
-
Beautiful, performant feature flags for Ruby.
|
5
|
+
> Beautiful, performant feature flags for Ruby.
|
6
|
+
|
7
|
+
Flipper gives you control over who has access to features in your app.
|
8
|
+
|
9
|
+
* Enable or disable features for everyone, specific actors, groups of actors, a percentage of actors, or a percentage of time.
|
10
|
+
* Configure your feature flags from the console or a web UI.
|
11
|
+
* Regardless of what data store you are using, Flipper can performantly store your feature flags.
|
12
|
+
* Use [Flipper Cloud](#flipper-cloud) to cascade features from multiple environments, share settings with your team, control permissions, keep an audit history, and rollback.
|
6
13
|
|
7
14
|
Control your software — don't let it control you.
|
8
15
|
|
@@ -12,6 +19,10 @@ Add this line to your application's Gemfile:
|
|
12
19
|
|
13
20
|
gem 'flipper'
|
14
21
|
|
22
|
+
You'll also want to pick a storage [adapter](#adapters), for example:
|
23
|
+
|
24
|
+
gem 'flipper-active_record'`
|
25
|
+
|
15
26
|
And then execute:
|
16
27
|
|
17
28
|
$ bundle
|
@@ -22,9 +33,62 @@ Or install it yourself with:
|
|
22
33
|
|
23
34
|
## Getting Started
|
24
35
|
|
36
|
+
Use `Flipper#enabled?` in your app to check if a feature is enabled.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# check if search is enabled
|
40
|
+
if Flipper.enabled? :search, current_user
|
41
|
+
puts 'Search away!'
|
42
|
+
else
|
43
|
+
puts 'No search for you!'
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
All features are disabled by default, so you'll need to explicitly enable them.
|
48
|
+
|
49
|
+
#### Enable a feature for everyone
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Flipper.enable :search
|
53
|
+
```
|
54
|
+
|
55
|
+
#### Enable a feature for a specific actor
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
Flipper.enable_actor :search, current_user
|
59
|
+
```
|
60
|
+
|
61
|
+
#### Enable a feature for a group of actors
|
62
|
+
|
63
|
+
First tell Flipper about your groups:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
# config/initializers/flipper.rb
|
67
|
+
Flipper.register(:admin) do |actor|
|
68
|
+
actor.respond_to?(:admin?) && actor.admin?
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
Then enable the feature for that group:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Flipper.enable_group :search, :admin
|
76
|
+
```
|
77
|
+
|
78
|
+
#### Enable a feature for a percentage of actors
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Flipper.enable_percentage_of_actors :search, 2
|
82
|
+
```
|
83
|
+
|
84
|
+
|
85
|
+
Read more about enabling and disabling features with [Gates](docs/Gates.md). Check out the [examples directory](examples/) for more, and take a peek at the [DSL](lib/flipper/dsl.rb) and [Feature](lib/flipper/feature.rb) classes for code/docs.
|
86
|
+
|
87
|
+
## Adapters
|
88
|
+
|
25
89
|
Flipper is built on adapters for maximum flexibility. Regardless of what data store you are using, Flipper can performantly store data in it.
|
26
90
|
|
27
|
-
|
91
|
+
Pick one of our [supported adapters](docs/Adapters.md#officially-supported) and follow the installation instructions:
|
28
92
|
|
29
93
|
* [Active Record](docs/active_record/README.md)
|
30
94
|
* [Sequel](docs/sequel/README.md)
|
@@ -35,7 +99,7 @@ To get started, pick one of our [supported adapters](docs/Adapters.md#officially
|
|
35
99
|
|
36
100
|
Or [roll your own](docs/Adapters.md#roll-your-own). We even provide automatic (rspec and minitest) tests for you, so you know you've built your custom adapter correctly.
|
37
101
|
|
38
|
-
|
102
|
+
Read more about [Adapters](docs/Adapters.md).
|
39
103
|
|
40
104
|
## Flipper UI
|
41
105
|
|
@@ -63,50 +127,12 @@ Or, (even better than OSS + UI) use [Flipper Cloud](https://www.flippercloud.io)
|
|
63
127
|
|
64
128
|
Cloud is super simple to integrate with Rails ([demo app](https://github.com/fewerandfaster/flipper-rails-demo)), Sinatra or any other framework.
|
65
129
|
|
66
|
-
##
|
67
|
-
|
68
|
-
Want to get a quick feel for what it looks like to work with Flipper? Check out the following example or the [examples directory](examples/). You might also want to peek at the [DSL](lib/flipper/dsl.rb) and [Feature](lib/flipper/feature.rb) classes for code/docs.
|
69
|
-
|
70
|
-
```ruby
|
71
|
-
require 'flipper'
|
72
|
-
|
73
|
-
Flipper.configure do |config|
|
74
|
-
config.default do
|
75
|
-
# pick an adapter, this uses memory, any will do, see docs above
|
76
|
-
adapter = Flipper::Adapters::Memory.new
|
77
|
-
|
78
|
-
# pass adapter to handy DSL instance
|
79
|
-
Flipper.new(adapter)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# check if search is enabled
|
84
|
-
if Flipper.enabled?(:search)
|
85
|
-
puts 'Search away!'
|
86
|
-
else
|
87
|
-
puts 'No search for you!'
|
88
|
-
end
|
89
|
-
|
90
|
-
puts 'Enabling Search...'
|
91
|
-
Flipper.enable(:search)
|
92
|
-
|
93
|
-
# check if search is enabled
|
94
|
-
if Flipper.enabled?(:search)
|
95
|
-
puts 'Search away!'
|
96
|
-
else
|
97
|
-
puts 'No search for you!'
|
98
|
-
end
|
99
|
-
```
|
100
|
-
|
101
|
-
## Docs
|
130
|
+
## Advanced
|
102
131
|
|
103
132
|
A few miscellaneous docs with more info for the hungry.
|
104
133
|
|
105
|
-
* [Gates](docs/Gates.md) - Boolean, Groups, Actors, % of Actors, and % of Time
|
106
|
-
* [Adapters](docs/Adapters.md) - Mongo, Redis, Cassandra, Active Record...
|
107
134
|
* [Instrumentation](docs/Instrumentation.md) - ActiveSupport::Notifications and Statsd
|
108
135
|
* [Optimization](docs/Optimization.md) - Memoization middleware and Cache adapters
|
109
|
-
* [Web Interface](docs/ui/README.md) - Point and click...
|
110
136
|
* [API](docs/api/README.md) - HTTP API interface
|
111
137
|
* [Caveats](docs/Caveats.md) - Flipper beware! (see what I did there)
|
112
138
|
* [Docker-Compose](docs/DockerCompose.md) - Using docker-compose in contributing
|
data/docs/Adapters.md
CHANGED
@@ -14,6 +14,7 @@ I plan on supporting the adapters in the flipper repo. Other adapters are welcom
|
|
14
14
|
* [PStore adapter](https://github.com/jnunemaker/flipper/blob/master/lib/flipper/adapters/pstore.rb) – great for when a local file is enough
|
15
15
|
* [read-only adapter](https://github.com/jnunemaker/flipper/blob/master/docs/read-only)
|
16
16
|
* [Redis adapter](https://github.com/jnunemaker/flipper/blob/master/docs/redis)
|
17
|
+
* [Rollout adapter](rollout/README.md)
|
17
18
|
* [Sequel adapter](https://github.com/jnunemaker/flipper/blob/master/docs/sequel)
|
18
19
|
|
19
20
|
## Community Supported
|
data/docs/Gates.md
CHANGED
@@ -7,76 +7,82 @@ Out of the box several types of enabling are supported. They are checked in this
|
|
7
7
|
All on or all off. Think top level things like `:stats`, `:search`, `:logging`, etc. Also, an easy way to release a new feature as once a feature is boolean enabled it is on for every situation.
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
flipper[:stats].enabled? # check
|
10
|
+
Flipper.enable :stats # turn on
|
11
|
+
Flipper.disable :stats # turn off
|
12
|
+
Flipper.enabled? :stats # check
|
14
13
|
```
|
15
14
|
|
16
15
|
## 2. Individual Actor
|
17
16
|
|
18
|
-
Turn feature on for individual thing. Think enable feature for someone to test or for a buddy.
|
17
|
+
Turn feature on for individual thing. Think enable feature for someone to test or for a buddy.
|
19
18
|
|
20
19
|
```ruby
|
21
|
-
|
20
|
+
Flipper.enable_actor :stats, user
|
21
|
+
Flipper.enabled? :stats, user # true
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
flipper[:stats].disable user
|
27
|
-
flipper[:stats].enabled? user # false
|
23
|
+
Flipper.disable_actor :stats, user
|
24
|
+
Flipper.enabled? :stats, user # false
|
28
25
|
|
29
26
|
# you can enable anything, does not need to be user or person
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# you can also use shortcut methods
|
34
|
-
flipper.enable_actor :search, user
|
35
|
-
flipper.disable_actor :search, user
|
36
|
-
flipper[:search].enable_actor user
|
37
|
-
flipper[:search].disable_actor user
|
38
|
-
```
|
27
|
+
Flipper.enable_actor :search, organization
|
28
|
+
Flipper.enabled? :search, organization
|
39
29
|
|
40
|
-
|
30
|
+
# you can also save a reference to a specific feature
|
31
|
+
feature = Flipper[:search]
|
32
|
+
|
33
|
+
feature.enable_actor user
|
34
|
+
feature.enabled? user # true
|
35
|
+
feature.disable_actor user
|
36
|
+
```
|
41
37
|
|
42
|
-
The
|
38
|
+
The only requirement for an individual actor is that it must have a unique `flipper_id`. Include the `Flipper::Identifier` module for a default implementation which combines the class name and `id` (e.g. `User;6`).
|
43
39
|
|
44
40
|
```ruby
|
45
|
-
class User
|
46
|
-
|
47
|
-
"User;#{id}"
|
48
|
-
end
|
41
|
+
class User < Struct.new(:id)
|
42
|
+
include Flipper::Identifier
|
49
43
|
end
|
50
44
|
|
51
|
-
|
45
|
+
User.new(5).flipper_id # => "User;5"
|
46
|
+
```
|
47
|
+
|
48
|
+
You can also define your own implementation:
|
49
|
+
|
50
|
+
```
|
51
|
+
class Organization < Struct.new(:uuid)
|
52
52
|
def flipper_id
|
53
|
-
|
53
|
+
uuid
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
Organization.new("DEB3D850-39FB-444B-A1E9-404A990FDBE0").flipper_id
|
58
|
+
# => "DEB3D850-39FB-444B-A1E9-404A990FDBE0"
|
56
59
|
```
|
57
60
|
|
61
|
+
Just make sure each type of object has a unique `flipper_id`.
|
62
|
+
|
58
63
|
## 3. Percentage of Actors
|
59
64
|
|
60
65
|
Turn this on for a percentage of actors (think user, member, account, group, whatever). Consistently on or off for this user as long as percentage increases. Think slow rollout of a new feature to a percentage of things.
|
61
66
|
|
62
67
|
```ruby
|
63
|
-
flipper = Flipper.new(adapter)
|
64
|
-
|
65
|
-
# returns a percentage of actors instance set to 10
|
66
|
-
percentage = flipper.actors(10)
|
67
|
-
|
68
68
|
# turn stats on for 10 percent of users in the system
|
69
|
-
|
69
|
+
Flipper.enable :stats, Flipper.actors(10)
|
70
|
+
# or
|
71
|
+
Flipper.enable_percentage_of_actors :stats, 10
|
70
72
|
|
71
73
|
# checks if actor's flipper_id is in the enabled percentage by hashing
|
72
74
|
# user.flipper_id.to_s to ensure enabled distribution is smooth
|
73
|
-
|
75
|
+
Flipper.enabled? :stats, user
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
Flipper.disable_percentage_of_actors :search # sets to 0
|
78
|
+
# or
|
79
|
+
Flipper.disable :stats, Flipper.actors(0)
|
80
|
+
|
81
|
+
# you can also save a reference to a specific feature
|
82
|
+
feature = Flipper[:search]
|
83
|
+
feature.enable_percentage_of_actors 10
|
84
|
+
feature.enabled? user
|
85
|
+
feature.disable_percentage_of_actors # sets to 0
|
80
86
|
```
|
81
87
|
|
82
88
|
## 4. Percentage of Time
|
@@ -84,22 +90,20 @@ flipper[:search].disable_percentage_of_actors # sets to 0
|
|
84
90
|
Turn this on for a percentage of time. Think load testing new features behind the scenes and such.
|
85
91
|
|
86
92
|
```ruby
|
87
|
-
flipper = Flipper.new(adapter)
|
88
|
-
|
89
|
-
# get percentage of time instance set to 5
|
90
|
-
percentage = flipper.time(5)
|
91
|
-
|
92
93
|
# Register a feature called logging and turn it on for 5 percent of the time.
|
93
94
|
# This could be on during one request and off the next
|
94
95
|
# could even be on first time in request and off second time
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
96
|
+
Flipper.enable_percentage_of_time :logging, 5
|
97
|
+
|
98
|
+
Flipper.enabled? :logging # this will return true 5% of the time.
|
99
|
+
|
100
|
+
Flipper.disable_percentage_of_time :logging # sets to 0
|
101
|
+
|
102
|
+
# you can also save a reference to a specific feature
|
103
|
+
feature = Flipper[:search]
|
104
|
+
feature.enable_percentage_of_time, 5
|
105
|
+
feature.enabled?
|
106
|
+
feature.disable_percentage_of_time
|
103
107
|
```
|
104
108
|
|
105
109
|
Timeness is not a good idea for enabling new features in the UI. Most of the time you want a feature on or off for a user, but there are definitely times when I have found percentage of time to be very useful.
|
@@ -114,52 +118,48 @@ Flipper.register(:admins) do |actor|
|
|
114
118
|
actor.respond_to?(:admin?) && actor.admin?
|
115
119
|
end
|
116
120
|
|
117
|
-
|
118
|
-
|
119
|
-
flipper[:stats].enable flipper.group(:admins) # This registers a stats feature and turns it on for admins (which is anything that returns true from the registered block).
|
120
|
-
flipper[:stats].disable flipper.group(:admins) # turn off the stats feature for admins
|
121
|
+
Flipper.enable_group :stats, :admins # This registers a stats feature and turns it on for admins (which is anything that returns true from the registered block).
|
122
|
+
Flipper.disable_group :stats, :admins # turn off the stats feature for admins
|
121
123
|
|
122
124
|
person = Person.find(params[:id])
|
123
|
-
|
125
|
+
Flipper.enabled? :stats, person # check if enabled, returns true if person.admin? is true
|
124
126
|
|
125
|
-
# you can also use shortcut methods. This also registers a stats feature and turns it on for admins.
|
126
|
-
flipper.enable_group :stats, :admins
|
127
|
-
person = Person.find(params[:id])
|
128
|
-
flipper[:stats].enabled? person # same as above. check if enabled, returns true if person.admin? is true
|
129
127
|
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
# you can also use shortcut methods. This also registers a stats feature and turns it on for admins.
|
129
|
+
feature = Flipper[:search]
|
130
|
+
feature.enable_group :admins
|
131
|
+
feature.enabled? person
|
132
|
+
feature.disable_group :admins
|
133
133
|
```
|
134
134
|
|
135
135
|
Here's a quick explanation of the above code block:
|
136
136
|
|
137
|
-
```
|
137
|
+
```ruby
|
138
138
|
Flipper.register(:admins) do |actor|
|
139
139
|
actor.respond_to?(:admin?) && actor.admin?
|
140
140
|
end
|
141
141
|
```
|
142
|
-
- The above first registers a group called `admins` which essentially saves a [Proc](http://www.eriktrautman.com/posts/ruby-explained-blocks-procs-and-lambdas-aka-closures) to be called later. The `actor` is an instance of the `Flipper::Types::Actor` that wraps the thing being checked against and `actor.thing` is the original object being checked.
|
142
|
+
- The above first registers a group called `admins` which essentially saves a [Proc](http://www.eriktrautman.com/posts/ruby-explained-blocks-procs-and-lambdas-aka-closures) to be called later. The `actor` is an instance of the `Flipper::Types::Actor` that wraps the thing being checked against and `actor.thing` is the original object being checked.
|
143
143
|
|
144
|
-
```
|
145
|
-
|
144
|
+
```ruby
|
145
|
+
Flipper.enable_group :stats, :admins
|
146
146
|
```
|
147
147
|
|
148
148
|
- The above enables the stats feature to any object that returns true from the `:admins` proc.
|
149
149
|
|
150
|
-
```
|
150
|
+
```ruby
|
151
151
|
person = Person.find(params[:id])
|
152
|
-
|
152
|
+
Flipper.enabled? :stats, person # check if person is enabled, returns true if person.admin? is true
|
153
153
|
```
|
154
154
|
|
155
|
-
When the `person` object is passed to the `enabled?` method, it is then passed into the proc. If the proc returns true, the entire statement returns true and so `
|
155
|
+
When the `person` object is passed to the `enabled?` method, it is then passed into the proc. If the proc returns true, the entire statement returns true and so `Flipper[:stats].enabled? person` returns true. Whatever logic follows this conditional check is then executed.
|
156
156
|
|
157
157
|
There is no requirement that the thing yielded to the block be a user model or whatever. It can be anything you want, therefore it is a good idea to check that the thing passed into the group block actually responds to what you are trying to do in the `register` proc.
|
158
158
|
|
159
159
|
In your application code, you can do something like this now:
|
160
160
|
|
161
|
-
```
|
162
|
-
if
|
161
|
+
```ruby
|
162
|
+
if Flipper.enabled? :stats, some_admin
|
163
163
|
# do thing...
|
164
164
|
else
|
165
165
|
# do not do thing
|
data/examples/basic.rb
CHANGED
@@ -1,17 +1,6 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
Flipper.configure do |config|
|
6
|
-
config.default do
|
7
|
-
# pick an adapter, this uses memory, any will do
|
8
|
-
adapter = Flipper::Adapters::Memory.new
|
9
|
-
|
10
|
-
# pass adapter to handy DSL instance
|
11
|
-
Flipper.new(adapter)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
4
|
# check if search is enabled
|
16
5
|
if Flipper.enabled?(:search)
|
17
6
|
puts 'Search away!'
|
data/examples/dsl.rb
CHANGED
@@ -1,20 +1,9 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
adapter = Flipper::Adapters::Memory.new
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
|
8
4
|
# create a thing with an identifier
|
9
|
-
class Person
|
10
|
-
|
11
|
-
|
12
|
-
def initialize(id)
|
13
|
-
@id = id
|
14
|
-
end
|
15
|
-
|
16
|
-
# Must respond to flipper_id
|
17
|
-
alias_method :flipper_id, :id
|
5
|
+
class Person < Struct.new(:id)
|
6
|
+
include Flipper::Identifier
|
18
7
|
end
|
19
8
|
|
20
9
|
person = Person.new(1)
|
@@ -22,14 +11,14 @@ person = Person.new(1)
|
|
22
11
|
puts "Stats are disabled by default\n\n"
|
23
12
|
|
24
13
|
# is a feature enabled
|
25
|
-
puts "flipper.enabled? :stats: #{
|
14
|
+
puts "flipper.enabled? :stats: #{Flipper.enabled? :stats}"
|
26
15
|
|
27
16
|
# is a feature on or off for a particular person
|
28
|
-
puts "
|
17
|
+
puts "Flipper.enabled? :stats, person: #{Flipper.enabled? :stats, person}"
|
29
18
|
|
30
19
|
# get at a feature
|
31
|
-
puts "\nYou can also get an individual feature like this:\nstats =
|
32
|
-
stats =
|
20
|
+
puts "\nYou can also get an individual feature like this:\nstats = Flipper[:stats]\n\n"
|
21
|
+
stats = Flipper[:stats]
|
33
22
|
|
34
23
|
# is that feature enabled
|
35
24
|
puts "stats.enabled?: #{stats.enabled?}"
|
@@ -39,7 +28,7 @@ puts "stats.enabled? person: #{stats.enabled? person}"
|
|
39
28
|
|
40
29
|
# enable a feature by name
|
41
30
|
puts "\nEnabling stats\n\n"
|
42
|
-
|
31
|
+
Flipper.enable :stats
|
43
32
|
|
44
33
|
# or, you can use the feature to enable
|
45
34
|
stats.enable
|
@@ -49,7 +38,7 @@ puts "stats.enabled? person: #{stats.enabled? person}"
|
|
49
38
|
|
50
39
|
# oh, no, let's turn this baby off
|
51
40
|
puts "\nDisabling stats\n\n"
|
52
|
-
|
41
|
+
Flipper.disable :stats
|
53
42
|
|
54
43
|
# or we can disable using feature obviously
|
55
44
|
stats.disable
|
@@ -59,18 +48,18 @@ puts "stats.enabled? person: #{stats.enabled? person}"
|
|
59
48
|
puts
|
60
49
|
|
61
50
|
# get an instance of the percentage of time type set to 5
|
62
|
-
puts
|
51
|
+
puts Flipper.time(5).inspect
|
63
52
|
|
64
53
|
# get an instance of the percentage of actors type set to 15
|
65
|
-
puts
|
54
|
+
puts Flipper.actors(15).inspect
|
66
55
|
|
67
56
|
# get an instance of an actor using an object that responds to flipper_id
|
68
57
|
responds_to_flipper_id = Struct.new(:flipper_id).new(10)
|
69
|
-
puts
|
58
|
+
puts Flipper.actor(responds_to_flipper_id).inspect
|
70
59
|
|
71
60
|
# get an instance of an actor using an object
|
72
61
|
thing = Struct.new(:flipper_id).new(22)
|
73
|
-
puts
|
62
|
+
puts Flipper.actor(thing).inspect
|
74
63
|
|
75
64
|
# register a top level group
|
76
65
|
admins = Flipper.register(:admins) { |actor|
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
4
|
# Some class that represents what will be trying to do something
|
@@ -22,21 +21,15 @@ end
|
|
22
21
|
user1 = User.new(1, true)
|
23
22
|
user2 = User.new(2, false)
|
24
23
|
|
25
|
-
# pick an adapter
|
26
|
-
adapter = Flipper::Adapters::Memory.new
|
27
|
-
|
28
|
-
# get a handy dsl instance
|
29
|
-
flipper = Flipper.new(adapter)
|
30
|
-
|
31
24
|
Flipper.register :admins do |actor|
|
32
25
|
actor.admin?
|
33
26
|
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
Flipper.enable :search
|
29
|
+
Flipper.enable_actor :stats, user1
|
30
|
+
Flipper.enable_percentage_of_actors :pro_stats, 50
|
31
|
+
Flipper.enable_group :tweets, :admins
|
32
|
+
Flipper.enable_actor :posts, user2
|
40
33
|
|
41
|
-
pp
|
42
|
-
pp
|
34
|
+
pp Flipper.features.select { |feature| feature.enabled?(user1) }.map(&:name)
|
35
|
+
pp Flipper.features.select { |feature| feature.enabled?(user2) }.map(&:name)
|
data/examples/group.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
stats = flipper[:stats]
|
4
|
+
stats = Flipper[:stats]
|
8
5
|
|
9
6
|
# Register group
|
10
7
|
Flipper.register(:admins) do |actor|
|
@@ -35,7 +32,7 @@ puts "Stats for admin: #{stats.enabled?(admin)}"
|
|
35
32
|
puts "Stats for non_admin: #{stats.enabled?(non_admin)}"
|
36
33
|
|
37
34
|
puts "\nEnabling Stats for admins...\n\n"
|
38
|
-
stats.
|
35
|
+
stats.enable_group :admins
|
39
36
|
|
40
37
|
puts "Stats for admin: #{stats.enabled?(admin)}"
|
41
38
|
puts "Stats for non_admin: #{stats.enabled?(non_admin)}"
|
@@ -1,10 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
stats = flipper[:stats]
|
4
|
+
stats = Flipper[:stats]
|
8
5
|
|
9
6
|
# Register group
|
10
7
|
Flipper.register(:enabled_team_member) do |actor, context|
|
@@ -15,19 +12,12 @@ Flipper.register(:enabled_team_member) do |actor, context|
|
|
15
12
|
end
|
16
13
|
|
17
14
|
# Some class that represents actor that will be trying to do something
|
18
|
-
class User
|
19
|
-
|
20
|
-
|
21
|
-
def initialize(id)
|
22
|
-
@id = id
|
23
|
-
end
|
24
|
-
|
25
|
-
def flipper_id
|
26
|
-
"User;#{@id}"
|
27
|
-
end
|
15
|
+
class User < Struct.new(:id)
|
16
|
+
include Flipper::Identifier
|
28
17
|
end
|
29
18
|
|
30
19
|
class Team
|
20
|
+
include Flipper::Identifier
|
31
21
|
attr_reader :name
|
32
22
|
|
33
23
|
def self.all
|
@@ -51,10 +41,6 @@ class Team
|
|
51
41
|
def member?(actor)
|
52
42
|
@members.map(&:id).include?(actor.id)
|
53
43
|
end
|
54
|
-
|
55
|
-
def flipper_id
|
56
|
-
"Team:#{@name}"
|
57
|
-
end
|
58
44
|
end
|
59
45
|
|
60
46
|
jnunemaker = User.new("jnunemaker")
|
@@ -1,10 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
stats = flipper[:stats]
|
4
|
+
stats = Flipper[:stats]
|
8
5
|
|
9
6
|
# Register group
|
10
7
|
Flipper.register(:team_actor) do |actor|
|
@@ -12,15 +9,8 @@ Flipper.register(:team_actor) do |actor|
|
|
12
9
|
end
|
13
10
|
|
14
11
|
# Some class that represents actor that will be trying to do something
|
15
|
-
class User
|
16
|
-
|
17
|
-
|
18
|
-
def initialize(id)
|
19
|
-
@id = id
|
20
|
-
end
|
21
|
-
|
22
|
-
# Must respond to flipper_id
|
23
|
-
alias_method :flipper_id, :id
|
12
|
+
class User < Struct.new(:id)
|
13
|
+
include Flipper::Identifier
|
24
14
|
end
|
25
15
|
|
26
16
|
class Team
|
data/examples/importing.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
stats = flipper[:stats]
|
4
|
+
stats = Flipper[:stats]
|
8
5
|
|
9
6
|
# Some class that represents what will be trying to do something
|
10
7
|
class User
|
data/examples/instrumentation.rb
CHANGED
data/examples/memoizing.rb
CHANGED
@@ -1,21 +1,11 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
stats = flipper[:stats]
|
4
|
+
stats = Flipper[:stats]
|
8
5
|
|
9
6
|
# Some class that represents what will be trying to do something
|
10
|
-
class User
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(id)
|
14
|
-
@id = id
|
15
|
-
end
|
16
|
-
|
17
|
-
# Must respond to flipper_id
|
18
|
-
alias_method :flipper_id, :id
|
7
|
+
class User < Struct.new(:id)
|
8
|
+
include Flipper::Identifier
|
19
9
|
end
|
20
10
|
|
21
11
|
total = 100_000
|
@@ -24,10 +14,10 @@ total = 100_000
|
|
24
14
|
users = (1..total).map { |n| User.new(n) }
|
25
15
|
|
26
16
|
perform_test = lambda { |number|
|
27
|
-
|
17
|
+
Flipper.enable_percentage_of_actors :stats, number
|
28
18
|
|
29
19
|
enabled = users.map { |user|
|
30
|
-
|
20
|
+
Flipper.enabled?(:stats, user) ? true : nil
|
31
21
|
}.compact
|
32
22
|
|
33
23
|
actual = (enabled.size / total.to_f * 100).round(3)
|
@@ -1,10 +1,6 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
adapter = Flipper::Adapters::Memory.new
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
|
8
4
|
# Some class that represents what will be trying to do something
|
9
5
|
class User
|
10
6
|
attr_reader :id
|
@@ -18,15 +14,16 @@ class User
|
|
18
14
|
end
|
19
15
|
|
20
16
|
# checking a bunch
|
21
|
-
gate = Flipper::Gates::PercentageOfActors.new
|
22
|
-
feature_name = "data_migration"
|
23
|
-
percentage_enabled = 10
|
24
17
|
total = 20_000
|
25
18
|
enabled = []
|
19
|
+
percentage_enabled = 10
|
20
|
+
|
21
|
+
feature = Flipper[:data_migration]
|
22
|
+
feature.enable_percentage_of_actors 10
|
26
23
|
|
27
24
|
(1..total).each do |id|
|
28
25
|
user = User.new(id)
|
29
|
-
if
|
26
|
+
if feature.enabled? user
|
30
27
|
enabled << user
|
31
28
|
end
|
32
29
|
end
|
@@ -35,4 +32,4 @@ p actual: enabled.size, expected: total * (percentage_enabled * 0.01)
|
|
35
32
|
|
36
33
|
# checking one
|
37
34
|
user = User.new(1)
|
38
|
-
p user_1_enabled:
|
35
|
+
p user_1_enabled: feature.enabled?(user)
|
@@ -3,25 +3,12 @@
|
|
3
3
|
# feature for actors in a particular location or on a particular plan, but only
|
4
4
|
# for a percentage of them. The percentage is a constant, but could easily be
|
5
5
|
# plucked from memcached, redis, mysql or whatever.
|
6
|
-
require
|
6
|
+
require 'bundler/setup'
|
7
7
|
require 'flipper'
|
8
8
|
|
9
|
-
adapter = Flipper::Adapters::Memory.new
|
10
|
-
flipper = Flipper.new(adapter)
|
11
|
-
stats = flipper[:stats]
|
12
|
-
|
13
9
|
# Some class that represents what will be trying to do something
|
14
|
-
class User
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(id)
|
18
|
-
@id = id
|
19
|
-
end
|
20
|
-
|
21
|
-
# Must respond to flipper_id
|
22
|
-
def flipper_id
|
23
|
-
"User;#{@id}"
|
24
|
-
end
|
10
|
+
class User < Struct.new(:id)
|
11
|
+
include Flipper::Identifier
|
25
12
|
end
|
26
13
|
|
27
14
|
PERCENTAGE = 50
|
@@ -34,13 +21,13 @@ Flipper.register(:experimental) do |actor|
|
|
34
21
|
end
|
35
22
|
|
36
23
|
# enable the experimental group
|
37
|
-
|
24
|
+
Flipper.enable_group :stats, :experimental
|
38
25
|
|
39
26
|
# create a bunch of fake users and see how many are enabled
|
40
27
|
total = 10_000
|
41
28
|
users = (1..total).map { |n| User.new(n) }
|
42
29
|
enabled = users.map { |user|
|
43
|
-
|
30
|
+
Flipper.enabled?(:stats, user) ? true : nil
|
44
31
|
}.compact
|
45
32
|
|
46
33
|
# show the results
|
@@ -1,13 +1,10 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/setup'
|
3
2
|
require 'flipper'
|
4
3
|
|
5
|
-
|
6
|
-
flipper = Flipper.new(adapter)
|
7
|
-
logging = flipper[:logging]
|
4
|
+
logging = Flipper[:logging]
|
8
5
|
|
9
6
|
perform_test = lambda do |number|
|
10
|
-
logging.
|
7
|
+
logging.enable_percentage_of_time number
|
11
8
|
|
12
9
|
total = 100_000
|
13
10
|
enabled = []
|
data/lib/flipper.rb
CHANGED
@@ -152,6 +152,7 @@ require 'flipper/feature'
|
|
152
152
|
require 'flipper/gate'
|
153
153
|
require 'flipper/instrumenters/memory'
|
154
154
|
require 'flipper/instrumenters/noop'
|
155
|
+
require 'flipper/identifier'
|
155
156
|
require 'flipper/middleware/memoizer'
|
156
157
|
require 'flipper/middleware/setup_env'
|
157
158
|
require 'flipper/registry'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Flipper
|
2
2
|
class Configuration
|
3
3
|
def initialize
|
4
|
-
@default = -> {
|
4
|
+
@default = -> { Flipper.new(Flipper::Adapters::Memory.new) }
|
5
5
|
end
|
6
6
|
|
7
7
|
# Controls the default instance for flipper. When used with a block it
|
@@ -9,15 +9,15 @@ module Flipper
|
|
9
9
|
# without a block, it performs a block invocation and returns the result.
|
10
10
|
#
|
11
11
|
# configuration = Flipper::Configuration.new
|
12
|
-
# configuration.default # =>
|
12
|
+
# configuration.default # => Flipper::DSL instance using Memory adapter
|
13
13
|
#
|
14
|
-
# # sets the default block to generate a new instance using
|
14
|
+
# # sets the default block to generate a new instance using ActiveRecord adapter
|
15
15
|
# configuration.default do
|
16
|
-
# require "flipper
|
17
|
-
# Flipper.new(Flipper::Adapters::
|
16
|
+
# require "flipper-active_record"
|
17
|
+
# Flipper.new(Flipper::Adapters::ActiveRecord.new)
|
18
18
|
# end
|
19
19
|
#
|
20
|
-
# configuration.default # => Flipper::DSL instance using
|
20
|
+
# configuration.default # => Flipper::DSL instance using ActiveRecord adapter
|
21
21
|
#
|
22
22
|
# Returns result of default block invocation if called without block. If
|
23
23
|
# called with block, assigns the default block.
|
data/lib/flipper/errors.rb
CHANGED
@@ -16,9 +16,8 @@ module Flipper
|
|
16
16
|
# use it.
|
17
17
|
class DefaultNotSet < Flipper::Error
|
18
18
|
def initialize(message = nil)
|
19
|
-
|
20
|
-
|
21
|
-
super(message || default)
|
19
|
+
warn "Flipper::DefaultNotSet is deprecated and will be removed in 1.0"
|
20
|
+
super
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Flipper
|
2
|
+
# A default implementation of `#flipper_id` for actors.
|
3
|
+
#
|
4
|
+
# class User < Struct.new(:id)
|
5
|
+
# include Flipper::Identifier
|
6
|
+
# end
|
7
|
+
#
|
8
|
+
# user = User.new(99)
|
9
|
+
# Flipper.enable :thing, user
|
10
|
+
# Flipper.enabled? :thing, user #=> true
|
11
|
+
#
|
12
|
+
module Identifier
|
13
|
+
def flipper_id
|
14
|
+
"#{self.class.name};#{id}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/flipper/version.rb
CHANGED
@@ -3,12 +3,15 @@ require 'flipper/configuration'
|
|
3
3
|
|
4
4
|
RSpec.describe Flipper::Configuration do
|
5
5
|
describe '#default' do
|
6
|
-
it '
|
7
|
-
expect
|
6
|
+
it 'returns instance using Memory adapter' do
|
7
|
+
expect(subject.default).to be_a(Flipper::DSL)
|
8
|
+
# All adapter are wrapped in Memoizable
|
9
|
+
expect(subject.default.adapter.adapter).to be_a(Flipper::Adapters::Memory)
|
8
10
|
end
|
9
11
|
|
10
12
|
it 'can be set default' do
|
11
13
|
instance = Flipper.new(Flipper::Adapters::Memory.new)
|
14
|
+
expect(subject.default).not_to be(instance)
|
12
15
|
subject.default { instance }
|
13
16
|
expect(subject.default).to be(instance)
|
14
17
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/identifier'
|
3
|
+
|
4
|
+
RSpec.describe Flipper::Identifier do
|
5
|
+
describe '#flipper_id' do
|
6
|
+
class User < Struct.new(:id)
|
7
|
+
include Flipper::Identifier
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'uses class name and id' do
|
11
|
+
expect(User.new(5).flipper_id).to eq('User;5')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -342,7 +342,7 @@ RSpec.describe Flipper::Middleware::Memoizer do
|
|
342
342
|
it 'eagerly caches known features for duration of request' do
|
343
343
|
memory = Flipper::Adapters::Memory.new
|
344
344
|
logged_memory = Flipper::Adapters::OperationLogger.new(memory)
|
345
|
-
cache = ActiveSupport::Cache::
|
345
|
+
cache = ActiveSupport::Cache::MemoryStore.new
|
346
346
|
cache.clear
|
347
347
|
cached = Flipper::Adapters::ActiveSupportCacheStore.new(logged_memory, cache, expires_in: 10)
|
348
348
|
logged_cached = Flipper::Adapters::OperationLogger.new(cached)
|
@@ -93,20 +93,4 @@ RSpec.describe Flipper::Middleware::SetupEnv do
|
|
93
93
|
expect(last_response.body).to eq(Flipper.object_id.to_s)
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
97
|
-
context 'when flipper instance or block are nil and default Flipper is NOT configured' do
|
98
|
-
let(:app) do
|
99
|
-
app = lambda do |env|
|
100
|
-
[200, { 'Content-Type' => 'text/html' }, [env['flipper'].enabled?(:search)]]
|
101
|
-
end
|
102
|
-
builder = Rack::Builder.new
|
103
|
-
builder.use described_class
|
104
|
-
builder.run app
|
105
|
-
builder
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'can use env flipper' do
|
109
|
-
expect { get '/' }.to raise_error(Flipper::DefaultNotSet)
|
110
|
-
end
|
111
|
-
end
|
112
96
|
end
|
data/spec/flipper_spec.rb
CHANGED
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -41,7 +41,6 @@ files:
|
|
41
41
|
- examples/configuring_default.rb
|
42
42
|
- examples/dsl.rb
|
43
43
|
- examples/enabled_for_actor.rb
|
44
|
-
- examples/example_setup.rb
|
45
44
|
- examples/group.rb
|
46
45
|
- examples/group_dynamic_lookup.rb
|
47
46
|
- examples/group_with_members.rb
|
@@ -83,6 +82,7 @@ files:
|
|
83
82
|
- lib/flipper/gates/group.rb
|
84
83
|
- lib/flipper/gates/percentage_of_actors.rb
|
85
84
|
- lib/flipper/gates/percentage_of_time.rb
|
85
|
+
- lib/flipper/identifier.rb
|
86
86
|
- lib/flipper/instrumentation/log_subscriber.rb
|
87
87
|
- lib/flipper/instrumentation/statsd.rb
|
88
88
|
- lib/flipper/instrumentation/statsd_subscriber.rb
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- spec/flipper/gates/group_spec.rb
|
131
131
|
- spec/flipper/gates/percentage_of_actors_spec.rb
|
132
132
|
- spec/flipper/gates/percentage_of_time_spec.rb
|
133
|
+
- spec/flipper/identifier_spec.rb
|
133
134
|
- spec/flipper/instrumentation/log_subscriber_spec.rb
|
134
135
|
- spec/flipper/instrumentation/statsd_subscriber_spec.rb
|
135
136
|
- spec/flipper/instrumenters/memory_spec.rb
|
@@ -170,9 +171,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
171
|
version: '0'
|
171
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
173
|
requirements:
|
173
|
-
- - "
|
174
|
+
- - ">"
|
174
175
|
- !ruby/object:Gem::Version
|
175
|
-
version:
|
176
|
+
version: 1.3.1
|
176
177
|
requirements: []
|
177
178
|
rubygems_version: 3.0.3
|
178
179
|
signing_key:
|
@@ -205,6 +206,7 @@ test_files:
|
|
205
206
|
- spec/flipper/gates/group_spec.rb
|
206
207
|
- spec/flipper/gates/percentage_of_actors_spec.rb
|
207
208
|
- spec/flipper/gates/percentage_of_time_spec.rb
|
209
|
+
- spec/flipper/identifier_spec.rb
|
208
210
|
- spec/flipper/instrumentation/log_subscriber_spec.rb
|
209
211
|
- spec/flipper/instrumentation/statsd_subscriber_spec.rb
|
210
212
|
- spec/flipper/instrumenters/memory_spec.rb
|
data/examples/example_setup.rb
DELETED