this_feature-adapters-flipper 0.3.0 → 0.4.0
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/Gemfile +1 -0
- data/Gemfile.lock +30 -2
- data/README.md +42 -16
- data/lib/this_feature.rb +3 -4
- data/lib/this_feature/adapters/base.rb +5 -13
- data/lib/this_feature/adapters/flipper.rb +20 -24
- data/lib/this_feature/adapters/memory.rb +22 -13
- data/lib/this_feature/adapters/split_io.rb +52 -0
- data/lib/this_feature/configuration.rb +1 -3
- data/lib/this_feature/errors.rb +4 -4
- data/lib/this_feature/flag.rb +0 -8
- data/lib/this_feature/version.rb +1 -1
- data/memory +0 -0
- data/this_feature-adapters-flipper.gemspec +1 -0
- data/this_feature-adapters-split_io.gemspec +23 -0
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22af6aafd342c298c31378889d21f2f762b5ae5b96c36068a5297be4bb91cc3c
|
4
|
+
data.tar.gz: 67bfd16d7027c4c9ff4fe302bc559e2f3fffc68c54ef8b5dc374d174487ab53d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40d04ebd41d2861ce29170706d6aff6d8da1455d190c592af2a133bf9fa0eaef778308a8eb5c75127d48e54aef79a6a1a2d35e31ca9662ee8e16a8f51dc3cee5
|
7
|
+
data.tar.gz: b8896633916796b3a01dc395e8b34c16c0c0051009f5ef8d2d04c313b3d99875da0130f823603c1818792a08417293ff7d4a18d36c3640da3651e57c1e91978c
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
this_feature (0.
|
5
|
-
this_feature-adapters-flipper (0.
|
4
|
+
this_feature (0.4.0)
|
5
|
+
this_feature-adapters-flipper (0.4.0)
|
6
6
|
flipper (~> 0.16)
|
7
7
|
flipper-active_record (~> 0.16)
|
8
|
+
this_feature
|
9
|
+
this_feature-adapters-split_io (0.4.0)
|
10
|
+
splitclient-rb
|
11
|
+
this_feature
|
8
12
|
|
9
13
|
GEM
|
10
14
|
remote: https://rubygems.org/
|
@@ -23,20 +27,30 @@ GEM
|
|
23
27
|
byebug (11.1.2)
|
24
28
|
coderay (1.1.2)
|
25
29
|
concurrent-ruby (1.1.6)
|
30
|
+
connection_pool (2.2.3)
|
26
31
|
database_cleaner (1.8.4)
|
27
32
|
database_cleaner-active_record (1.8.0)
|
28
33
|
activerecord
|
29
34
|
database_cleaner (~> 1.8.0)
|
30
35
|
diff-lcs (1.3)
|
36
|
+
faraday (1.0.1)
|
37
|
+
multipart-post (>= 1.2, < 3)
|
31
38
|
flipper (0.18.0)
|
32
39
|
flipper-active_record (0.18.0)
|
33
40
|
activerecord (>= 5.0, < 7)
|
34
41
|
flipper (~> 0.18.0)
|
35
42
|
gem-release (2.1.1)
|
43
|
+
hitimes (1.3.1)
|
36
44
|
i18n (1.8.5)
|
37
45
|
concurrent-ruby (~> 1.0)
|
46
|
+
json (2.3.1)
|
47
|
+
jwt (2.2.2)
|
48
|
+
lru_redux (1.1.0)
|
38
49
|
method_source (1.0.0)
|
39
50
|
minitest (5.14.1)
|
51
|
+
multipart-post (2.1.1)
|
52
|
+
net-http-persistent (4.0.0)
|
53
|
+
connection_pool (~> 2.2)
|
40
54
|
pry (0.13.1)
|
41
55
|
coderay (~> 1.1)
|
42
56
|
method_source (~> 1.0)
|
@@ -44,6 +58,7 @@ GEM
|
|
44
58
|
byebug (~> 11.0)
|
45
59
|
pry (~> 0.13.0)
|
46
60
|
rake (13.0.1)
|
61
|
+
redis (4.2.1)
|
47
62
|
rspec (3.9.0)
|
48
63
|
rspec-core (~> 3.9.0)
|
49
64
|
rspec-expectations (~> 3.9.0)
|
@@ -57,6 +72,18 @@ GEM
|
|
57
72
|
diff-lcs (>= 1.2.0, < 2.0)
|
58
73
|
rspec-support (~> 3.9.0)
|
59
74
|
rspec-support (3.9.2)
|
75
|
+
socketry (0.5.1)
|
76
|
+
hitimes (~> 1.2)
|
77
|
+
splitclient-rb (7.1.3)
|
78
|
+
concurrent-ruby (~> 1.0)
|
79
|
+
faraday (>= 0.8)
|
80
|
+
json (>= 1.8)
|
81
|
+
jwt (>= 2.2.1)
|
82
|
+
lru_redux
|
83
|
+
net-http-persistent (>= 2.9)
|
84
|
+
redis (>= 3.2)
|
85
|
+
socketry (~> 0.5.1)
|
86
|
+
thread_safe (>= 0.3)
|
60
87
|
sqlite3 (1.4.2)
|
61
88
|
thread_safe (0.3.6)
|
62
89
|
tzinfo (1.2.7)
|
@@ -76,6 +103,7 @@ DEPENDENCIES
|
|
76
103
|
sqlite3
|
77
104
|
this_feature!
|
78
105
|
this_feature-adapters-flipper!
|
106
|
+
this_feature-adapters-split_io!
|
79
107
|
|
80
108
|
BUNDLED WITH
|
81
109
|
2.1.4
|
data/README.md
CHANGED
@@ -19,42 +19,68 @@ bundle
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
21
21
|
```sh
|
22
|
-
gem install
|
22
|
+
gem install this_feature
|
23
23
|
```
|
24
24
|
|
25
|
-
##
|
25
|
+
## Configuration
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# config/initializers/this_feature.rb
|
29
|
+
require 'this_feature'
|
26
30
|
|
27
|
-
|
31
|
+
ThisFeature.configure do |config|
|
32
|
+
config.adapters = [ThisFeature::Adapters::Memory]
|
33
|
+
config.default_adapter = config.adapters.first
|
34
|
+
end
|
35
|
+
```
|
28
36
|
|
29
|
-
|
30
|
-
We will update this document when more are added.
|
37
|
+
**NOTE**: When searching for the presence of a flag, adapters are queried in order. The default adapter is the fallback adapter used when a flag isn't present in any of the adapters.
|
31
38
|
|
32
|
-
|
39
|
+
|
40
|
+
### With Flipper
|
33
41
|
|
34
42
|
```ruby
|
35
|
-
|
43
|
+
# config/initializers/this_feature.rb
|
44
|
+
require 'this_feature/adapters/flipper'
|
45
|
+
|
46
|
+
ThisFeature.configure do |config|
|
47
|
+
config.adapters = [ThisFeature::Adapters::Flipper]
|
48
|
+
config.default_adapter = config.adapters.first
|
49
|
+
end
|
36
50
|
```
|
37
51
|
|
38
|
-
This `set_adapters` will internally call the `.setup` method on the `FlipperAdapter`, which performs the Flipper initialization.
|
39
52
|
|
40
|
-
Then you can call `ThisFeature.enabled?("flag name")`.
|
41
53
|
|
42
|
-
|
54
|
+
## Usage
|
55
|
+
|
56
|
+
### Flags
|
57
|
+
```ruby
|
58
|
+
ThisFeature.flag('flag_name').on? # check if flag is turned on
|
59
|
+
ThisFeature.flag('flag_name').off? # check if flag is turned off
|
60
|
+
ThisFeature.flag('flag_name').control? # see if the adapter is using the control
|
61
|
+
ThisFeature.flag('flag_name').on! # turn on the flag
|
62
|
+
ThisFeature.flag('flag_name').off! # turn off the flag
|
63
|
+
```
|
43
64
|
|
44
|
-
|
65
|
+
### Context
|
45
66
|
|
46
|
-
|
67
|
+
You can also pass a context to the flag, many feature flagging systems support this.
|
47
68
|
|
48
|
-
|
69
|
+
```ruby
|
70
|
+
ThisFeature.flag('flag_name', context: current_user).on?
|
71
|
+
```
|
49
72
|
|
50
|
-
|
73
|
+
### Data
|
51
74
|
|
52
|
-
|
75
|
+
In case context is not sufficient, you can also pass a data hash.
|
53
76
|
|
54
77
|
```ruby
|
55
|
-
ThisFeature.
|
78
|
+
ThisFeature.flag('flag_name', context: context, data: { org_id: 1 }).on?
|
56
79
|
```
|
57
80
|
|
81
|
+
## TODO: Write documentation for the adapters (creating adapters, using memory adapter, using flipper adapter)
|
82
|
+
|
83
|
+
|
58
84
|
## Development
|
59
85
|
|
60
86
|
The tests are a good reflection of the current development state.
|
data/lib/this_feature.rb
CHANGED
@@ -13,19 +13,19 @@ class ThisFeature
|
|
13
13
|
|
14
14
|
def self.adapter_for(flag_name, context: nil, data: {})
|
15
15
|
matching_adapter = adapters.find do |adapter|
|
16
|
-
adapter.present?(flag_name
|
16
|
+
adapter.present?(flag_name)
|
17
17
|
end
|
18
18
|
|
19
19
|
matching_adapter || configuration.default_adapter
|
20
20
|
end
|
21
21
|
|
22
|
-
# Configuration
|
23
|
-
|
24
22
|
def self.configuration
|
25
23
|
@configuration ||= Configuration.new
|
26
24
|
end
|
27
25
|
|
28
26
|
def self.configure
|
27
|
+
@configuration = Configuration.new
|
28
|
+
|
29
29
|
yield(configuration)
|
30
30
|
|
31
31
|
configuration.init
|
@@ -34,5 +34,4 @@ class ThisFeature
|
|
34
34
|
def self.adapters
|
35
35
|
configuration.adapters
|
36
36
|
end
|
37
|
-
|
38
37
|
end
|
@@ -2,33 +2,25 @@ class ThisFeature
|
|
2
2
|
module Adapters
|
3
3
|
class Base
|
4
4
|
|
5
|
-
def
|
5
|
+
def setup
|
6
6
|
raise UnimplementedError.new(self, __method__)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def present?(flag_name)
|
10
10
|
raise UnimplementedError.new(self, __method__)
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def on?(flag_name, context: nil, data: {})
|
14
14
|
raise UnimplementedError.new(self, __method__)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
raise UnimplementedError.new(self, __method__)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.on!(flag_name, context: nil, data: {})
|
22
|
-
raise UnimplementedError.new(self, __method__)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.off!(flag_name, context: nil, data: {})
|
17
|
+
def off?(flag_name, context: nil, data: {})
|
26
18
|
raise UnimplementedError.new(self, __method__)
|
27
19
|
end
|
28
20
|
|
29
21
|
# OPTIONAL method
|
30
22
|
# check to see if a control is being used
|
31
|
-
def
|
23
|
+
def control?(flag_name, context: nil, data: {})
|
32
24
|
false
|
33
25
|
end
|
34
26
|
end
|
@@ -4,31 +4,27 @@ require "flipper/adapters/active_record"
|
|
4
4
|
class ThisFeature
|
5
5
|
module Adapters
|
6
6
|
class Flipper < Base
|
7
|
+
attr_reader :client
|
7
8
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
@flipper = ::Flipper
|
9
|
+
def initialize(client: nil)
|
10
|
+
@client = client || default_flipper_adapter
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
adapter = ::Flipper::Adapters::ActiveRecord.new
|
16
|
-
::Flipper.new(adapter)
|
17
|
-
end
|
18
|
-
end
|
13
|
+
def present?(flag_name)
|
14
|
+
client[flag_name].exist?
|
19
15
|
end
|
20
16
|
|
21
|
-
def
|
22
|
-
|
17
|
+
def control?(flag_name, **kwargs)
|
18
|
+
!present?(flag_name)
|
23
19
|
end
|
24
20
|
|
25
|
-
def
|
21
|
+
def on?(flag_name, context: nil, data: {})
|
26
22
|
return unless present?(flag_name)
|
27
23
|
|
28
|
-
|
24
|
+
client[flag_name].enabled?(*[context].compact)
|
29
25
|
end
|
30
26
|
|
31
|
-
def
|
27
|
+
def off?(flag_name, context: nil, data: {})
|
32
28
|
on_result = on?(flag_name, context: context)
|
33
29
|
|
34
30
|
return if on_result.nil?
|
@@ -36,16 +32,16 @@ class ThisFeature
|
|
36
32
|
!on_result
|
37
33
|
end
|
38
34
|
|
39
|
-
|
40
|
-
flipper[flag_name].enable(*[context].compact)
|
41
|
-
end
|
35
|
+
private
|
42
36
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
def default_flipper_adapter
|
38
|
+
::Flipper.configure do |config|
|
39
|
+
config.default do
|
40
|
+
adapter = ::Flipper::Adapters::ActiveRecord.new
|
41
|
+
::Flipper.new(adapter)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
::Flipper
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
@@ -2,20 +2,19 @@ class ThisFeature
|
|
2
2
|
module Adapters
|
3
3
|
class Memory < Base
|
4
4
|
|
5
|
-
def
|
6
|
-
@
|
5
|
+
def initialize(context_key_method: nil)
|
6
|
+
@context_key_method = context_key_method
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def clear
|
10
10
|
storage.clear
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def present?(flag_name)
|
14
14
|
!storage[flag_name].nil?
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
# binding.pry
|
17
|
+
def on?(flag_name, context: nil, data: {})
|
19
18
|
return unless present?(flag_name)
|
20
19
|
|
21
20
|
flag_data = storage[flag_name]
|
@@ -25,10 +24,10 @@ class ThisFeature
|
|
25
24
|
|
26
25
|
flag_data[:contexts] ||= {}
|
27
26
|
|
28
|
-
!!flag_data[:contexts][context
|
27
|
+
!!flag_data[:contexts][context_key(context)]
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
30
|
+
def off?(flag_name, context: nil, data: {})
|
32
31
|
on_result = on?(flag_name, context: context)
|
33
32
|
|
34
33
|
return if on_result.nil?
|
@@ -36,27 +35,37 @@ class ThisFeature
|
|
36
35
|
!on_result
|
37
36
|
end
|
38
37
|
|
39
|
-
def
|
38
|
+
def on!(flag_name, context: nil, data: {})
|
40
39
|
storage[flag_name] ||= {}
|
41
40
|
|
42
41
|
return storage[flag_name][:global] = true if context.nil?
|
43
42
|
|
44
43
|
storage[flag_name][:contexts] ||= {}
|
45
|
-
storage[flag_name][:contexts][context
|
44
|
+
storage[flag_name][:contexts][context_key(context)] = true
|
46
45
|
end
|
47
46
|
|
48
|
-
def
|
47
|
+
def off!(flag_name, context: nil, data: {})
|
49
48
|
storage[flag_name] ||= {}
|
50
49
|
|
51
50
|
return storage[flag_name][:global] = false if context.nil?
|
52
51
|
|
53
52
|
storage[flag_name][:contexts] ||= {}
|
54
|
-
storage[flag_name][:contexts][context
|
53
|
+
storage[flag_name][:contexts][context_key(context)] = false
|
55
54
|
end
|
56
55
|
|
57
|
-
def
|
56
|
+
def storage
|
58
57
|
@storage ||= {}
|
59
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
attr_reader :context_key_method
|
63
|
+
|
64
|
+
def context_key(context)
|
65
|
+
return context if context_key_method.nil?
|
66
|
+
|
67
|
+
context.send(context_key_method)
|
68
|
+
end
|
60
69
|
end
|
61
70
|
end
|
62
71
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'splitclient-rb'
|
2
|
+
|
3
|
+
class ThisFeature
|
4
|
+
module Adapters
|
5
|
+
class SplitIo < Base
|
6
|
+
# used as treatment key when none is given, it's required by split
|
7
|
+
UNDEFINED_KEY = 'undefined_key'
|
8
|
+
|
9
|
+
def initialize(client: nil)
|
10
|
+
@client = client || default_split_client
|
11
|
+
|
12
|
+
@client.block_until_ready
|
13
|
+
end
|
14
|
+
|
15
|
+
def present?(flag_name)
|
16
|
+
!control?(flag_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def control?(flag_name, context: UNDEFINED_KEY, data: {})
|
20
|
+
treatment(flag_name, context: context, data: data).eql?('control_treatment')
|
21
|
+
end
|
22
|
+
|
23
|
+
def on?(flag_name, context: UNDEFINED_KEY, data: {})
|
24
|
+
treatment(flag_name, context: context, data: data).eql?('on')
|
25
|
+
end
|
26
|
+
|
27
|
+
def off?(flag_name, context: UNDEFINED_KEY, data: {})
|
28
|
+
treatment(flag_name, context: context, data: data).eql?('off')
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :client
|
34
|
+
|
35
|
+
def treatment(flag_name, context: UNDEFINED_KEY, data: {})
|
36
|
+
key = if context.nil?
|
37
|
+
UNDEFINED_KEY
|
38
|
+
elsif context.respond_to?(:to_s)
|
39
|
+
context.to_s
|
40
|
+
else
|
41
|
+
context
|
42
|
+
end
|
43
|
+
|
44
|
+
client.get_treatment(key, flag_name, data)
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_split_client
|
48
|
+
SplitIoClient::SplitFactory.new(ENV.fetch('SPLIT_IO_AUTH_KEY')).client
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -5,13 +5,11 @@ class ThisFeature
|
|
5
5
|
|
6
6
|
def init
|
7
7
|
validate_adapters!
|
8
|
-
|
9
|
-
adapters.each(&:setup)
|
10
8
|
end
|
11
9
|
|
12
10
|
def validate_adapters!
|
13
11
|
adapters.each do |adapter|
|
14
|
-
raise BadAdapterError.new(adapter) unless adapter < Adapters::Base
|
12
|
+
raise BadAdapterError.new(adapter) unless adapter.class < Adapters::Base
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
data/lib/this_feature/errors.rb
CHANGED
@@ -3,14 +3,14 @@ class ThisFeature
|
|
3
3
|
class Error < StandardError; end
|
4
4
|
|
5
5
|
class UnimplementedError < Error
|
6
|
-
def initialize(
|
7
|
-
super("class #{
|
6
|
+
def initialize(adapter_instance, fn_name)
|
7
|
+
super("class #{adapter_instance.class.name} doesnt implement method .#{fn_name}")
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
class BadAdapterError < Error
|
12
|
-
def initialize(
|
13
|
-
super("adapter #{
|
12
|
+
def initialize(adapter_instance)
|
13
|
+
super("adapter #{adapter_instance.class.name} doesn't inherit from #{ThisFeature::Adapters::Base.name}")
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
data/lib/this_feature/flag.rb
CHANGED
@@ -20,13 +20,5 @@ class ThisFeature
|
|
20
20
|
def control?
|
21
21
|
adapter.control?(flag_name, context: context, data: data)
|
22
22
|
end
|
23
|
-
|
24
|
-
def on!
|
25
|
-
adapter.on!(flag_name, context: context, data: data)
|
26
|
-
end
|
27
|
-
|
28
|
-
def off!
|
29
|
-
adapter.off!(flag_name, context: context, data: data)
|
30
|
-
end
|
31
23
|
end
|
32
24
|
end
|
data/lib/this_feature/version.rb
CHANGED
data/memory
CHANGED
Binary file
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'this_feature/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'this_feature-adapters-split_io'
|
9
|
+
s.version = ThisFeature::VERSION
|
10
|
+
s.authors = ['Max Pleaner', 'Matt Fong']
|
11
|
+
s.email = ['maxpleaner@gmail.com', 'matthewjf@gmail.com']
|
12
|
+
s.homepage = 'http://hover.to'
|
13
|
+
s.licenses = ['MIT']
|
14
|
+
s.summary = '[summary]'
|
15
|
+
s.description = '[description]'
|
16
|
+
|
17
|
+
s.files = Dir.glob('{bin/*,lib/**/*,[A-Z]*}')
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_runtime_dependency "this_feature"
|
22
|
+
s.add_runtime_dependency "splitclient-rb"
|
23
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: this_feature-adapters-flipper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Pleaner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: this_feature
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: flipper
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,18 +72,20 @@ files:
|
|
58
72
|
- lib/this_feature/adapters/base.rb
|
59
73
|
- lib/this_feature/adapters/flipper.rb
|
60
74
|
- lib/this_feature/adapters/memory.rb
|
75
|
+
- lib/this_feature/adapters/split_io.rb
|
61
76
|
- lib/this_feature/configuration.rb
|
62
77
|
- lib/this_feature/errors.rb
|
63
78
|
- lib/this_feature/flag.rb
|
64
79
|
- lib/this_feature/version.rb
|
65
80
|
- memory
|
66
81
|
- this_feature-adapters-flipper.gemspec
|
82
|
+
- this_feature-adapters-split_io.gemspec
|
67
83
|
- this_feature.gemspec
|
68
84
|
homepage: http://hover.to
|
69
85
|
licenses:
|
70
86
|
- MIT
|
71
87
|
metadata: {}
|
72
|
-
post_install_message:
|
88
|
+
post_install_message:
|
73
89
|
rdoc_options: []
|
74
90
|
require_paths:
|
75
91
|
- lib
|
@@ -85,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
101
|
version: '0'
|
86
102
|
requirements: []
|
87
103
|
rubygems_version: 3.1.2
|
88
|
-
signing_key:
|
104
|
+
signing_key:
|
89
105
|
specification_version: 4
|
90
106
|
summary: "[summary]"
|
91
107
|
test_files: []
|