offs 1.0.0 → 1.1.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/README.md +4 -2
- data/lib/offs/flags.rb +45 -0
- data/lib/offs/permutations.rb +28 -0
- data/lib/offs/version.rb +1 -1
- data/lib/offs.rb +11 -27
- data/spec/offs/permutations_spec.rb +35 -0
- data/spec/offs_spec.rb +9 -7
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc1b08f770214df36eb4c408459b0060fc9dd8af
|
4
|
+
data.tar.gz: 43f9ab69b33a234eae79f53555c52772933628ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb477f36c3cac9362b242d04ca9b66019a4d888131f1543ce9168d35f61fde7d683122dbefcddab14ef3ed18ea949a6aa6d7069733b1b1980eb91ffdef3e7b01
|
7
|
+
data.tar.gz: 4ffce2d90133a5072a75bb2085e68faf20a8a366ae1da7a82a87565cc371db79b7e2dc3e1655644430a4740ae235e6abc64fe99299b0a49d17e332a0a812efd2
|
data/README.md
CHANGED
@@ -38,8 +38,10 @@ you could put the following in `config/initializers/offs_flags.rb`:
|
|
38
38
|
```ruby
|
39
39
|
require 'offs'
|
40
40
|
|
41
|
-
OFFS.
|
42
|
-
|
41
|
+
OFFS::Flags.set do |offs|
|
42
|
+
offs.flag :use_my_million_dollar_idea, false
|
43
|
+
offs.flag :use_this_mostly_done_feature, true
|
44
|
+
end
|
43
45
|
```
|
44
46
|
|
45
47
|
You've now defined the flags that your app will use, and you've given
|
data/lib/offs/flags.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
class OFFS
|
2
|
+
class Flags
|
3
|
+
UndefinedFlagError = Class.new(StandardError)
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def instance
|
7
|
+
@instance ||= new
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(&block)
|
11
|
+
block.call(instance)
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def flag(name, default)
|
17
|
+
env_var_name = name.to_s.upcase
|
18
|
+
feature_flags[name] = if ENV.has_key?(env_var_name)
|
19
|
+
ENV[env_var_name].strip == '1'
|
20
|
+
else
|
21
|
+
default
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def feature_flags
|
26
|
+
@feature_flags ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def enabled?(flag)
|
30
|
+
!!feature_flags[flag]
|
31
|
+
end
|
32
|
+
|
33
|
+
def valid?(flag)
|
34
|
+
feature_flags.has_key?(flag)
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate!(flag)
|
38
|
+
if valid?(flag)
|
39
|
+
flag
|
40
|
+
else
|
41
|
+
raise UndefinedFlagError, "The #{flag} flag has not been defined."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'injectable_dependencies'
|
3
|
+
|
4
|
+
class OFFS
|
5
|
+
class Permutations < DelegateClass(Enumerator)
|
6
|
+
include InjectableDependencies
|
7
|
+
|
8
|
+
dependency(:flags) { Flags.instance }
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
initialize_dependencies(options[:dependencies])
|
12
|
+
__setobj__ create_permutations
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def create_permutations
|
18
|
+
keys = flags.to_a
|
19
|
+
permutations = [true,false].repeated_permutation(keys.size).map { |values|
|
20
|
+
keys.zip(values).inject({}) { |m, pair|
|
21
|
+
m[pair[0]] = pair[1]
|
22
|
+
m
|
23
|
+
}
|
24
|
+
}
|
25
|
+
permutations.each
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/offs/version.rb
CHANGED
data/lib/offs.rb
CHANGED
@@ -1,31 +1,17 @@
|
|
1
1
|
require "offs/version"
|
2
|
+
require 'offs/flags'
|
2
3
|
require 'injectable_dependencies'
|
3
4
|
|
4
5
|
class OFFS
|
5
6
|
include InjectableDependencies
|
6
7
|
|
7
|
-
UndefinedFlagError = Class.new(StandardError)
|
8
|
-
|
9
8
|
class << self
|
10
9
|
def so_you_want_to(flag, &block)
|
11
10
|
new(flag).so_you_want_to(&block)
|
12
11
|
end
|
13
|
-
|
14
|
-
def flag(name, default)
|
15
|
-
env_var_name = name.to_s.upcase
|
16
|
-
feature_flags[name] = if ENV.has_key?(env_var_name)
|
17
|
-
ENV[env_var_name].strip == '1'
|
18
|
-
else
|
19
|
-
default
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def feature_flags
|
24
|
-
@feature_flags ||= {}
|
25
|
-
end
|
26
12
|
end
|
27
13
|
|
28
|
-
dependency(:feature_flags) {
|
14
|
+
dependency(:feature_flags) { Flags.instance }
|
29
15
|
|
30
16
|
def initialize(flag, options={})
|
31
17
|
initialize_dependencies options[:dependencies]
|
@@ -37,28 +23,26 @@ class OFFS
|
|
37
23
|
end
|
38
24
|
|
39
25
|
def would_like_to(&block)
|
40
|
-
|
41
|
-
block.call
|
26
|
+
when_flag(true, &block)
|
42
27
|
end
|
43
28
|
|
44
29
|
def may_still_need_to(&block)
|
45
|
-
|
46
|
-
block.call
|
30
|
+
when_flag(false, &block)
|
47
31
|
end
|
48
32
|
|
49
33
|
private
|
50
34
|
|
51
35
|
attr_reader :flag
|
52
36
|
|
53
|
-
def
|
54
|
-
|
37
|
+
def when_flag(bool, &block)
|
38
|
+
block.call if flag_status == bool
|
39
|
+
end
|
40
|
+
|
41
|
+
def flag_status
|
42
|
+
feature_flags.enabled?(flag)
|
55
43
|
end
|
56
44
|
|
57
45
|
def flag=(new_flag)
|
58
|
-
|
59
|
-
@flag = new_flag
|
60
|
-
else
|
61
|
-
raise UndefinedFlagError, "The #{new_flag} flag has not been defined."
|
62
|
-
end
|
46
|
+
@flag = feature_flags.validate!(new_flag)
|
63
47
|
end
|
64
48
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'offs/permutations'
|
3
|
+
|
4
|
+
describe OFFS::Permutations do
|
5
|
+
subject { described_class.new(dependencies: dependencies) }
|
6
|
+
|
7
|
+
let(:dependencies) {{
|
8
|
+
flags: flags
|
9
|
+
}}
|
10
|
+
|
11
|
+
let(:flags) { double(:flags, to_a: [:feature_a, :feature_b, :feature_c]) }
|
12
|
+
|
13
|
+
let(:possible_permutations) {[
|
14
|
+
{ feature_a: true, feature_b: true, feature_c: true },
|
15
|
+
{ feature_a: false, feature_b: true, feature_c: true },
|
16
|
+
{ feature_a: true, feature_b: false, feature_c: true },
|
17
|
+
{ feature_a: true, feature_b: true, feature_c: false },
|
18
|
+
{ feature_a: false, feature_b: false, feature_c: true },
|
19
|
+
{ feature_a: false, feature_b: true, feature_c: false },
|
20
|
+
{ feature_a: true, feature_b: false, feature_c: false },
|
21
|
+
{ feature_a: false, feature_b: false, feature_c: false },
|
22
|
+
]}
|
23
|
+
|
24
|
+
let(:receiver) { double(:receiver) }
|
25
|
+
|
26
|
+
it 'yields every permutation of feature flag combinations' do
|
27
|
+
possible_permutations.each do |permutation|
|
28
|
+
expect(receiver).to receive(:flags).with(permutation)
|
29
|
+
end
|
30
|
+
|
31
|
+
subject.each do |flags|
|
32
|
+
receiver.flags(flags)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/offs_spec.rb
CHANGED
@@ -13,18 +13,18 @@ describe OFFS do
|
|
13
13
|
feature_flags: feature_flags
|
14
14
|
}}
|
15
15
|
|
16
|
-
let(:feature_flags) {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
let(:feature_flags) {
|
17
|
+
OFFS::Flags.set do |f|
|
18
|
+
f.flag :my_cool_new_feature, feature_status
|
19
|
+
end
|
20
|
+
}
|
21
21
|
|
22
22
|
context 'when the specified feature flag is not defined' do
|
23
|
-
let(:feature_flags) {
|
23
|
+
let(:feature_flags) { OFFS::Flags.new }
|
24
24
|
|
25
25
|
it 'raises an error' do
|
26
26
|
expect{ subject.so_you_want_to {} }.to \
|
27
|
-
raise_error(OFFS::UndefinedFlagError,
|
27
|
+
raise_error(OFFS::Flags::UndefinedFlagError,
|
28
28
|
"The #{flag} flag has not been defined.")
|
29
29
|
end
|
30
30
|
end
|
@@ -41,6 +41,8 @@ describe OFFS do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
context "and the feature is turned on by default" do
|
44
|
+
let(:feature_status) { true }
|
45
|
+
|
44
46
|
it 'executes the would_like_to block' do
|
45
47
|
expect(would_like_to_blk).to receive(:call)
|
46
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: offs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Wilger
|
@@ -85,8 +85,11 @@ files:
|
|
85
85
|
- README.md
|
86
86
|
- Rakefile
|
87
87
|
- lib/offs.rb
|
88
|
+
- lib/offs/flags.rb
|
89
|
+
- lib/offs/permutations.rb
|
88
90
|
- lib/offs/version.rb
|
89
91
|
- offs.gemspec
|
92
|
+
- spec/offs/permutations_spec.rb
|
90
93
|
- spec/offs_spec.rb
|
91
94
|
- spec/spec_helper.rb
|
92
95
|
homepage: ''
|
@@ -114,5 +117,6 @@ signing_key:
|
|
114
117
|
specification_version: 4
|
115
118
|
summary: OFFS Feature Flagging System
|
116
119
|
test_files:
|
120
|
+
- spec/offs/permutations_spec.rb
|
117
121
|
- spec/offs_spec.rb
|
118
122
|
- spec/spec_helper.rb
|