flipper 0.17.2 → 0.20.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +27 -1
- data/Dockerfile +1 -1
- data/Gemfile +2 -6
- data/Rakefile +1 -4
- data/docs/Adapters.md +1 -1
- data/docs/DockerCompose.md +0 -1
- data/docs/Gates.md +1 -1
- data/examples/memoizing.rb +39 -0
- data/flipper.gemspec +0 -1
- data/lib/flipper.rb +3 -2
- data/lib/flipper/adapters/dual_write.rb +67 -0
- data/lib/flipper/adapters/operation_logger.rb +5 -0
- data/lib/flipper/adapters/sync.rb +7 -7
- data/lib/flipper/adapters/sync/synchronizer.rb +1 -0
- data/lib/flipper/dsl.rb +8 -0
- data/lib/flipper/feature.rb +2 -2
- data/lib/flipper/middleware/memoizer.rb +1 -1
- data/lib/flipper/middleware/setup_env.rb +13 -3
- data/lib/flipper/test/shared_adapter_test.rb +0 -1
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/adapter_spec.rb +2 -2
- data/spec/flipper/adapters/dual_write_spec.rb +71 -0
- data/spec/flipper/adapters/operation_logger_spec.rb +9 -0
- data/spec/flipper/adapters/sync_spec.rb +4 -4
- data/spec/flipper/feature_spec.rb +5 -5
- data/spec/flipper/middleware/memoizer_spec.rb +1 -1
- data/spec/flipper/middleware/setup_env_spec.rb +39 -3
- data/spec/{integration_spec.rb → flipper_integration_spec.rb} +0 -0
- data/spec/flipper_spec.rb +27 -0
- data/spec/support/descriptions.yml +1 -0
- data/spec/support/spec_helpers.rb +5 -0
- metadata +13 -11
- data/.rubocop.yml +0 -52
- data/.rubocop_todo.yml +0 -562
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d324a4fa07054c9c189fba3f8baa100e4c4a70ae4618b251c84be77f56e27e54
|
4
|
+
data.tar.gz: 73a1ff5ddfdfbf04f43296fb0dfe67dd0cf2a3ab094d35909462dfa30fc9ba87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ae1cde3eef862c76a40f6166deb59406a5f8a3560829220fd4291c614e4fd8eb91d300ad2eb218f81e433a447e90c6d88fea194ad05d9e27ea5a282bac51dfe
|
7
|
+
data.tar.gz: 33e3c151261a516fc9cf5b8415c57c472f5a5560d6670815f872b71cbf99293c79a1e7f1788e2db6a262f7c3b7e8ec2479717b59cdd6dba2cdc52945d9fc5c1b
|
data/Changelog.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## 0.19.1
|
2
|
+
|
3
|
+
### Additions/Changes
|
4
|
+
|
5
|
+
* Bump rack-protection version to < 2.2 (https://github.com/jnunemaker/flipper/pull/487)
|
6
|
+
* Add memoizer_options to Flipper::Api.app (https://github.com/jnunemaker/flipper/commit/174ad4bb94046a25c432d3c53fe1ff9f5a76d838)
|
7
|
+
|
8
|
+
## 0.19.0
|
9
|
+
|
10
|
+
### Additions/Changes
|
11
|
+
|
12
|
+
* 100% of actors is now considered conditional. Feature#on?, Feature#conditional?, Feature#state would all be affected. See https://github.com/jnunemaker/flipper/issues/463 for more.
|
13
|
+
* Several doc updates.
|
14
|
+
|
15
|
+
## 0.18.0
|
16
|
+
|
17
|
+
### Additions/Changes
|
18
|
+
|
19
|
+
* Add support for feature descriptions to flipper-ui (https://github.com/jnunemaker/flipper/pull/461).
|
20
|
+
* Remove rubocop (https://github.com/jnunemaker/flipper/pull/469).
|
21
|
+
* flipper-ui redesign (https://github.com/jnunemaker/flipper/pull/470).
|
22
|
+
* Removed support for ruby 2.4.
|
23
|
+
* Added support for ruby 2.7.
|
24
|
+
* Removed support for Rails 4.x.x.
|
25
|
+
* Removed support for customizing actors, groups, % of actors and % of time text in flipper-ui in favor of automatic and more descriptive text.
|
26
|
+
|
1
27
|
## 0.17.2
|
2
28
|
|
3
29
|
### Additions/Changes
|
@@ -90,7 +116,7 @@
|
|
90
116
|
|
91
117
|
### Additions/Changes
|
92
118
|
|
93
|
-
* Added rollout adapter documentation (https://github.com/jnunemaker/flipper/pull/328).
|
119
|
+
* Added rollout adapter documentation (https://github.com/jnunemaker/flipper/pull/328).
|
94
120
|
|
95
121
|
### Bug Fixes
|
96
122
|
|
data/Dockerfile
CHANGED
data/Gemfile
CHANGED
@@ -12,20 +12,16 @@ 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', "~> #{ENV['SQLITE3_VERSION'] || '1.
|
15
|
+
gem 'sqlite3', "~> #{ENV['SQLITE3_VERSION'] || '1.4.1'}"
|
16
16
|
gem 'rails', "~> #{ENV['RAILS_VERSION'] || '6.0.0'}"
|
17
17
|
gem 'minitest', '~> 5.8'
|
18
18
|
gem 'minitest-documentation'
|
19
|
-
gem 'rubocop'
|
20
|
-
gem 'rubocop-rspec'
|
21
19
|
gem 'webmock', '~> 3.0'
|
20
|
+
gem 'climate_control'
|
22
21
|
|
23
22
|
group(:guard) do
|
24
23
|
gem 'guard', '~> 2.15'
|
25
|
-
gem 'guard-rubocop', '~> 1.3'
|
26
24
|
gem 'guard-rspec', '~> 4.5'
|
27
25
|
gem 'guard-bundler', '~> 2.2'
|
28
|
-
gem 'guard-coffeescript', '~> 2.0'
|
29
|
-
gem 'guard-sass', '~> 1.6'
|
30
26
|
gem 'rb-fsevent', '~> 0.9'
|
31
27
|
end
|
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
3
|
require 'rake/testtask'
|
4
|
-
require 'rubocop/rake_task'
|
5
4
|
require 'flipper/version'
|
6
5
|
|
7
6
|
# gem install pkg/*.gem
|
@@ -50,6 +49,4 @@ Rake::TestTask.new(:test_rails) do |t|
|
|
50
49
|
t.warning = false
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
task default: [:spec, :test, :test_rails, :rubocop]
|
52
|
+
task default: [:spec, :test, :test_rails]
|
data/docs/Adapters.md
CHANGED
@@ -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
|
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)
|
data/docs/DockerCompose.md
CHANGED
@@ -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
|
data/docs/Gates.md
CHANGED
@@ -96,7 +96,7 @@ flipper[:logging].enable percentage
|
|
96
96
|
flipper[:logging].enabled? # this will return true 5% of the time.
|
97
97
|
|
98
98
|
# you can also use shortcut methods
|
99
|
-
flipper.enable_percentage_of_time :search, 5 # registers a feature called "
|
99
|
+
flipper.enable_percentage_of_time :search, 5 # registers a feature called "search" and enables it 5% of the time
|
100
100
|
flipper.disable_percentage_of_time :search # sets to 0
|
101
101
|
flipper[:search].enable_percentage_of_time 5
|
102
102
|
flipper[:search].disable_percentage_of_time # sets to 0
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../example_setup', __FILE__)
|
2
|
+
|
3
|
+
require 'flipper'
|
4
|
+
require 'flipper/adapters/operation_logger'
|
5
|
+
require 'flipper/instrumentation/log_subscriber'
|
6
|
+
|
7
|
+
Flipper.configure do |config|
|
8
|
+
config.default do
|
9
|
+
# pick an adapter, this uses memory, any will do
|
10
|
+
adapter = Flipper::Adapters::OperationLogger.new(Flipper::Adapters::Memory.new)
|
11
|
+
|
12
|
+
# pass adapter to handy DSL instance
|
13
|
+
Flipper.new(adapter)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Flipper.enable(:foo)
|
18
|
+
Flipper.enable(:bar)
|
19
|
+
Flipper.disable(:baz)
|
20
|
+
Flipper.disable(:wick)
|
21
|
+
# reset the operation logging adapter to empty for clarity
|
22
|
+
Flipper.adapter.reset
|
23
|
+
|
24
|
+
# Turn on memoization (the memoizing middleware does this per request).
|
25
|
+
Flipper.memoize = true
|
26
|
+
|
27
|
+
# Preload all the features.
|
28
|
+
Flipper.preload_all
|
29
|
+
|
30
|
+
# Do as many feature checks as your heart desires.
|
31
|
+
%w[foo bar baz wick].each do |name|
|
32
|
+
Flipper.enabled?(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
# See that only one operation exists, a get_all (which is the preload_all).
|
36
|
+
pp Flipper.adapter.operations
|
37
|
+
# [#<Flipper::Adapters::OperationLogger::Operation:0x00007fdcfe1100e8
|
38
|
+
# @args=[],
|
39
|
+
# @type=:get_all>]
|
data/flipper.gemspec
CHANGED
@@ -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.' # rubocop:disable Layout/LineLength
|
29
28
|
gem.homepage = 'https://github.com/jnunemaker/flipper'
|
30
29
|
gem.license = 'MIT'
|
31
30
|
|
data/lib/flipper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "forwardable"
|
2
2
|
|
3
3
|
module Flipper
|
4
|
-
extend self
|
4
|
+
extend self
|
5
5
|
extend Forwardable
|
6
6
|
|
7
7
|
# Private: The namespace for all instrumented events.
|
@@ -65,7 +65,8 @@ module Flipper
|
|
65
65
|
:time, :percentage_of_time,
|
66
66
|
:features, :feature, :[], :preload, :preload_all,
|
67
67
|
:adapter, :add, :exist?, :remove, :import,
|
68
|
-
:memoize=, :memoizing
|
68
|
+
:memoize=, :memoizing?,
|
69
|
+
:sync, :sync_secret # For Flipper::Cloud. Will error for OSS Flipper.
|
69
70
|
|
70
71
|
# Public: Use this to register a group by name.
|
71
72
|
#
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Flipper
|
2
|
+
module Adapters
|
3
|
+
class DualWrite
|
4
|
+
include ::Flipper::Adapter
|
5
|
+
|
6
|
+
# Public: The name of the adapter.
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
# Public: Build a new sync instance.
|
10
|
+
#
|
11
|
+
# local - The local flipper adapter that should serve reads.
|
12
|
+
# remote - The remote flipper adapter that writes should go to first (in
|
13
|
+
# addition to the local adapter).
|
14
|
+
def initialize(local, remote, options = {})
|
15
|
+
@name = :dual_write
|
16
|
+
@local = local
|
17
|
+
@remote = remote
|
18
|
+
end
|
19
|
+
|
20
|
+
def features
|
21
|
+
@local.features
|
22
|
+
end
|
23
|
+
|
24
|
+
def get(feature)
|
25
|
+
@local.get(feature)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_multi(features)
|
29
|
+
@local.get_multi(features)
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_all
|
33
|
+
@local.get_all
|
34
|
+
end
|
35
|
+
|
36
|
+
def add(feature)
|
37
|
+
result = @remote.add(feature)
|
38
|
+
@local.add(feature)
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove(feature)
|
43
|
+
result = @remote.remove(feature)
|
44
|
+
@local.remove(feature)
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear(feature)
|
49
|
+
result = @remote.clear(feature)
|
50
|
+
@local.clear(feature)
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def enable(feature, gate, thing)
|
55
|
+
result = @remote.enable(feature, gate, thing)
|
56
|
+
@local.enable(feature, gate, thing)
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
def disable(feature, gate, thing)
|
61
|
+
result = @remote.disable(feature, gate, thing)
|
62
|
+
@local.disable(feature, gate, thing)
|
63
|
+
result
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -117,6 +117,11 @@ module Flipper
|
|
117
117
|
def reset
|
118
118
|
@operations.clear
|
119
119
|
end
|
120
|
+
|
121
|
+
def inspect
|
122
|
+
inspect_id = ::Kernel::format "%x", (object_id * 2)
|
123
|
+
%(#<#{self.class}:0x#{inspect_id} @name=#{name.inspect}, @operations=#{@operations.inspect}, @adapter=#{@adapter.inspect}>)
|
124
|
+
end
|
120
125
|
end
|
121
126
|
end
|
122
127
|
end
|
@@ -17,7 +17,7 @@ module Flipper
|
|
17
17
|
# Public: Build a new sync instance.
|
18
18
|
#
|
19
19
|
# local - The local flipper adapter that should serve reads.
|
20
|
-
# remote - The remote flipper
|
20
|
+
# remote - The remote flipper adapter that should serve writes and update
|
21
21
|
# the local on an interval.
|
22
22
|
# interval - The Float or Integer number of seconds between syncs from
|
23
23
|
# remote to local. Default value is set in IntervalSynchronizer.
|
@@ -34,26 +34,26 @@ module Flipper
|
|
34
34
|
synchronizer = Synchronizer.new(@local, @remote, sync_options)
|
35
35
|
IntervalSynchronizer.new(synchronizer, interval: options[:interval])
|
36
36
|
end
|
37
|
-
|
37
|
+
synchronize
|
38
38
|
end
|
39
39
|
|
40
40
|
def features
|
41
|
-
|
41
|
+
synchronize
|
42
42
|
@local.features
|
43
43
|
end
|
44
44
|
|
45
45
|
def get(feature)
|
46
|
-
|
46
|
+
synchronize
|
47
47
|
@local.get(feature)
|
48
48
|
end
|
49
49
|
|
50
50
|
def get_multi(features)
|
51
|
-
|
51
|
+
synchronize
|
52
52
|
@local.get_multi(features)
|
53
53
|
end
|
54
54
|
|
55
55
|
def get_all
|
56
|
-
|
56
|
+
synchronize
|
57
57
|
@local.get_all
|
58
58
|
end
|
59
59
|
|
@@ -89,7 +89,7 @@ module Flipper
|
|
89
89
|
|
90
90
|
private
|
91
91
|
|
92
|
-
def
|
92
|
+
def synchronize
|
93
93
|
@synchronizer.call
|
94
94
|
end
|
95
95
|
end
|
@@ -15,6 +15,7 @@ module Flipper
|
|
15
15
|
# adapter should be brought in line with.
|
16
16
|
# options - The Hash of options.
|
17
17
|
# :instrumenter - The instrumenter used to instrument.
|
18
|
+
# :raise - Should errors be raised (default: true).
|
18
19
|
def initialize(local, remote, options = {})
|
19
20
|
@local = local
|
20
21
|
@remote = remote
|
data/lib/flipper/dsl.rb
CHANGED
@@ -273,5 +273,13 @@ module Flipper
|
|
273
273
|
def import(flipper)
|
274
274
|
adapter.import(flipper.adapter)
|
275
275
|
end
|
276
|
+
|
277
|
+
# Cloud DSL method that does nothing for open source version.
|
278
|
+
def sync
|
279
|
+
end
|
280
|
+
|
281
|
+
# Cloud DSL method that does nothing for open source version.
|
282
|
+
def sync_secret
|
283
|
+
end
|
276
284
|
end
|
277
285
|
end
|
data/lib/flipper/feature.rb
CHANGED
@@ -5,7 +5,7 @@ require 'flipper/feature_check_context'
|
|
5
5
|
require 'flipper/gate_values'
|
6
6
|
|
7
7
|
module Flipper
|
8
|
-
class Feature
|
8
|
+
class Feature
|
9
9
|
# Private: The name of feature instrumentation events.
|
10
10
|
InstrumentationName = "feature_operation.#{InstrumentationNamespace}".freeze
|
11
11
|
|
@@ -205,7 +205,7 @@ module Flipper
|
|
205
205
|
boolean = gate(:boolean)
|
206
206
|
non_boolean_gates = gates - [boolean]
|
207
207
|
|
208
|
-
if values.boolean || values.
|
208
|
+
if values.boolean || values.percentage_of_time == 100
|
209
209
|
:on
|
210
210
|
elsif non_boolean_gates.detect { |gate| gate.enabled?(values[gate.key]) }
|
211
211
|
:conditional
|
@@ -23,7 +23,7 @@ module Flipper
|
|
23
23
|
#
|
24
24
|
def initialize(app, opts = {})
|
25
25
|
if opts.is_a?(Flipper::DSL) || opts.is_a?(Proc)
|
26
|
-
raise 'Flipper::Middleware::Memoizer no longer initializes with a flipper instance or block. Read more at: https://git.io/vSo31.'
|
26
|
+
raise 'Flipper::Middleware::Memoizer no longer initializes with a flipper instance or block. Read more at: https://git.io/vSo31.'
|
27
27
|
end
|
28
28
|
|
29
29
|
@app = app
|
@@ -7,7 +7,8 @@ module Flipper
|
|
7
7
|
#
|
8
8
|
# app - The app this middleware is included in.
|
9
9
|
# flipper_or_block - The Flipper::DSL instance or a block that yields a
|
10
|
-
# Flipper::DSL instance to use for all operations
|
10
|
+
# Flipper::DSL instance to use for all operations
|
11
|
+
# (optional, default: Flipper).
|
11
12
|
#
|
12
13
|
# Examples
|
13
14
|
#
|
@@ -19,18 +20,27 @@ module Flipper
|
|
19
20
|
# # using with a block that yields a flipper instance
|
20
21
|
# use Flipper::Middleware::SetupEnv, lambda { Flipper.new(...) }
|
21
22
|
#
|
22
|
-
|
23
|
+
# # using default configured Flipper instance
|
24
|
+
# Flipper.configure do |config|
|
25
|
+
# config.default { Flipper.new(...) }
|
26
|
+
# end
|
27
|
+
# use Flipper::Middleware::SetupEnv
|
28
|
+
def initialize(app, flipper_or_block = nil, options = {})
|
23
29
|
@app = app
|
24
30
|
@env_key = options.fetch(:env_key, 'flipper')
|
25
31
|
|
26
32
|
if flipper_or_block.respond_to?(:call)
|
27
33
|
@flipper_block = flipper_or_block
|
28
34
|
else
|
29
|
-
@flipper = flipper_or_block
|
35
|
+
@flipper = flipper_or_block || Flipper
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
33
39
|
def call(env)
|
40
|
+
dup.call!(env)
|
41
|
+
end
|
42
|
+
|
43
|
+
def call!(env)
|
34
44
|
env[@env_key] ||= flipper
|
35
45
|
@app.call(env)
|
36
46
|
end
|
data/lib/flipper/version.rb
CHANGED
@@ -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
|
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
|
28
|
+
include Flipper::Adapter
|
29
29
|
end
|
30
30
|
expect(adapter_class.new.default_config).to eq(default_config)
|
31
31
|
end
|