flipper 0.16.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 49607173763cd256cdb8f6a9ef1ada1fb213092a
4
- data.tar.gz: 123bcd59f941d0a4673526132bab358c75ada4ae
2
+ SHA256:
3
+ metadata.gz: 60a4f0efac1116f4a9c4f0aeb899cd9104dcccf6578691ba639e047a23b77fe0
4
+ data.tar.gz: 270782a3c6d8021e8efa4b926fd0dfbe49613f1b47793d4783e15667cddb58e3
5
5
  SHA512:
6
- metadata.gz: bf6951c97102685c5222c8b096133857b0a7a3251190cd3e6cf8885b0260463c341b8bb9f02e100e2ea2f541999ff6c7c53e6d4f73abed1cea09c8327f70acd4
7
- data.tar.gz: 10ecb72720e4b8a58956d025351118810baa6c20c82ec629ea6c5117b870cf2ef499958ba6efd6e924ecfadc86776a73be66a11c200251e39d08c64897452c72
6
+ metadata.gz: 10f4d755b8f3f9137cdf3868ddc3277177e4dea8d27e1125449c3bfc25afe3350dc4a4a6c97f71f26db8cc180357221686fcc737a1e60ce29edb6adbb60a5cc5
7
+ data.tar.gz: cd5b0bf940e4ff2dbede6c82c7ea2d30ab44fb9ec4917032df3b36b6c7c390c587494a6c334c36fa0498cf83162562afcecb44a12e2373ec8ebf0a3e941d525d
@@ -1,3 +1,65 @@
1
+ ## 0.18.0
2
+
3
+ ## Additions/Changes
4
+
5
+ * Add support for feature descriptions to flipper-ui (https://github.com/jnunemaker/flipper/pull/461).
6
+ * Remove rubocop (https://github.com/jnunemaker/flipper/pull/469).
7
+ * flipper-ui redesign (https://github.com/jnunemaker/flipper/pull/470).
8
+ * Removed support for ruby 2.4.
9
+ * Added support for ruby 2.7.
10
+ * Removed support for Rails 4.x.x.
11
+ * Removed support for customizing actors, groups, % of actors and % of time text in flipper-ui in favor of automatic and more descriptive text.
12
+
13
+ ## 0.17.2
14
+
15
+ ### Additions/Changes
16
+
17
+ * Avoid errors on import when there are no features and shared specs/tests for get all with no features (https://github.com/jnunemaker/flipper/pull/441 and https://github.com/jnunemaker/flipper/pull/442)
18
+ * ::ActiveRecord::RecordNotUnique > ActiveRecord::RecordNotUnique (https://github.com/jnunemaker/flipper/pull/444)
19
+ * Clear gate values on enable (https://github.com/jnunemaker/flipper/pull/454)
20
+ * Remove use of multi from redis adapter (https://github.com/jnunemaker/flipper/pull/451)
21
+
22
+ ## 0.17.1
23
+
24
+ * Fix require in flipper-active_record (https://github.com/jnunemaker/flipper/pull/437)
25
+
26
+ ## 0.17.0
27
+
28
+ ### Additions/Changes
29
+
30
+ * Allow shorthand block notation on group types (https://github.com/jnunemaker/flipper/pull/406)
31
+ * Relax active record/support constraints to support Rails 6 (https://github.com/jnunemaker/flipper/pull/409)
32
+ * Allow disabling fun (https://github.com/jnunemaker/flipper/pull/413)
33
+ * Include thing_value in payload of Instrumented#enable and #disable (https://github.com/jnunemaker/flipper/pull/417)
34
+ * Replace Erubis with Erubi (https://github.com/jnunemaker/flipper/pull/407)
35
+ * Allow customizing Rack::Protection middleware list (https://github.com/jnunemaker/flipper/pull/385)
36
+ * Allow setting write_timeout for ruby 2.6+ (https://github.com/jnunemaker/flipper/pull/433)
37
+ * Drop support for Ruby 2.1, 2.2, and 2.3 (https://github.com/jnunemaker/flipper/commit/cf58982e70de5e6963b018ceced4f36a275f5b5d)
38
+ * Add support for Ruby 2.6 (https://github.com/jnunemaker/flipper/commit/57888311449ec81184d3d47ba9ae5cb1ad4a2f45)
39
+ * Remove support for Rails 3.2 (https://github.com/jnunemaker/flipper/commit/177c48c4edf51d4e411e7c673e30e06d1c66fb40)
40
+ * Add write_timeout for flipper http adapter for ruby 2.6+ (https://github.com/jnunemaker/flipper/pull/433)
41
+ * Relax moneta version to allow for < 1.2 (https://github.com/jnunemaker/flipper/pull/434).
42
+ * Improve active record idempotency (https://github.com/jnunemaker/flipper/pull/436).
43
+ * Allow customizing add actor placeholder text (https://github.com/jnunemaker/flipper/commit/5faa1e9cf66b68f8227d2f8408fb448a14676c45)
44
+
45
+ ## 0.16.2
46
+
47
+ ### Additions/Changes
48
+
49
+ * Bump rollout redis dependency to < 5 (https://github.com/jnunemaker/flipper/pull/403)
50
+ * Bump redis dependency to < 5 (https://github.com/jnunemaker/flipper/pull/401)
51
+ * Bump sequel dependency to < 6 (https://github.com/jnunemaker/flipper/pull/399 and https://github.com/jnunemaker/flipper/commit/edc767e69b4ce8daead9801f38e0e8bf6b238765)
52
+
53
+ ## 0.16.1
54
+
55
+ ### Additions/Changes
56
+
57
+ * Add actors API endpoint (https://github.com/jnunemaker/flipper/pull/372).
58
+ * Fix rack body proxy require for those using flipper without rack (https://github.com/jnunemaker/flipper/pull/376).
59
+ * Unescapes feature_name in FeatureNameFromRoute (https://github.com/jnunemaker/flipper/pull/377).
60
+ * Replace delete_all with destroy_all in ActiveRecord adapter (https://github.com/jnunemaker/flipper/pull/395)
61
+ * Target correct bootstrap breakpoints in flipper UI (https://github.com/jnunemaker/flipper/pull/396)
62
+
1
63
  ## 0.16.0
2
64
 
3
65
  ### Bug Fixes
@@ -40,7 +102,7 @@
40
102
 
41
103
  ### Additions/Changes
42
104
 
43
- * Added rollout adapter documentation (https://github.com/jnunemaker/flipper/pull/328).
105
+ * Added rollout adapter documentation (https://github.com/jnunemaker/flipper/pull/328).
44
106
 
45
107
  ### Bug Fixes
46
108
 
@@ -174,8 +236,8 @@
174
236
 
175
237
  * Added Flipper.groups and Flipper.group_names
176
238
  * Changed percentage_of_random to percentage_of_time
177
- * Added enable/disable convenience methods for all gates (ie: enable_group, enable_actor, enable_percentage_of_actors, enable_percentage_of_time)
178
- * Added value convenience methods (ie: boolean_value, groups_value, actors_value, etc.)
239
+ * Added enable/disable convenience methods for all gates (enable_group, enable_actor, enable_percentage_of_actors, enable_percentage_of_time)
240
+ * Added value convenience methods (boolean_value, groups_value, actors_value, etc.)
179
241
  * Added Feature#gate_values for getting typecast adapter gate values
180
242
  * Added Feature#enabled_gates and #disabled_gates for getting the gates that are enabled/disabled for the feature
181
243
  * Remove Feature#description
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.2.5
1
+ FROM ruby:2.5
2
2
 
3
3
  RUN apt-get update && apt-get install -y \
4
4
  # build-essential \
data/Gemfile CHANGED
@@ -7,27 +7,20 @@ Dir['flipper-*.gemspec'].each do |gemspec|
7
7
  end
8
8
 
9
9
  gem 'pry'
10
- gem 'rake', '~> 10.4.2'
10
+ gem 'rake', '~> 12.3.3'
11
11
  gem 'shotgun', '~> 0.9'
12
12
  gem 'statsd-ruby', '~> 1.2.1'
13
13
  gem 'rspec', '~> 3.0'
14
14
  gem 'rack-test', '~> 0.6.3'
15
- gem 'sqlite3', '~> 1.3.11'
16
- gem 'rails', "~> #{ENV['RAILS_VERSION'] || '5.1.4'}"
17
- gem 'minitest', '~> 5.8.0'
18
- gem 'rubocop', '~> 0.45.0'
19
- gem 'rubocop-rspec', '= 1.5.1'
20
- gem 'webmock', '~> 2.0'
21
-
22
- # for active support tests in test/ and only needed for ruby 2.2.x
23
- gem 'test-unit', '~> 3.0'
15
+ gem 'sqlite3', "~> #{ENV['SQLITE3_VERSION'] || '1.4.1'}"
16
+ gem 'rails', "~> #{ENV['RAILS_VERSION'] || '6.0.0'}"
17
+ gem 'minitest', '~> 5.8'
18
+ gem 'minitest-documentation'
19
+ gem 'webmock', '~> 3.0'
24
20
 
25
21
  group(:guard) do
26
- gem 'guard', '~> 2.12.5'
27
- gem 'guard-rubocop', '~> 1.3.0'
28
- gem 'guard-rspec', '~> 4.5.0'
29
- gem 'guard-bundler', '~> 2.1.0'
30
- gem 'guard-coffeescript', '~> 2.0.1'
31
- gem 'guard-sass', '~> 1.6.0'
32
- gem 'rb-fsevent', '~> 0.9.4'
22
+ gem 'guard', '~> 2.15'
23
+ gem 'guard-rspec', '~> 4.5'
24
+ gem 'guard-bundler', '~> 2.2'
25
+ gem 'rb-fsevent', '~> 0.9'
33
26
  end
data/README.md CHANGED
@@ -85,7 +85,7 @@ Of course there are more [examples for you to peruse](examples/). You could also
85
85
 
86
86
  1. Fork it
87
87
  2. Create your feature branch (`git checkout -b my-new-feature`)
88
- 3. Check your changes with Rubocop tests (`script/rubocop`)
88
+ 3. Run the tests (`bundle exec rake`)
89
89
  4. Commit your changes (`git commit -am 'Added some feature'`)
90
90
  5. Push to the branch (`git push origin my-new-feature`)
91
91
  6. Create new Pull Request
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ end
25
25
 
26
26
  require 'rspec/core/rake_task'
27
27
  RSpec::Core::RakeTask.new(:spec) do |t|
28
- t.rspec_opts = %w(--color)
28
+ t.rspec_opts = %w(--color --format documentation)
29
29
  end
30
30
 
31
31
  namespace :spec do
@@ -39,6 +39,14 @@ end
39
39
  Rake::TestTask.new do |t|
40
40
  t.libs = %w(lib test)
41
41
  t.pattern = 'test/**/*_test.rb'
42
+ t.options = '--documentation'
43
+ t.warning = false
42
44
  end
43
45
 
44
- task default: [:spec, :test]
46
+ Rake::TestTask.new(:test_rails) do |t|
47
+ t.libs = %w(lib test_rails)
48
+ t.pattern = 'test_rails/**/*_test.rb'
49
+ t.warning = false
50
+ end
51
+
52
+ task default: [:spec, :test, :test_rails]
@@ -4,7 +4,7 @@ I plan on supporting the adapters in the flipper repo. Other adapters are welcom
4
4
 
5
5
  ## Officially Supported
6
6
 
7
- * [ActiveRecord adapter](https://github.com/jnunemaker/flipper/blob/master/docs/active_record) - Rails 3, 4, and 5.
7
+ * [ActiveRecord adapter](https://github.com/jnunemaker/flipper/blob/master/docs/active_record) - Rails 3, 4, 5, and 6.
8
8
  * [ActiveSupportCacheStore adapter](https://github.com/jnunemaker/flipper/blob/master/docs/active_support_cache_store) - ActiveSupport::Cache::Store
9
9
  * [Cassanity adapter](https://github.com/jnunemaker/flipper-cassanity)
10
10
  * [Http adapter](https://github.com/jnunemaker/flipper/blob/master/docs/http)
@@ -1,4 +1,4 @@
1
1
  # Caveats
2
2
 
3
- 1. The [individual actor gate](https://github.com/jnunemaker/flipper/blob/master/docs/Gates.md#3-individual-actor) is typically not designed for hundreds or thousands of actors to be enabled. This is an explicit choice to make it easier to batch load data from the adapters instead of performing individual checks for actors over and over. If you need to enable something for more than 20 individual people, I would recommend using a [group](https://github.com/jnunemaker/flipper/blob/master/docs/Gates.md#2-group).
3
+ 1. The [individual actor gate](https://github.com/jnunemaker/flipper/blob/master/docs/Gates.md#2-individual-actor) is typically not designed for hundreds or thousands of actors to be enabled. This is an explicit choice to make it easier to batch load data from the adapters instead of performing individual checks for actors over and over. If you need to enable something for more than 20 individual people, I would recommend using a [group](https://github.com/jnunemaker/flipper/blob/master/docs/Gates.md#5-group).
4
4
  2. The disable method exists only to clear something that is enabled. If the thing you are disabling is not enabled, the disable is pointless. This means that if you enable one group an actor is in and disable another group, the feature will be enabled for the actor. ([related issue](https://github.com/jnunemaker/flipper/issues/71))
@@ -11,7 +11,6 @@ new contributor could start working on code with a minumum efforts.
11
11
  1. Install gems `docker-compose run --rm app bundle install`
12
12
  1. Run specs `docker-compose run --rm app bundle exec rspec`
13
13
  1. Run tests `docker-compose run --rm app bundle exec rake test`
14
- 1. Clear and check files with Rubocop `docker-compose run --rm app bundle exec rubocop -D`
15
14
  1. Optional: log in to container an using a `bash` shell for running specs
16
15
  ```sh
17
16
  docker-compose run --rm app bash
@@ -13,69 +13,7 @@ flipper[:stats].disable # turn off
13
13
  flipper[:stats].enabled? # check
14
14
  ```
15
15
 
16
- ## 2. Group
17
-
18
- Turn on feature based on the return value of block. Super flexible way to turn on a feature for multiple things (users, people, accounts, etc.) as long as the thing returns true when passed to the block.
19
-
20
- ```ruby
21
- # this registers a group
22
- Flipper.register(:admins) do |actor|
23
- actor.respond_to?(:admin?) && actor.admin?
24
- end
25
-
26
- flipper = Flipper.new(adapter)
27
-
28
- 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).
29
- flipper[:stats].disable flipper.group(:admins) # turn off the stats feature for admins
30
-
31
- person = Person.find(params[:id])
32
- flipper[:stats].enabled? person # check if enabled, returns true if person.admin? is true
33
-
34
- # you can also use shortcut methods. This also registers a stats feature and turns it on for admins.
35
- flipper.enable_group :stats, :admins
36
- person = Person.find(params[:id])
37
- flipper[:stats].enabled? person # same as above. check if enabled, returns true if person.admin? is true
38
-
39
- flipper.disable_group :stats, :admins
40
- flipper[:stats].enable_group :admins
41
- flipper[:stats].disable_group :admins
42
- ```
43
-
44
- Here's a quick explanation of the above code block:
45
-
46
- ```
47
- Flipper.register(:admins) do |actor|
48
- actor.respond_to?(:admin?) && actor.admin?
49
- end
50
- ```
51
- - 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.
52
-
53
- ```
54
- flipper[:stats].enable flipper.group(:admins)
55
- ```
56
-
57
- - The above enables the stats feature to any object that returns true from the `:admins` proc.
58
-
59
- ```
60
- person = Person.find(params[:id])
61
- flipper[:stats].enabled? person # check if person is enabled, returns true if person.admin? is true
62
- ```
63
-
64
- 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.
65
-
66
- 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.
67
-
68
- In your application code, you can do something like this now:
69
-
70
- ```
71
- if flipper[:stats].enabled?(some_admin)
72
- # do thing...
73
- else
74
- # do not do thing
75
- end
76
- ```
77
-
78
- ## 3. Individual Actor
16
+ ## 2. Individual Actor
79
17
 
80
18
  Turn feature on for individual thing. Think enable feature for someone to test or for a buddy. The only requirement for an individual actor is that it must respond to `flipper_id`.
81
19
 
@@ -117,7 +55,7 @@ class Group
117
55
  end
118
56
  ```
119
57
 
120
- ## 4. Percentage of Actors
58
+ ## 3. Percentage of Actors
121
59
 
122
60
  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.
123
61
 
@@ -141,7 +79,7 @@ flipper[:search].enable_percentage_of_actors 10
141
79
  flipper[:search].disable_percentage_of_actors # sets to 0
142
80
  ```
143
81
 
144
- ## 5. Percentage of Time
82
+ ## 4. Percentage of Time
145
83
 
146
84
  Turn this on for a percentage of time. Think load testing new features behind the scenes and such.
147
85
 
@@ -158,10 +96,72 @@ flipper[:logging].enable percentage
158
96
  flipper[:logging].enabled? # this will return true 5% of the time.
159
97
 
160
98
  # you can also use shortcut methods
161
- flipper.enable_percentage_of_time :search, 5 # registers a feature called "enable_percentage_of_time" and enables it 5% of the time
99
+ flipper.enable_percentage_of_time :search, 5 # registers a feature called "search" and enables it 5% of the time
162
100
  flipper.disable_percentage_of_time :search # sets to 0
163
101
  flipper[:search].enable_percentage_of_time 5
164
102
  flipper[:search].disable_percentage_of_time # sets to 0
165
103
  ```
166
104
 
167
105
  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.
106
+
107
+ ## 5. Group
108
+
109
+ Turn on feature based on the return value of block. Super flexible way to turn on a feature for multiple things (users, people, accounts, etc.) as long as the thing returns true when passed to the block.
110
+
111
+ ```ruby
112
+ # this registers a group
113
+ Flipper.register(:admins) do |actor|
114
+ actor.respond_to?(:admin?) && actor.admin?
115
+ end
116
+
117
+ flipper = Flipper.new(adapter)
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
+
122
+ person = Person.find(params[:id])
123
+ flipper[:stats].enabled? person # check if enabled, returns true if person.admin? is true
124
+
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
+
130
+ flipper.disable_group :stats, :admins
131
+ flipper[:stats].enable_group :admins
132
+ flipper[:stats].disable_group :admins
133
+ ```
134
+
135
+ Here's a quick explanation of the above code block:
136
+
137
+ ```
138
+ Flipper.register(:admins) do |actor|
139
+ actor.respond_to?(:admin?) && actor.admin?
140
+ end
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.
143
+
144
+ ```
145
+ flipper[:stats].enable flipper.group(:admins)
146
+ ```
147
+
148
+ - The above enables the stats feature to any object that returns true from the `:admins` proc.
149
+
150
+ ```
151
+ person = Person.find(params[:id])
152
+ flipper[:stats].enabled? person # check if person is enabled, returns true if person.admin? is true
153
+ ```
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 `flipper[:stats].enabled? person` returns true. Whatever logic follows this conditional check is then executed.
156
+
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
+
159
+ In your application code, you can do something like this now:
160
+
161
+ ```
162
+ if flipper[:stats].enabled?(some_admin)
163
+ # do thing...
164
+ else
165
+ # do not do thing
166
+ end
167
+ ```
@@ -527,7 +527,7 @@ Successful enabling of the actor will return a 200 HTTP status and the feature o
527
527
  {
528
528
  "key": "actors",
529
529
  "name": "actor",
530
- "value": ["User:1"]
530
+ "value": ["User;1"]
531
531
  },
532
532
  {
533
533
  "key": "percentage_of_actors",
@@ -815,6 +815,41 @@ Successful disabling of a percentage of time will set the percentage to 0 and re
815
815
  }
816
816
  ```
817
817
 
818
+ ### Check if features are enabled for an actor
819
+
820
+ **URL**
821
+
822
+ `GET /actors/{flipper_id}`
823
+
824
+ **Parameters**
825
+
826
+ * `keys` - comma-separated list of features to check
827
+
828
+ **Request**
829
+
830
+ ```
831
+ curl -X GET http://example.com/flipper/api/actors/User;1?keys=my_feature_1,my_feature_2
832
+ ```
833
+
834
+ **Response**
835
+
836
+ Returns whether the actor with the provided flipper_id is enabled for the specififed feature keys.
837
+ If no keys are specified all features are returned.
838
+
839
+ ```json
840
+ {
841
+ "flipper_id": "User;1",
842
+ "features": {
843
+ "my_feature_1": {
844
+ "enabled": true,
845
+ },
846
+ "my_feature_2": {
847
+ "enabled": false,
848
+ }
849
+ }
850
+ }
851
+ ```
852
+
818
853
  ## Errors
819
854
  In the event of an error the Flipper API will return an error object. The error object will contain a Flipper-specific error code, an error message, and a link to documentation providing more information about the error.
820
855
 
@@ -25,7 +25,6 @@ Gem::Specification.new do |gem|
25
25
  gem.authors = ['John Nunemaker']
26
26
  gem.email = ['nunemaker@gmail.com']
27
27
  gem.summary = 'Feature flipper for ANYTHING'
28
- gem.description = 'Feature flipper is the act of enabling/disabling features in your application, ideally without re-deploying or changing anything in your code base. Flipper makes this extremely easy to do with any backend you would like to use.'
29
28
  gem.homepage = 'https://github.com/jnunemaker/flipper'
30
29
  gem.license = 'MIT'
31
30
 
@@ -1,7 +1,7 @@
1
1
  require "forwardable"
2
2
 
3
3
  module Flipper
4
- extend self # rubocop:disable Style/ModuleFunction
4
+ extend self
5
5
  extend Forwardable
6
6
 
7
7
  # Private: The namespace for all instrumented events.
@@ -21,6 +21,7 @@ module Flipper
21
21
  @basic_auth_password = options[:basic_auth_password]
22
22
  @read_timeout = options[:read_timeout]
23
23
  @open_timeout = options[:open_timeout]
24
+ @write_timeout = options[:write_timeout]
24
25
  @debug_output = options[:debug_output]
25
26
  end
26
27
 
@@ -57,6 +58,7 @@ module Flipper
57
58
  http = Net::HTTP.new(uri.host, uri.port)
58
59
  http.read_timeout = @read_timeout if @read_timeout
59
60
  http.open_timeout = @open_timeout if @open_timeout
61
+ apply_write_timeout(http)
60
62
  http.set_debug_output(@debug_output) if @debug_output
61
63
 
62
64
  if uri.scheme == HTTPS_SCHEME
@@ -79,6 +81,16 @@ module Flipper
79
81
 
80
82
  request
81
83
  end
84
+
85
+ def apply_write_timeout(http)
86
+ if @write_timeout
87
+ if RUBY_VERSION >= '2.6.0'
88
+ http.write_timeout = @write_timeout
89
+ else
90
+ Kernel.warn("Warning: option :write_timeout requires Ruby version 2.6.0 or later")
91
+ end
92
+ end
93
+ end
82
94
  end
83
95
  end
84
96
  end
@@ -32,115 +32,117 @@ module Flipper
32
32
 
33
33
  # Public
34
34
  def features
35
- payload = {
35
+ default_payload = {
36
36
  operation: :features,
37
37
  adapter_name: @adapter.name,
38
38
  }
39
39
 
40
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
40
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
41
41
  payload[:result] = @adapter.features
42
42
  end
43
43
  end
44
44
 
45
45
  # Public
46
46
  def add(feature)
47
- payload = {
47
+ default_payload = {
48
48
  operation: :add,
49
49
  adapter_name: @adapter.name,
50
50
  feature_name: feature.name,
51
51
  }
52
52
 
53
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
53
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
54
54
  payload[:result] = @adapter.add(feature)
55
55
  end
56
56
  end
57
57
 
58
58
  # Public
59
59
  def remove(feature)
60
- payload = {
60
+ default_payload = {
61
61
  operation: :remove,
62
62
  adapter_name: @adapter.name,
63
63
  feature_name: feature.name,
64
64
  }
65
65
 
66
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
66
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
67
67
  payload[:result] = @adapter.remove(feature)
68
68
  end
69
69
  end
70
70
 
71
71
  # Public
72
72
  def clear(feature)
73
- payload = {
73
+ default_payload = {
74
74
  operation: :clear,
75
75
  adapter_name: @adapter.name,
76
76
  feature_name: feature.name,
77
77
  }
78
78
 
79
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
79
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
80
80
  payload[:result] = @adapter.clear(feature)
81
81
  end
82
82
  end
83
83
 
84
84
  # Public
85
85
  def get(feature)
86
- payload = {
86
+ default_payload = {
87
87
  operation: :get,
88
88
  adapter_name: @adapter.name,
89
89
  feature_name: feature.name,
90
90
  }
91
91
 
92
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
92
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
93
93
  payload[:result] = @adapter.get(feature)
94
94
  end
95
95
  end
96
96
 
97
97
  def get_multi(features)
98
- payload = {
98
+ default_payload = {
99
99
  operation: :get_multi,
100
100
  adapter_name: @adapter.name,
101
101
  feature_names: features.map(&:name),
102
102
  }
103
103
 
104
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
104
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
105
105
  payload[:result] = @adapter.get_multi(features)
106
106
  end
107
107
  end
108
108
 
109
109
  def get_all
110
- payload = {
110
+ default_payload = {
111
111
  operation: :get_all,
112
112
  adapter_name: @adapter.name,
113
113
  }
114
114
 
115
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
115
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
116
116
  payload[:result] = @adapter.get_all
117
117
  end
118
118
  end
119
119
 
120
120
  # Public
121
121
  def enable(feature, gate, thing)
122
- payload = {
122
+ default_payload = {
123
123
  operation: :enable,
124
124
  adapter_name: @adapter.name,
125
125
  feature_name: feature.name,
126
126
  gate_name: gate.name,
127
+ thing_value: thing.value,
127
128
  }
128
129
 
129
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
130
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
130
131
  payload[:result] = @adapter.enable(feature, gate, thing)
131
132
  end
132
133
  end
133
134
 
134
135
  # Public
135
136
  def disable(feature, gate, thing)
136
- payload = {
137
+ default_payload = {
137
138
  operation: :disable,
138
139
  adapter_name: @adapter.name,
139
140
  feature_name: feature.name,
140
141
  gate_name: gate.name,
142
+ thing_value: thing.value,
141
143
  }
142
144
 
143
- @instrumenter.instrument(InstrumentationName, payload) do |payload|
145
+ @instrumenter.instrument(InstrumentationName, default_payload) do |payload|
144
146
  payload[:result] = @adapter.disable(feature, gate, thing)
145
147
  end
146
148
  end
@@ -2,7 +2,7 @@ require 'set'
2
2
 
3
3
  module Flipper
4
4
  module Adapters
5
- # Public: Adapter for storing everything in memory (ie: Hash).
5
+ # Public: Adapter for storing everything in memory.
6
6
  # Useful for tests/specs.
7
7
  class Memory
8
8
  include ::Flipper::Adapter
@@ -65,7 +65,10 @@ module Flipper
65
65
  # Public
66
66
  def enable(feature, gate, thing)
67
67
  case gate.data_type
68
- when :boolean, :integer
68
+ when :boolean
69
+ clear(feature)
70
+ write key(feature, gate), thing.value.to_s
71
+ when :integer
69
72
  write key(feature, gate), thing.value.to_s
70
73
  when :set
71
74
  set_add key(feature, gate), thing.value.to_s
@@ -84,7 +84,10 @@ module Flipper
84
84
  def enable(feature, gate, thing)
85
85
  @store.transaction do
86
86
  case gate.data_type
87
- when :boolean, :integer
87
+ when :boolean
88
+ clear_gates(feature)
89
+ write key(feature, gate), thing.value.to_s
90
+ when :integer
88
91
  write key(feature, gate), thing.value.to_s
89
92
  when :set
90
93
  set_add key(feature, gate), thing.value.to_s
@@ -5,7 +5,6 @@ require 'flipper/feature_check_context'
5
5
  require 'flipper/gate_values'
6
6
 
7
7
  module Flipper
8
- # rubocop:disable Metrics/ClassLength
9
8
  class Feature
10
9
  # Private: The name of feature instrumentation events.
11
10
  InstrumentationName = "feature_operation.#{InstrumentationNamespace}".freeze
@@ -1,5 +1,3 @@
1
- require 'rack/body_proxy'
2
-
3
1
  module Flipper
4
2
  module Middleware
5
3
  class Memoizer
@@ -25,7 +23,7 @@ module Flipper
25
23
  #
26
24
  def initialize(app, opts = {})
27
25
  if opts.is_a?(Flipper::DSL) || opts.is_a?(Proc)
28
- raise 'Flipper::Middleware::Memoizer no longer initializes with a flipper instance or block. Read more at: https://git.io/vSo31.' # rubocop:disable LineLength
26
+ raise 'Flipper::Middleware::Memoizer no longer initializes with a flipper instance or block. Read more at: https://git.io/vSo31.'
29
27
  end
30
28
 
31
29
  @app = app
@@ -1,6 +1,5 @@
1
1
  # Requires the following methods:
2
2
  # * subject - The instance of the adapter
3
- # rubocop:disable Metrics/BlockLength
4
3
  RSpec.shared_examples_for 'a flipper adapter' do
5
4
  let(:flipper) { Flipper.new(subject) }
6
5
  let(:feature) { flipper[:stats] }
@@ -280,4 +279,29 @@ RSpec.shared_examples_for 'a flipper adapter' do
280
279
  expect(subject.enable(feature, group_gate, flipper.group(:admins))).to eq(true)
281
280
  expect(subject.get(feature).fetch(:groups)).to eq(Set['admins'])
282
281
  end
282
+
283
+ it 'can double enable percentage without error' do
284
+ expect(subject.enable(feature, actors_gate, flipper.actors(25))).to eq(true)
285
+ expect(subject.enable(feature, actors_gate, flipper.actors(25))).to eq(true)
286
+ end
287
+
288
+ it 'can double enable without error' do
289
+ expect(subject.enable(feature, boolean_gate, flipper.boolean)).to eq(true)
290
+ expect(subject.enable(feature, boolean_gate, flipper.boolean)).to eq(true)
291
+ end
292
+
293
+ it 'can get_all features when there are none' do
294
+ expect(subject.features).to eq(Set.new)
295
+ expect(subject.get_all).to eq({})
296
+ end
297
+
298
+ it 'clears other gate values on enable' do
299
+ actor = Flipper::Actor.new('Flipper::Actor;22')
300
+ subject.enable(feature, actors_gate, flipper.actors(25))
301
+ subject.enable(feature, time_gate, flipper.time(25))
302
+ subject.enable(feature, group_gate, flipper.group(:admins))
303
+ subject.enable(feature, actor_gate, flipper.actor(actor))
304
+ subject.enable(feature, boolean_gate, flipper.boolean(true))
305
+ expect(subject.get(feature)).to eq(subject.default_config.merge(boolean: "true"))
306
+ end
283
307
  end
@@ -1,4 +1,3 @@
1
- # rubocop:disable Metrics/ModuleLength
2
1
  module Flipper
3
2
  module Test
4
3
  module SharedAdapterTests
@@ -43,7 +42,7 @@ module Flipper
43
42
  assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
44
43
  assert_equal 'true', @adapter.get(@feature)[:boolean]
45
44
  assert_equal true, @adapter.disable(@feature, @boolean_gate, @flipper.boolean(false))
46
- assert_equal nil, @adapter.get(@feature)[:boolean]
45
+ assert_nil @adapter.get(@feature)[:boolean]
47
46
  end
48
47
 
49
48
  def test_fully_disables_all_enabled_things_when_boolean_gate_disabled
@@ -275,6 +274,32 @@ module Flipper
275
274
  assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
276
275
  assert_equal Set['admins'], @adapter.get(@feature).fetch(:groups)
277
276
  end
277
+
278
+ def test_can_double_enable_percentage_without_error
279
+ assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
280
+ assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
281
+ end
282
+
283
+ def test_can_double_enable_without_error
284
+ assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
285
+ assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean)
286
+ end
287
+
288
+ def test_can_get_all_features_when_there_are_none
289
+ expected = {}
290
+ assert_equal Set.new, @adapter.features
291
+ assert_equal expected, @adapter.get_all
292
+ end
293
+
294
+ def test_clears_other_gate_values_on_enable
295
+ actor = Flipper::Actor.new('Flipper::Actor;22')
296
+ assert_equal true, @adapter.enable(@feature, @actors_gate, @flipper.actors(25))
297
+ assert_equal true, @adapter.enable(@feature, @time_gate, @flipper.time(25))
298
+ assert_equal true, @adapter.enable(@feature, @group_gate, @flipper.group(:admins))
299
+ assert_equal true, @adapter.enable(@feature, @actor_gate, @flipper.actor(actor))
300
+ assert_equal true, @adapter.enable(@feature, @boolean_gate, @flipper.boolean(true))
301
+ assert_equal @adapter.default_config.merge(boolean: "true"), @adapter.get(@feature)
302
+ end
278
303
  end
279
304
  end
280
305
  end
@@ -14,7 +14,7 @@ module Flipper
14
14
 
15
15
  if block_given?
16
16
  @block = block
17
- @single_argument = @block.arity == 1
17
+ @single_argument = @block.arity.abs == 1
18
18
  else
19
19
  @block = ->(_thing, _context) { false }
20
20
  @single_argument = false
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.16.0'.freeze
2
+ VERSION = '0.18.0'.freeze
3
3
  end
@@ -16,7 +16,7 @@ RSpec.describe Flipper::Adapter do
16
16
  describe '.default_config' do
17
17
  it 'returns default config' do
18
18
  adapter_class = Class.new do
19
- include Flipper::Adapter # rubocop:disable RSpec/DescribedClass
19
+ include Flipper::Adapter
20
20
  end
21
21
  expect(adapter_class.default_config).to eq(default_config)
22
22
  end
@@ -25,7 +25,7 @@ RSpec.describe Flipper::Adapter do
25
25
  describe '#default_config' do
26
26
  it 'returns default config' do
27
27
  adapter_class = Class.new do
28
- include Flipper::Adapter # rubocop:disable RSpec/DescribedClass
28
+ include Flipper::Adapter
29
29
  end
30
30
  expect(adapter_class.new.default_config).to eq(default_config)
31
31
  end
@@ -128,6 +128,7 @@ RSpec.describe Flipper::Adapters::Http do
128
128
  basic_auth_password: 'password',
129
129
  read_timeout: 100,
130
130
  open_timeout: 40,
131
+ write_timeout: 40,
131
132
  debug_output: debug_output,
132
133
  }
133
134
  end
@@ -73,6 +73,7 @@ RSpec.describe Flipper::Adapters::Instrumented do
73
73
  expect(event.payload[:adapter_name]).to eq(:memory)
74
74
  expect(event.payload[:feature_name]).to eq(:stats)
75
75
  expect(event.payload[:gate_name]).to eq(:percentage_of_actors)
76
+ expect(event.payload[:thing_value]).to eq(22)
76
77
  expect(event.payload[:result]).to be(result)
77
78
  end
78
79
  end
@@ -88,6 +89,7 @@ RSpec.describe Flipper::Adapters::Instrumented do
88
89
  expect(event.payload[:adapter_name]).to eq(:memory)
89
90
  expect(event.payload[:feature_name]).to eq(:stats)
90
91
  expect(event.payload[:gate_name]).to eq(:percentage_of_actors)
92
+ expect(event.payload[:thing_value]).to eq(22)
91
93
  expect(event.payload[:result]).to be(result)
92
94
  end
93
95
  end
@@ -41,8 +41,8 @@ RSpec.describe Flipper::FeatureCheckContext do
41
41
  end
42
42
 
43
43
  it 'knows actors_value' do
44
- args = options.merge(values: Flipper::GateValues.new(actors: Set['User:1']))
45
- expect(described_class.new(args).actors_value).to eq(Set['User:1'])
44
+ args = options.merge(values: Flipper::GateValues.new(actors: Set['User;1']))
45
+ expect(described_class.new(args).actors_value).to eq(Set['User;1'])
46
46
  end
47
47
 
48
48
  it 'knows groups_value' do
@@ -530,12 +530,12 @@ RSpec.describe Flipper::Feature do
530
530
 
531
531
  context 'when one or more actors are enabled' do
532
532
  before do
533
- subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User:5'))
534
- subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User:22'))
533
+ subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User;5'))
534
+ subject.enable Flipper::Types::Actor.new(Flipper::Actor.new('User;22'))
535
535
  end
536
536
 
537
537
  it 'returns set of actor ids' do
538
- expect(subject.actors_value).to eq(Set.new(['User:5', 'User:22']))
538
+ expect(subject.actors_value).to eq(Set.new(['User;5', 'User;22']))
539
539
  end
540
540
  end
541
541
  end
@@ -65,6 +65,28 @@ RSpec.describe Flipper::Types::Group do
65
65
  expect(group.match?(double('Actor'), fake_context)).to be_falsey
66
66
  end
67
67
 
68
+ it 'returns true for truthy shortand block results' do
69
+ actor = Class.new do
70
+ def admin?
71
+ true
72
+ end
73
+ end.new
74
+
75
+ group = described_class.new(:admin, &:admin?)
76
+ expect(group.match?(actor, fake_context)).to be_truthy
77
+ end
78
+
79
+ it 'returns false for falsy shortand block results' do
80
+ actor = Class.new do
81
+ def admin?
82
+ false
83
+ end
84
+ end.new
85
+
86
+ group = described_class.new(:admin, &:admin?)
87
+ expect(group.match?(actor, fake_context)).to be_falsey
88
+ end
89
+
68
90
  it 'can yield without context as block argument' do
69
91
  context = Flipper::FeatureCheckContext.new(
70
92
  feature_name: :my_feature,
@@ -17,7 +17,7 @@ require 'flipper'
17
17
  require 'flipper-ui'
18
18
  require 'flipper-api'
19
19
 
20
- Dir[FlipperRoot.join('spec/support/**/*.rb')].each { |f| require f }
20
+ Dir[FlipperRoot.join('spec/support/**/*.rb')].sort.each { |f| require f }
21
21
 
22
22
  RSpec.configure do |config|
23
23
  config.before(:example) do
@@ -0,0 +1 @@
1
+ some_awesome_feature: 'Awesome feature description'
@@ -1,6 +1,6 @@
1
1
  require 'flipper'
2
2
  require 'minitest/autorun'
3
3
  require 'minitest/unit'
4
- Dir['./lib/flipper/test/*.rb'].each { |f| require(f) }
4
+ Dir['./lib/flipper/test/*.rb'].sort.each { |f| require(f) }
5
5
 
6
6
  FlipperRoot = Pathname(__FILE__).dirname.join('..').expand_path
@@ -6,6 +6,6 @@ require 'rails/test_help'
6
6
 
7
7
  begin
8
8
  ActiveSupport::TestCase.test_order = :random
9
- rescue NoMethodError => boom
9
+ rescue NoMethodError
10
10
  # no biggie, means we are on older version of AS that doesn't have this option
11
11
  end
metadata CHANGED
@@ -1,18 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-01 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Feature flipper is the act of enabling/disabling features in your application,
14
- ideally without re-deploying or changing anything in your code base. Flipper makes
15
- this extremely easy to do with any backend you would like to use.
13
+ description:
16
14
  email:
17
15
  - nunemaker@gmail.com
18
16
  executables: []
@@ -20,8 +18,6 @@ extensions: []
20
18
  extra_rdoc_files: []
21
19
  files:
22
20
  - ".codeclimate.yml"
23
- - ".rubocop.yml"
24
- - ".rubocop_todo.yml"
25
21
  - CODE_OF_CONDUCT.md
26
22
  - Changelog.md
27
23
  - Dockerfile
@@ -143,15 +139,16 @@ files:
143
139
  - spec/flipper/types/percentage_of_actors_spec.rb
144
140
  - spec/flipper/types/percentage_of_time_spec.rb
145
141
  - spec/flipper/types/percentage_spec.rb
142
+ - spec/flipper_integration_spec.rb
146
143
  - spec/flipper_spec.rb
147
144
  - spec/helper.rb
148
- - spec/integration_spec.rb
145
+ - spec/support/descriptions.yml
149
146
  - spec/support/fake_udp_socket.rb
150
147
  - spec/support/spec_helpers.rb
151
148
  - test/adapters/memory_test.rb
152
149
  - test/adapters/pstore_test.rb
153
- - test/helper.rb
154
150
  - test/test_helper.rb
151
+ - test_rails/helper.rb
155
152
  homepage: https://github.com/jnunemaker/flipper
156
153
  licenses:
157
154
  - MIT
@@ -172,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
169
  - !ruby/object:Gem::Version
173
170
  version: '0'
174
171
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 2.4.5.4
172
+ rubygems_version: 3.0.3
177
173
  signing_key:
178
174
  specification_version: 4
179
175
  summary: Feature flipper for ANYTHING
@@ -217,12 +213,12 @@ test_files:
217
213
  - spec/flipper/types/percentage_of_actors_spec.rb
218
214
  - spec/flipper/types/percentage_of_time_spec.rb
219
215
  - spec/flipper/types/percentage_spec.rb
216
+ - spec/flipper_integration_spec.rb
220
217
  - spec/flipper_spec.rb
221
218
  - spec/helper.rb
222
- - spec/integration_spec.rb
219
+ - spec/support/descriptions.yml
223
220
  - spec/support/fake_udp_socket.rb
224
221
  - spec/support/spec_helpers.rb
225
222
  - test/adapters/memory_test.rb
226
223
  - test/adapters/pstore_test.rb
227
- - test/helper.rb
228
224
  - test/test_helper.rb
@@ -1,54 +0,0 @@
1
- # This is the configuration used to check the rubocop source code.
2
-
3
- require: rubocop-rspec
4
- inherit_from:
5
- - .rubocop_todo.yml
6
-
7
- AllCops:
8
- Exclude:
9
- - 'docker-compose/**/*'
10
- - 'examples/**/*'
11
- - 'tmp/**/*'
12
- - 'bin/**/*'
13
- TargetRubyVersion: 2.0
14
- # DefaultFormatter: fuubar
15
- Style/Alias:
16
- Enabled: false
17
-
18
- Style/Documentation:
19
- Enabled: false
20
-
21
- Style/Encoding:
22
- Enabled: false
23
-
24
- Style/NumericLiterals:
25
- Enabled: false
26
-
27
- Style/StringLiterals:
28
- Enabled: false
29
-
30
- Style/GuardClause:
31
- Enabled: false
32
-
33
- Style/IfUnlessModifier:
34
- Enabled: false
35
-
36
- Metrics/LineLength:
37
- Max: 100
38
- Exclude:
39
- - '*.gemspec'
40
-
41
- Style/RegexpLiteral:
42
- EnforcedStyle: mixed
43
-
44
- Style/TrailingCommaInLiteral:
45
- EnforcedStyleForMultiline: consistent_comma
46
-
47
- RSpec/InstanceVariable:
48
- Enabled: false
49
-
50
- Style/AccessorMethodName:
51
- Enabled: false
52
-
53
- Lint/HandleExceptions:
54
- Enabled: false
@@ -1,199 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2016-11-20 15:49:33 +0000 using RuboCop version 0.45.0.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- require: rubocop-rspec
10
-
11
- # Offense count: 2
12
- Lint/AmbiguousRegexpLiteral:
13
- Exclude:
14
- - 'lib/flipper/instrumentation/metriks.rb'
15
- - 'lib/flipper/instrumentation/statsd.rb'
16
-
17
- # Offense count: 6
18
- # Configuration parameters: AllowSafeAssignment.
19
- Lint/AssignmentInCondition:
20
- Exclude:
21
- - 'lib/flipper/adapters/active_record.rb'
22
- - 'lib/flipper/adapters/sequel.rb'
23
- - 'lib/flipper/feature.rb'
24
- - 'lib/flipper/gate_values.rb'
25
-
26
- # Offense count: 1
27
- Lint/Eval:
28
- Exclude:
29
- - 'flipper.gemspec'
30
-
31
- # Offense count: 3
32
- Lint/HandleExceptions:
33
- Exclude:
34
- - 'spec/flipper/adapters/mongo_spec.rb'
35
- - 'test/adapters/mongo_test.rb'
36
- - 'test/helper.rb'
37
-
38
- # Offense count: 24
39
- Lint/ShadowingOuterLocalVariable:
40
- Exclude:
41
- - 'lib/flipper/adapters/active_record.rb'
42
- - 'lib/flipper/adapters/instrumented.rb'
43
- - 'lib/flipper/adapters/sequel.rb'
44
- - 'spec/flipper/api/v1/actions/actors_gate_spec.rb'
45
- - 'spec/flipper/api/v1/actions/percentage_of_actors_gate_spec.rb'
46
- - 'spec/flipper/api/v1/actions/percentage_of_time_gate_spec.rb'
47
- - 'spec/flipper/dsl_spec.rb'
48
- - 'spec/flipper/feature_spec.rb'
49
- - 'spec/flipper/types/group_spec.rb'
50
-
51
- # Offense count: 26
52
- Lint/UselessAssignment:
53
- Exclude:
54
- - 'lib/flipper/instrumentation/log_subscriber.rb'
55
- - 'lib/flipper/instrumentation/subscriber.rb'
56
- - 'lib/flipper/ui/actions/groups_gate.rb'
57
- - 'spec/flipper/api/action_spec.rb'
58
- - 'spec/flipper/dsl_spec.rb'
59
- - 'spec/flipper/feature_spec.rb'
60
- - 'spec/flipper/gates/group_spec.rb'
61
- - 'spec/flipper/instrumentation/metriks_subscriber_spec.rb'
62
- - 'spec/flipper/instrumentation/statsd_subscriber_spec.rb'
63
- - 'spec/flipper_spec.rb'
64
- - 'spec/flipper/middleware/memoizer_spec.rb'
65
- - 'test/helper.rb'
66
-
67
- # Offense count: 27
68
- Metrics/AbcSize:
69
- Max: 30
70
-
71
- # Offense count: 1
72
- # Configuration parameters: CountComments.
73
- Metrics/BlockLength:
74
- Max: 195
75
-
76
- # Offense count: 4
77
- # Configuration parameters: CountComments.
78
- Metrics/ClassLength:
79
- Max: 178
80
-
81
- # Offense count: 39
82
- # Configuration parameters: CountComments.
83
- Metrics/MethodLength:
84
- Max: 23
85
-
86
- # Offense count: 65
87
- # Configuration parameters: Max.
88
- RSpec/ExampleLength:
89
- Enabled: false
90
-
91
- # Offense count: 2
92
- # Configuration parameters: CustomTransform.
93
- RSpec/FilePath:
94
- Exclude:
95
- - 'spec/flipper/adapters/pstore_spec.rb'
96
- - 'spec/integration_spec.rb'
97
-
98
- # Offense count: 91
99
- RSpec/InstanceVariable:
100
- Exclude:
101
- - 'spec/flipper/adapters/operation_logger_spec.rb'
102
- - 'spec/flipper/dsl_spec.rb'
103
- - 'spec/flipper/feature_spec.rb'
104
- - 'spec/flipper/instrumentation/log_subscriber_spec.rb'
105
- - 'spec/flipper/ui/actions/add_feature_spec.rb'
106
- - 'spec/flipper/ui/actions/features_spec.rb'
107
- - 'spec/flipper/ui/decorators/feature_spec.rb'
108
- - 'spec/flipper/ui/decorators/gate_spec.rb'
109
- - 'spec/flipper/ui_spec.rb'
110
- - 'spec/flipper_spec.rb'
111
- - 'spec/integration_spec.rb'
112
-
113
- # Offense count: 15
114
- # Configuration parameters: IgnoreSymbolicNames.
115
- RSpec/VerifiedDoubles:
116
- Exclude:
117
- - 'spec/flipper/api/v1/actions/features_spec.rb'
118
- - 'spec/flipper/dsl_spec.rb'
119
- - 'spec/flipper/feature_spec.rb'
120
- - 'spec/flipper/types/group_spec.rb'
121
- - 'spec/flipper_spec.rb'
122
- - 'spec/integration_spec.rb'
123
-
124
- # Offense count: 2
125
- Style/AccessorMethodName:
126
- Exclude:
127
- - 'lib/flipper/adapters/memory.rb'
128
- - 'lib/flipper/adapters/pstore.rb'
129
-
130
- # Offense count: 7
131
- Style/ConstantName:
132
- Exclude:
133
- - 'lib/flipper.rb'
134
- - 'lib/flipper/adapters/dalli.rb'
135
- - 'lib/flipper/adapters/memoizable.rb'
136
- - 'lib/flipper/adapters/memory.rb'
137
- - 'lib/flipper/adapters/mongo.rb'
138
- - 'lib/flipper/adapters/pstore.rb'
139
- - 'lib/flipper/adapters/redis.rb'
140
-
141
- # Offense count: 3
142
- Style/DoubleNegation:
143
- Exclude:
144
- - 'lib/flipper/adapters/memoizable.rb'
145
- - 'lib/flipper/gates/boolean.rb'
146
- - 'lib/flipper/typecast.rb'
147
-
148
- # Offense count: 7
149
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
150
- Style/FileName:
151
- Exclude:
152
- - 'lib/flipper-active_record.rb'
153
- - 'lib/flipper-api.rb'
154
- - 'lib/flipper-active_support_cache_store.rb'
155
- - 'lib/flipper-cloud.rb'
156
- - 'lib/flipper-dalli.rb'
157
- - 'lib/flipper-mongo.rb'
158
- - 'lib/flipper-redis.rb'
159
- - 'lib/flipper-sequel.rb'
160
- - 'lib/flipper-ui.rb'
161
-
162
- # Offense count: 2
163
- # Configuration parameters: EnforcedStyle, SupportedStyles.
164
- # SupportedStyles: format, sprintf, percent
165
- Style/FormatString:
166
- Exclude:
167
- - 'lib/flipper/instrumentation/log_subscriber.rb'
168
-
169
- # Offense count: 10
170
- # Configuration parameters: MinBodyLength.
171
- Style/GuardClause:
172
- Exclude:
173
- - 'lib/flipper/api/v1/actions/percentage_of_actors_gate.rb'
174
- - 'lib/flipper/api/v1/actions/percentage_of_time_gate.rb'
175
- - 'lib/flipper/gate_values.rb'
176
- - 'lib/flipper/instrumentation/statsd_subscriber.rb'
177
- - 'lib/flipper/instrumentation/subscriber.rb'
178
- - 'lib/flipper/registry.rb'
179
- - 'lib/flipper/typecast.rb'
180
-
181
- # Offense count: 1
182
- Style/IfInsideElse:
183
- Exclude:
184
- - 'lib/flipper/gates/actor.rb'
185
-
186
- # Offense count: 1
187
- Style/MethodMissing:
188
- Exclude:
189
- - 'lib/flipper/types/actor.rb'
190
-
191
- Style/AccessorMethodName:
192
- Exclude:
193
- - 'lib/flipper/adapter.rb'
194
- - 'lib/flipper/adapters/http.rb'
195
- - 'lib/flipper/adapters/instrumented.rb'
196
- - 'lib/flipper/adapters/memoizable.rb'
197
- - 'lib/flipper/adapters/operation_logger.rb'
198
- - 'lib/flipper/adapters/memory.rb'
199
- - 'lib/flipper/adapters/pstore.rb'