feature_guard 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac443b4c9e81abf91976dd0bc5ab802b7ea2b11f
4
+ data.tar.gz: 5e95d160aa879d4867bd33274f035c0690c1ff22
5
+ SHA512:
6
+ metadata.gz: 435e28575454290cc3da192e53a3a84c8f5c008ee504a11fe9d195774c1562e26ad3f1dee945191064d6b3c4e18ac5746c8b29813e6469aee76b6e59992005b2
7
+ data.tar.gz: 8d7898ad67a3b76ad8aa33767b12a1f3113114001a30798d6e5ed58a84a352fb4ad67bc60e5910170ad71f815a422d713ad352467a60e1a25bcd2869e691600e
data/README.md CHANGED
@@ -60,6 +60,25 @@ FeatureGuard.allow? :my_feature
60
60
 
61
61
  The optional second argument to`.allow?` can be of any type (e.g., user ID or name or even an object). It is hashed with the feature name to create a reproducible numeric value for checking whether to return true or false based on the current ramp-up value. With no second argument, `.allow?` uses a new random value on every call.
62
62
 
63
+ To retrieve information on all binary-enabled/disabled features, use `.all_flags`:
64
+
65
+ ```ruby
66
+ FeatureGuard.enable :my_feature
67
+ FeatureGuard.enable :another_feature
68
+ FeatureGuard.toggle :my_feature
69
+ FeatureGuard.all_flags
70
+ # {"my_feature"=>false, "another_feature"=>true}
71
+ ```
72
+
73
+ To retrieve information on all ramp values, use `.all_ramps`:
74
+
75
+ ```ruby
76
+ FeatureGuard.set_ramp :my_feature, 50
77
+ FeatureGuard.set_ramp :another_feature, 30
78
+ FeatureGuard.all_ramps
79
+ # {"my_feature"=>50.0, "another_feature"=>30.0}
80
+ ```
81
+
63
82
  ## Configuration
64
83
 
65
84
  Optionally change the Redis client with:
