flipper 0.17.2 → 0.20.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|