togls 2.2.1 → 3.0.0.pre.rc.1
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/.ruby-version +1 -1
- data/CHANGELOG.md +107 -36
- data/README.md +12 -9
- data/lib/togls/default_feature_target_type_manager.rb +25 -0
- data/lib/togls/errors.rb +15 -4
- data/lib/togls/feature.rb +13 -1
- data/lib/togls/feature_repository.rb +28 -2
- data/lib/togls/feature_toggle_registry_manager.rb +138 -0
- data/lib/togls/helpers.rb +2 -2
- data/lib/togls/null_toggle.rb +4 -1
- data/lib/togls/rule.rb +29 -3
- data/lib/togls/rule_repository.rb +36 -3
- data/lib/togls/rule_repository_drivers/env_override_driver.rb +22 -0
- data/lib/togls/rule_type_registry.rb +38 -0
- data/lib/togls/rule_type_repository.rb +57 -0
- data/lib/togls/rule_type_repository_drivers/in_memory_driver.rb +52 -0
- data/lib/togls/rule_type_repository_drivers.rb +5 -0
- data/lib/togls/rules/boolean.rb +21 -1
- data/lib/togls/rules/group.rb +26 -0
- data/lib/togls/target_types.rb +9 -0
- data/lib/togls/toggle.rb +57 -13
- data/lib/togls/toggle_registry.rb +45 -0
- data/lib/togls/toggle_repository.rb +20 -5
- data/lib/togls/toggler.rb +6 -2
- data/lib/togls/version.rb +1 -1
- data/lib/togls.rb +11 -4
- data/togls.gemspec +1 -1
- metadata +15 -10
- data/lib/tasks/togls.rake +0 -9
- data/lib/togls/feature_toggle_registry.rb +0 -57
- data/lib/togls/release_toggle_registry_manager.rb +0 -43
- data/lib/togls/test_toggle_registry.rb +0 -26
@@ -0,0 +1,22 @@
|
|
1
|
+
module Togls
|
2
|
+
module RuleRepositoryDrivers
|
3
|
+
# Rule Repository Environment Override Driver
|
4
|
+
#
|
5
|
+
# The Rule Repository Environment Driver provides the interface to store and
|
6
|
+
# retrieve rules. This is intended to be used by a Rule Repository instance.
|
7
|
+
class EnvOverrideDriver
|
8
|
+
def store(rule_id, rule_data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(rule_id)
|
12
|
+
if rule_id == Togls::Helpers.sha1(Togls::Rules::Boolean, true)
|
13
|
+
return { 'type_id' => 'boolean', 'data' => true, 'target_type' => Togls::TargetTypes::NONE.to_s }
|
14
|
+
elsif rule_id == Togls::Helpers.sha1(Togls::Rules::Boolean, false)
|
15
|
+
return { 'type_id' => 'boolean', 'data' => false, 'target_type' => Togls::TargetTypes::NONE.to_s }
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Togls
|
2
|
+
class RuleTypeRegistry
|
3
|
+
def initialize(rule_type_repository)
|
4
|
+
@rule_type_repository = rule_type_repository
|
5
|
+
end
|
6
|
+
|
7
|
+
def expand(&block)
|
8
|
+
instance_eval(&block)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def register(type_id, klass)
|
13
|
+
verify_uniqueness_of_type_id(type_id)
|
14
|
+
verify_uniqueness_of_rule_type_klass(klass)
|
15
|
+
@rule_type_repository.store(type_id, klass)
|
16
|
+
end
|
17
|
+
|
18
|
+
def verify_uniqueness_of_type_id(type_id)
|
19
|
+
if @rule_type_repository.include?(type_id)
|
20
|
+
raise RuleTypeAlreadyDefined, "Rule Type identified by '#{type_id}' has already been registered"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def verify_uniqueness_of_rule_type_klass(klass)
|
25
|
+
if @rule_type_repository.include_klass?(klass)
|
26
|
+
raise RuleTypeAlreadyDefined, "Rule Type with class '#{klass}' has already been registered"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get(type_id)
|
31
|
+
@rule_type_repository.get_klass(type_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_type_id(klass_string)
|
35
|
+
@rule_type_repository.get_type_id(klass_string)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Togls
|
2
|
+
class RuleTypeRepository
|
3
|
+
def initialize(drivers)
|
4
|
+
@drivers = drivers
|
5
|
+
end
|
6
|
+
|
7
|
+
def store(type_id, klass)
|
8
|
+
@drivers.each do |driver|
|
9
|
+
driver.store(type_id.to_s, klass.to_s, klass.title, klass.description,
|
10
|
+
klass.target_type.to_s)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def include?(type_id)
|
15
|
+
type = get_klass(type_id)
|
16
|
+
type ? true : false
|
17
|
+
end
|
18
|
+
|
19
|
+
def include_klass?(klass)
|
20
|
+
type = get_type_id(klass)
|
21
|
+
type ? true : false
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_klass(type_id)
|
25
|
+
klass_string = fetch_klass_string(type_id.to_s)
|
26
|
+
return Object.const_get(klass_string) if klass_string
|
27
|
+
klass_string
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_type_id(klass)
|
31
|
+
fetch_type_id(klass.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def reverse_drivers(&block)
|
37
|
+
val = nil
|
38
|
+
@drivers.reverse.each do |driver|
|
39
|
+
val = block.call(driver) if block_given?
|
40
|
+
break if val
|
41
|
+
end
|
42
|
+
val
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_klass_string(type_id)
|
46
|
+
reverse_drivers do |driver|
|
47
|
+
driver.get_klass(type_id)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_type_id(klass_str)
|
52
|
+
reverse_drivers do |driver|
|
53
|
+
driver.get_type_id(klass_str)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Togls
|
2
|
+
module RuleTypeRepositoryDrivers
|
3
|
+
class InMemoryDriver
|
4
|
+
def initialize
|
5
|
+
@rule_types = {}
|
6
|
+
@rule_type_meta_data = {}
|
7
|
+
@type_ids = {}
|
8
|
+
@rule_types_lock = Mutex.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def store(type_id, klass_str, title, description, target_type)
|
12
|
+
@rule_types_lock.synchronize do
|
13
|
+
@rule_types[type_id] = klass_str
|
14
|
+
@rule_type_meta_data[type_id] = { title: title,
|
15
|
+
description: description,
|
16
|
+
target_type: target_type }
|
17
|
+
@type_ids[klass_str] = type_id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_klass(type_id)
|
22
|
+
@rule_types_lock.synchronize do
|
23
|
+
if @rule_types.has_key?(type_id)
|
24
|
+
@rule_types[type_id].dup
|
25
|
+
else
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_type_meta_data(type_id)
|
32
|
+
@rule_types_lock.synchronize do
|
33
|
+
if @rule_types.has_key?(type_id)
|
34
|
+
@rule_type_meta_data[type_id].dup
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_type_id(klass_str)
|
42
|
+
@rule_types_lock.synchronize do
|
43
|
+
if @type_ids.has_key?(klass_str)
|
44
|
+
@type_ids[klass_str].dup
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/togls/rules/boolean.rb
CHANGED
@@ -6,7 +6,7 @@ module Togls
|
|
6
6
|
# it's initialization data and when evaluated determines the toggle state
|
7
7
|
# based on the initialization value. Example:
|
8
8
|
#
|
9
|
-
# always_on = Togls::Rules::Boolean.new(true)
|
9
|
+
# always_on = Togls::Rules::Boolean.new(:boolean, true)
|
10
10
|
# Togls.features do
|
11
11
|
# feature(:foo).on(always_on)
|
12
12
|
# end
|
@@ -15,6 +15,26 @@ module Togls
|
|
15
15
|
# ...
|
16
16
|
# end
|
17
17
|
class Boolean < Rule
|
18
|
+
def self.title
|
19
|
+
"Boolean"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.description
|
23
|
+
%Q{
|
24
|
+
The Boolean rule type is the base line rule for Togls. It allows you to
|
25
|
+
flag a feature on/off by specifing a boolean value as the initialization
|
26
|
+
data. For example:
|
27
|
+
|
28
|
+
Togls::Rules::Boolean.new(:boolean, true) # rule that always evaluates to on
|
29
|
+
|
30
|
+
Togls::Rules::Boolean.new(:boolean, false) # rule that always evaluates to off
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.target_type
|
35
|
+
Togls::TargetTypes::NONE
|
36
|
+
end
|
37
|
+
|
18
38
|
def run(_key, _target = nil)
|
19
39
|
@data
|
20
40
|
end
|
data/lib/togls/rules/group.rb
CHANGED
@@ -17,6 +17,32 @@ module Togls
|
|
17
17
|
# ...
|
18
18
|
# end
|
19
19
|
class Group < Rule
|
20
|
+
def self.title
|
21
|
+
"Group"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.description
|
25
|
+
%Q{
|
26
|
+
The Group rule allows you to define an arbitrary collection of objects to be
|
27
|
+
used in evaluating against the target. Specify the initialization data as an
|
28
|
+
array of inclusive identifiers for the group. When the feature toggle is
|
29
|
+
evaluated if the passed in target is included in the group then it is evaluated
|
30
|
+
to on. If not, it evaluates to off. Examples:
|
31
|
+
|
32
|
+
# Group defined by user ids
|
33
|
+
alpha_testers = Togls::Rules::Group.new([23, 343, 222, 123])
|
34
|
+
|
35
|
+
# Group defined by email addresses
|
36
|
+
beta_testers = Togls::Rules::Group.new(['bob@example.com', 'cindy@example.com'])
|
37
|
+
|
38
|
+
Togls.release do
|
39
|
+
feature(:foo, 'some foo desc').on(beta_testers)
|
40
|
+
end
|
41
|
+
|
42
|
+
Togls.feature(:foo).on?('jack@example.com') # evalutes to false (a.k.a. off)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
20
46
|
def run(_key, target)
|
21
47
|
@data.include?(target)
|
22
48
|
end
|
data/lib/togls/toggle.rb
CHANGED
@@ -5,34 +5,78 @@ module Togls
|
|
5
5
|
# responsibility is binding a specific rule to a specific feature. Toggle's by
|
6
6
|
# default are associated with a boolean rule initialized to false.
|
7
7
|
class Toggle
|
8
|
-
attr_reader :feature
|
9
|
-
attr_accessor :rule
|
8
|
+
attr_reader :feature, :rule
|
10
9
|
|
11
10
|
def initialize(feature)
|
12
11
|
@feature = feature
|
13
|
-
@rule = Togls::Rules::Boolean.new(false)
|
12
|
+
@rule = Togls::Rules::Boolean.new(:boolean, false)
|
14
13
|
end
|
15
14
|
|
16
15
|
def id
|
17
16
|
@feature.id
|
18
17
|
end
|
19
18
|
|
19
|
+
def rule=(rule)
|
20
|
+
raise Togls::RuleFeatureTargetTypeMismatch unless target_matches?(rule)
|
21
|
+
@rule = rule
|
22
|
+
end
|
23
|
+
|
24
|
+
# feature target type | rule target type | match? | notes
|
25
|
+
# -------------------------------------------------------
|
26
|
+
# NOT_SET | NONE | true |
|
27
|
+
# NONE | NONE | true |
|
28
|
+
# something (foo) | NONE | true |
|
29
|
+
# NOT_SET | NOT_SET | false | broken - shouldn't happen
|
30
|
+
# NONE | NOT_SET | false | broken - shouldn't happen
|
31
|
+
# something (foo) | NOT_SET | false | broken - shouldn't happen
|
32
|
+
# NOT_SET | something (foo) | false | broken - shouldn't happen
|
33
|
+
# NONE | something (foo) | false |
|
34
|
+
# something (foo) | something (foo) | true |
|
35
|
+
# something (foo) | something (bar) | false |
|
36
|
+
def target_matches?(rule)
|
37
|
+
if rule.target_type == Togls::TargetTypes::NONE
|
38
|
+
return true
|
39
|
+
elsif rule.target_type == Togls::TargetTypes::NOT_SET
|
40
|
+
Togls.logger.warn "Rule (id: #{rule.id}) cannot have target type of :not_set"
|
41
|
+
return false
|
42
|
+
elsif @feature.target_type == Togls::TargetTypes::NOT_SET
|
43
|
+
Togls.logger.warn "Feature (key: #{feature.key}) cannot have target type of :not_set when rule (id: #{rule.id}) specifies a target type (target_type: #{rule.target_type}"
|
44
|
+
return false
|
45
|
+
elsif rule.target_type == @feature.target_type
|
46
|
+
return true
|
47
|
+
else
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# feature.target_type | target.nil? | valid target
|
53
|
+
# NONE | false | FALSE - EXCEPTION
|
54
|
+
# :foo | true | FALSE - EXCEPTION
|
55
|
+
# NONE | true | true
|
56
|
+
# :foo | false | true
|
57
|
+
# NOT_SET | ignored | true - broken
|
58
|
+
# EITHER | true | true
|
59
|
+
# EITHER | false | true
|
60
|
+
def validate_target(target)
|
61
|
+
is_explicit_target_type = @feature.target_type != Togls::TargetTypes::NONE &&
|
62
|
+
@feature.target_type != Togls::TargetTypes::NOT_SET &&
|
63
|
+
@feature.target_type != Togls::TargetTypes::EITHER
|
64
|
+
if @feature.target_type == Togls::TargetTypes::NONE && target
|
65
|
+
raise Togls::UnexpectedEvaluationTarget
|
66
|
+
elsif is_explicit_target_type && target.nil?
|
67
|
+
raise Togls::EvaluationTargetMissing
|
68
|
+
end
|
69
|
+
# Is valid
|
70
|
+
end
|
71
|
+
|
20
72
|
def on?(target = nil)
|
73
|
+
validate_target(target)
|
21
74
|
@rule.run(@feature.key, target)
|
22
75
|
end
|
23
76
|
|
24
77
|
def off?(target = nil)
|
78
|
+
validate_target(target)
|
25
79
|
!@rule.run(@feature.key, target)
|
26
80
|
end
|
27
|
-
|
28
|
-
def to_s
|
29
|
-
display_value = if @rule.is_a?(Togls::Rules::Boolean)
|
30
|
-
@rule.run(@feature.key) ? ' on' : 'off'
|
31
|
-
else
|
32
|
-
' ?'
|
33
|
-
end
|
34
|
-
|
35
|
-
"#{display_value} - #{@feature.key} - #{@feature.description}"
|
36
|
-
end
|
37
81
|
end
|
38
82
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Togls
|
2
|
+
# Toggle Registry
|
3
|
+
#
|
4
|
+
# The Toggle Registry conceptually houses a registry of toggles. It
|
5
|
+
# accomplishes this by interfacing with the provided feature
|
6
|
+
# repository, and toggle repository. This plays a significant portion
|
7
|
+
# in the primary DSL as well.
|
8
|
+
class ToggleRegistry
|
9
|
+
def initialize(feature_repository, toggle_repository)
|
10
|
+
@feature_repository = feature_repository
|
11
|
+
@toggle_repository = toggle_repository
|
12
|
+
end
|
13
|
+
|
14
|
+
def expand(&block)
|
15
|
+
instance_eval(&block)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def feature(key, desc, target_type: Togls.default_feature_target_type)
|
20
|
+
verify_uniqueness_of_feature(key)
|
21
|
+
feature = Togls::Feature.new(key, desc, target_type)
|
22
|
+
toggle = Togls::Toggle.new(feature)
|
23
|
+
@toggle_repository.store(toggle)
|
24
|
+
Togls::Toggler.new(@toggle_repository, toggle)
|
25
|
+
end
|
26
|
+
|
27
|
+
def verify_uniqueness_of_feature(key)
|
28
|
+
if @feature_repository.include?(key.to_s)
|
29
|
+
raise FeatureAlreadyDefined, "Feature identified by '#{key}' has already been defined"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(key)
|
34
|
+
toggle = @toggle_repository.get(key.to_s)
|
35
|
+
if toggle.is_a?(Togls::ToggleMissingToggle)
|
36
|
+
Togls.logger.warn("Feature identified by '#{key}' has not been defined")
|
37
|
+
end
|
38
|
+
toggle
|
39
|
+
end
|
40
|
+
|
41
|
+
def all
|
42
|
+
@toggle_repository.all
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -32,15 +32,30 @@ module Togls
|
|
32
32
|
def get(id)
|
33
33
|
toggle_data = fetch_toggle_data(id)
|
34
34
|
return reconstitute_toggle(toggle_data) if toggle_data
|
35
|
-
Togls::
|
35
|
+
Togls::ToggleMissingToggle.new
|
36
36
|
end
|
37
37
|
|
38
38
|
def reconstitute_toggle(toggle_data)
|
39
|
-
|
40
|
-
|
39
|
+
begin
|
40
|
+
feature = @feature_repository.get(toggle_data['feature_id'])
|
41
|
+
rescue Togls::RepositoryFeatureDataInvalid => e
|
42
|
+
return Togls::NullToggle.new
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
rule = @rule_repository.get(toggle_data['rule_id'])
|
47
|
+
rescue Togls::RepositoryRuleDataInvalid => e
|
48
|
+
return Togls::NullToggle.new
|
49
|
+
end
|
50
|
+
|
41
51
|
toggle = Togls::Toggle.new(feature)
|
42
|
-
|
43
|
-
|
52
|
+
begin
|
53
|
+
toggle.rule = rule
|
54
|
+
toggle
|
55
|
+
rescue Togls::RuleFeatureTargetTypeMismatch
|
56
|
+
Togls.logger.warn("Feature (#{feature.key}) with target type '#{feature.target_type}' has a rule (#{rule.id}) mismatch with target type '#{rule.target_type}'")
|
57
|
+
return Togls::RuleFeatureMismatchToggle.new
|
58
|
+
end
|
44
59
|
end
|
45
60
|
|
46
61
|
def fetch_toggle_data(id)
|
data/lib/togls/toggler.rb
CHANGED
@@ -1,23 +1,27 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
module Togls
|
2
3
|
# Toggle Toggler
|
3
4
|
#
|
4
5
|
# The Toggle Toggler provides the convenience interface of being able to
|
5
6
|
# toggle a feature on/off via the `on` or `off` methods respectively.
|
6
7
|
class Toggler
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :@toggle, :on?, :off?, :feature, :rule
|
10
|
+
|
7
11
|
def initialize(toggle_repository, toggle)
|
8
12
|
@toggle_repository = toggle_repository
|
9
13
|
@toggle = toggle
|
10
14
|
end
|
11
15
|
|
12
16
|
def on(rule = nil)
|
13
|
-
rule = Togls::Rules::Boolean.new(true) if rule.nil?
|
17
|
+
rule = Togls::Rules::Boolean.new(:boolean, true) if rule.nil?
|
14
18
|
@toggle.rule = rule
|
15
19
|
@toggle_repository.store(@toggle)
|
16
20
|
@toggle
|
17
21
|
end
|
18
22
|
|
19
23
|
def off
|
20
|
-
rule = Togls::Rules::Boolean.new(false)
|
24
|
+
rule = Togls::Rules::Boolean.new(:boolean, false)
|
21
25
|
@toggle.rule = rule
|
22
26
|
@toggle_repository.store(@toggle)
|
23
27
|
@toggle
|
data/lib/togls/version.rb
CHANGED
data/lib/togls.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'togls/version'
|
2
2
|
require 'togls/errors'
|
3
3
|
require 'togls/helpers'
|
4
|
+
require 'togls/target_types'
|
4
5
|
require 'togls/toggle_repository_drivers'
|
5
6
|
require 'togls/toggle_repository_drivers/in_memory_driver'
|
6
7
|
require 'togls/toggle_repository_drivers/env_override_driver'
|
@@ -8,9 +9,13 @@ require 'togls/feature_repository_drivers'
|
|
8
9
|
require 'togls/feature_repository_drivers/in_memory_driver'
|
9
10
|
require 'togls/rule_repository_drivers'
|
10
11
|
require 'togls/rule_repository_drivers/in_memory_driver'
|
12
|
+
require 'togls/rule_repository_drivers/env_override_driver'
|
13
|
+
require 'togls/rule_type_repository_drivers'
|
14
|
+
require 'togls/rule_type_repository_drivers/in_memory_driver'
|
11
15
|
require 'togls/toggler'
|
12
|
-
require 'togls/
|
13
|
-
require 'togls/
|
16
|
+
require 'togls/rule_type_repository'
|
17
|
+
require 'togls/rule_type_registry'
|
18
|
+
require 'togls/toggle_registry'
|
14
19
|
require 'togls/feature_repository'
|
15
20
|
require 'togls/rule_repository'
|
16
21
|
require 'togls/toggle_repository'
|
@@ -20,12 +25,14 @@ require 'togls/null_toggle'
|
|
20
25
|
require 'togls/rule'
|
21
26
|
require 'togls/rules'
|
22
27
|
require 'logger'
|
23
|
-
require 'togls/
|
28
|
+
require 'togls/feature_toggle_registry_manager'
|
29
|
+
require 'togls/default_feature_target_type_manager'
|
24
30
|
|
25
31
|
# Togls
|
26
32
|
#
|
27
33
|
# Togls is the primary interface to the out of the box toggle registry. It is
|
28
34
|
# the namespace the DSL is exposed under.
|
29
35
|
module Togls
|
30
|
-
include
|
36
|
+
include FeatureToggleRegistryManager
|
37
|
+
include DefaultFeatureTargetTypeManager
|
31
38
|
end
|
data/togls.gemspec
CHANGED
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_development_dependency 'bundler', '~> 1.9'
|
29
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
31
31
|
spec.add_development_dependency 'pry', '~> 0.10'
|
32
32
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: togls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Miller
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-06-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -46,14 +46,14 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '3.
|
49
|
+
version: '3.4'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '3.
|
56
|
+
version: '3.4'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: pry
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,26 +93,31 @@ files:
|
|
93
93
|
- bin/console
|
94
94
|
- bin/setup
|
95
95
|
- contributing/togls_architecture.monopic
|
96
|
-
- lib/tasks/togls.rake
|
97
96
|
- lib/togls.rb
|
97
|
+
- lib/togls/default_feature_target_type_manager.rb
|
98
98
|
- lib/togls/errors.rb
|
99
99
|
- lib/togls/feature.rb
|
100
100
|
- lib/togls/feature_repository.rb
|
101
101
|
- lib/togls/feature_repository_drivers.rb
|
102
102
|
- lib/togls/feature_repository_drivers/in_memory_driver.rb
|
103
|
-
- lib/togls/
|
103
|
+
- lib/togls/feature_toggle_registry_manager.rb
|
104
104
|
- lib/togls/helpers.rb
|
105
105
|
- lib/togls/null_toggle.rb
|
106
|
-
- lib/togls/release_toggle_registry_manager.rb
|
107
106
|
- lib/togls/rule.rb
|
108
107
|
- lib/togls/rule_repository.rb
|
109
108
|
- lib/togls/rule_repository_drivers.rb
|
109
|
+
- lib/togls/rule_repository_drivers/env_override_driver.rb
|
110
110
|
- lib/togls/rule_repository_drivers/in_memory_driver.rb
|
111
|
+
- lib/togls/rule_type_registry.rb
|
112
|
+
- lib/togls/rule_type_repository.rb
|
113
|
+
- lib/togls/rule_type_repository_drivers.rb
|
114
|
+
- lib/togls/rule_type_repository_drivers/in_memory_driver.rb
|
111
115
|
- lib/togls/rules.rb
|
112
116
|
- lib/togls/rules/boolean.rb
|
113
117
|
- lib/togls/rules/group.rb
|
114
|
-
- lib/togls/
|
118
|
+
- lib/togls/target_types.rb
|
115
119
|
- lib/togls/toggle.rb
|
120
|
+
- lib/togls/toggle_registry.rb
|
116
121
|
- lib/togls/toggle_repository.rb
|
117
122
|
- lib/togls/toggle_repository_drivers.rb
|
118
123
|
- lib/togls/toggle_repository_drivers/env_override_driver.rb
|
@@ -135,9 +140,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
140
|
version: '0'
|
136
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
142
|
requirements:
|
138
|
-
- - "
|
143
|
+
- - ">"
|
139
144
|
- !ruby/object:Gem::Version
|
140
|
-
version:
|
145
|
+
version: 1.3.1
|
141
146
|
requirements: []
|
142
147
|
rubyforge_project:
|
143
148
|
rubygems_version: 2.5.1
|
data/lib/tasks/togls.rake
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Togls
|
2
|
-
# Feature Toggle Registry
|
3
|
-
#
|
4
|
-
# The Feature Toggle Registry conceptually houses a registry of toggles. It
|
5
|
-
# accomplishes this by technically housing a toggle repository, rule
|
6
|
-
# repository, and feature repository which is uses to store and retrieve the
|
7
|
-
# respective entities. This plays a significant portion in the primary DSL as
|
8
|
-
# well.
|
9
|
-
class FeatureToggleRegistry
|
10
|
-
def initialize
|
11
|
-
@toggle_repository_drivers = [
|
12
|
-
Togls::ToggleRepositoryDrivers::InMemoryDriver.new,
|
13
|
-
Togls::ToggleRepositoryDrivers::EnvOverrideDriver.new]
|
14
|
-
@feature_repository_drivers =
|
15
|
-
[Togls::FeatureRepositoryDrivers::InMemoryDriver.new]
|
16
|
-
@rule_repository_drivers =
|
17
|
-
[Togls::RuleRepositoryDrivers::InMemoryDriver.new]
|
18
|
-
@feature_repository = Togls::FeatureRepository.new(
|
19
|
-
@feature_repository_drivers)
|
20
|
-
@rule_repository = Togls::RuleRepository.new(@rule_repository_drivers)
|
21
|
-
@toggle_repository = Togls::ToggleRepository.new(
|
22
|
-
@toggle_repository_drivers, @feature_repository, @rule_repository)
|
23
|
-
@rule_repository.store(Togls::Rules::Boolean.new(true))
|
24
|
-
@rule_repository.store(Togls::Rules::Boolean.new(false))
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.create(&block)
|
28
|
-
feature_toggle_registry = new
|
29
|
-
feature_toggle_registry.instance_eval(&block)
|
30
|
-
feature_toggle_registry
|
31
|
-
end
|
32
|
-
|
33
|
-
def expand(&block)
|
34
|
-
instance_eval(&block)
|
35
|
-
self
|
36
|
-
end
|
37
|
-
|
38
|
-
def feature(key, desc)
|
39
|
-
feature = Togls::Feature.new(key, desc)
|
40
|
-
toggle = Togls::Toggle.new(feature)
|
41
|
-
@toggle_repository.store(toggle)
|
42
|
-
Togls::Toggler.new(@toggle_repository, toggle)
|
43
|
-
end
|
44
|
-
|
45
|
-
def get(key)
|
46
|
-
toggle = @toggle_repository.get(key.to_s)
|
47
|
-
if toggle.is_a?(Togls::NullToggle)
|
48
|
-
Togls.logger.warn("Feature identified by '#{key}' has not been defined")
|
49
|
-
end
|
50
|
-
toggle
|
51
|
-
end
|
52
|
-
|
53
|
-
def all
|
54
|
-
@toggle_repository.all
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|