@@ -3,7 +3,7 @@ require File.expand_path('../lib/feature_guard/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Ted Dumitrescu"]
6
- gem.email = ["miscmisc@cmme.org"]
6
+ gem.email = ["webdev@cmme.org"]
7
7
  gem.summary = %q{Simple Redis-based feature-flagging}
8
8
  gem.description = <<end
9
9
  Feature flags made simple: turn code on or off with Redis controls, allowing
@@ -22,5 +22,5 @@ end
22
22
  gem.add_dependency "redis", "~> 3.0"
23
23
 
24
24
  gem.add_development_dependency "fakeredis", "~> 0.4"
25
- gem.add_development_dependency "rspec", "~> 2.13"
25
+ gem.add_development_dependency "rspec", "~> 2.99"
26
26
  end
@@ -7,11 +7,30 @@ module FeatureGuard
7
7
  class << self
8
8
  attr_writer :redis
9
9
 
10
+ def all_flags
11
+ redis.hgetall(flags_hkey).keys.inject({}) { |h, f| h[f] = enabled? f; h }
12
+ end
13
+
14
+ def all_ramps
15
+ redis.hgetall(ramps_hkey).keys.inject({}) { |h, f| h[f] = ramp_val f; h }
16
+ end
17
+
18
+ def flags_hkey
19
+ "featureguard_flags"
20
+ end
21
+
22
+ def ramps_hkey
23
+ "featureguard_ramps"
24
+ end
25
+
10
26
  def redis
11
27
  @redis ||= Redis.new
12
28
  end
13
29
 
14
- [:allow?, :bump_ramp, :disable, :enable, :toggle, :enabled?, :ramp_val, :set_ramp].each do |mname|
30
+ [
31
+ :allow?, :bump_ramp, :disable, :enable, :toggle, :enabled?,
32
+ :ramp_val, :set_ramp
33
+ ].each do |mname|
15
34
  define_method(mname) do |key, *args|
16
35
  Guard.new(key).send(mname, *args)
17
36
  end
@@ -7,15 +7,15 @@ module FeatureGuard; class Guard
7
7
 
8
8
  # binary flag methods (enabled/disabled)
9
9
  def disable
10
- redis.set(flag_key, 0)
10
+ redis.hset(FeatureGuard.flags_hkey, feature_name, 0)
11
11
  end
12
12
 
13
13
  def enable
14
- redis.set(flag_key, 1)
14
+ redis.hset(FeatureGuard.flags_hkey, feature_name, 1)
15
15
  end
16
16
 
17
17
  def enabled?
18
- redis.get(flag_key).tap { |v| return (!v.nil? && v.to_i > 0) }
18
+ redis.hget(FeatureGuard.flags_hkey, feature_name).tap { |v| return (!v.nil? && v.to_i > 0) }
19
19
  rescue
20
20
  false
21
21
  end
@@ -35,7 +35,7 @@ module FeatureGuard; class Guard
35
35
  end
36
36
 
37
37
  def ramp_val
38
- redis.get(ramp_key).to_f
38
+ redis.hget(FeatureGuard.ramps_hkey, feature_name).to_f
39
39
  end
40
40
 
41
41
  def set_ramp(new_val)
@@ -43,26 +43,14 @@ module FeatureGuard; class Guard
43
43
  new_val = 100.0 if new_val > 100.0
44
44
  new_val = 0.0 if new_val < 0.0
45
45
 
46
- redis.set(ramp_key, new_val)
46
+ redis.hset(FeatureGuard.ramps_hkey, feature_name, new_val)
47
47
  new_val
48
48
  end
49
49
 
50
50
  private
51
51
 
52
- def feature_key
53
- @feature_key ||= feature_name.to_s.split.join('_')
54
- end
55
-
56
- def flag_key
57
- @flag_key ||= "fgf_#{feature_key}"
58
- end
59
-
60
- def ramp_key
61
- @ramp_key ||= "fgr_#{feature_key}"
62
- end
63
-
64
52
  def hashed_val(s)
65
- (Digest::MD5.hexdigest("#{ramp_key}_#{s}").to_i(16) % 10000).to_f / 100.0
53
+ (Digest::MD5.hexdigest("#{feature_name}_#{s}").to_i(16) % 10000).to_f / 100.0
66
54
  end
67
55
 
68
56
  def random_val
@@ -1,3 +1,3 @@
1
1
  module FeatureGuard
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -12,7 +12,7 @@ describe FeatureGuard::Guard do
12
12
 
13
13
  it 'uses a random value' do
14
14
  expect(guard).to receive(:random_val).and_return(29.9)
15
- expect(subject).to be_true
15
+ expect(subject).to eq(true)
16
16
  end
17
17
  end
18
18
 
@@ -21,7 +21,7 @@ describe FeatureGuard::Guard do
21
21
 
22
22
  it 'hashes the value together with the feature name' do
23
23
  expect(guard).to receive(:hashed_val).and_return(30.1)
24
- expect(subject).to be_false
24
+ expect(subject).to eq(false)
25
25
  end
26
26
  end
27
27
  end
@@ -42,13 +42,13 @@ describe FeatureGuard::Guard do
42
42
  subject { guard.enabled? }
43
43
 
44
44
  context 'for a non-existent flag' do
45
- it { should be_false }
45
+ it { is_expected.to eq(false) }
46
46
  end
47
47
 
48
48
  context 'for an enabled flag' do
49
49
  before { guard.enable }
50
50
 
51
- it { should be_true }
51
+ it { is_expected.to eq(true) }
52
52
  end
53
53
  end
54
54
 
@@ -41,13 +41,53 @@ describe FeatureGuard do
41
41
  subject { FeatureGuard.enabled? feature }
42
42
 
43
43
  context 'for a non-existent flag' do
44
- it { should be_false }
44
+ it { is_expected.to eq(false) }
45
45
  end
46
46
 
47
47
  context 'when the Redis client blows up or is non-existent' do
48
48
  before { FeatureGuard.stub(redis: nil) }
49
49
 
50
- it { should be_false }
50
+ it { is_expected.to eq(false) }
51
+ end
52
+ end
53
+
54
+ describe '.all_flags' do
55
+ subject { FeatureGuard.all_flags }
56
+
57
+ it 'returns information on enabled flags' do
58
+ expect {
59
+ FeatureGuard.enable feature
60
+ }.to change {
61
+ FeatureGuard.all_flags
62
+ }.from({}).to({feature.to_s => true})
63
+ end
64
+
65
+ it 'returns information on multiple flags' do
66
+ FeatureGuard.enable feature
67
+ FeatureGuard.enable 'another feature'
68
+ expect(subject.keys.size).to eq(2)
69
+ expect(subject.keys).to include(feature.to_s)
70
+ expect(subject.keys).to include('another feature')
71
+ end
72
+ end
73
+
74
+ describe '.all_ramps' do
75
+ subject { FeatureGuard.all_ramps }
76
+
77
+ it 'returns information on ramped flags' do
78
+ expect {
79
+ FeatureGuard.set_ramp feature, 50
80
+ }.to change {
81
+ FeatureGuard.all_ramps
82
+ }.from({}).to({feature.to_s => 50.0})
83
+ end
84
+
85
+ it 'returns information on multiple flags' do
86
+ FeatureGuard.set_ramp feature, 99
87
+ FeatureGuard.set_ramp 'another feature', 33
88
+ expect(subject.keys.size).to eq(2)
89
+ expect(subject.keys).to include(feature.to_s)
90
+ expect(subject.keys).to include('another feature')
51
91
  end
52
92
  end
53
93
  end
metadata CHANGED
@@ -1,57 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feature_guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ted Dumitrescu
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-11-01 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: redis
16
- requirement: &2164445320 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *2164445320
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: fakeredis
27
- requirement: &2164444580 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - ~>
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0.4'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *2164444580
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.4'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rspec
38
- requirement: &2164444120 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
45
  - - ~>
42
46
  - !ruby/object:Gem::Version
43
- version: '2.13'
47
+ version: '2.99'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *2164444120
47
- description: ! 'Feature flags made simple: turn code on or off with Redis controls,
48
- allowing
49
-
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.99'
55
+ description: |
56
+ Feature flags made simple: turn code on or off with Redis controls, allowing
50
57
  plain enabled/disabled states as well as finer-grained percentage-based control.
51
-
52
- '
53
58
  email:
54
- - miscmisc@cmme.org
59
+ - webdev@cmme.org
55
60
  executables: []
56
61
  extensions: []
57
62
  extra_rdoc_files: []
@@ -72,30 +77,28 @@ files:
72
77
  homepage: https://github.com/tdumitrescu/feature_guard
73
78
  licenses:
74
79
  - MIT
80
+ metadata: {}
75
81
  post_install_message:
76
82
  rdoc_options: []
77
83
  require_paths:
78
84
  - lib
79
85
  required_ruby_version: !ruby/object:Gem::Requirement
80
- none: false
81
86
  requirements:
82
- - - ! '>='
87
+ - - '>='
83
88
  - !ruby/object:Gem::Version
84
89
  version: '0'
85
90
  required_rubygems_version: !ruby/object:Gem::Requirement
86
- none: false
87
91
  requirements:
88
- - - ! '>='
92
+ - - '>='
89
93
  - !ruby/object:Gem::Version
90
94
  version: '0'
91
95
  requirements: []
92
96
  rubyforge_project:
93
- rubygems_version: 1.8.10
97
+ rubygems_version: 2.0.14
94
98
  signing_key:
95
- specification_version: 3
99
+ specification_version: 4
96
100
  summary: Simple Redis-based feature-flagging
97
101
  test_files:
98
102
  - spec/feature_guard/guard_spec.rb
99
103
  - spec/feature_guard_spec.rb
100
104
  - spec/spec_helper.rb
101
- has_rdoc: