togls 3.0.0.pre.rc.2 → 3.0.0.pre.rc.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6cbf5465b03534a0ea73b226ffacf1bc01825eb9
4
- data.tar.gz: f624a8d851aa5b59d69f5d5437f9409f7d987c3e
3
+ metadata.gz: 05024ddd358a85a71a6c2a321ca23e6dc1f1a54f
4
+ data.tar.gz: c0cffcdf9ac3c88225383dd052ebf02497a9d43e
5
5
  SHA512:
6
- metadata.gz: 4d9a49ca3670eee9ef1c00644060a8ca1b505e516f1d451d363353a81404c3cfb48d18fd9169eb0eedc7db8ebe75d96128b5ed19853b6c69b1f1d60597e34b01
7
- data.tar.gz: 699d108793a00c42c8228357ecb3eb4413e64f5b6dacec9ee9ed1704c9dc51dc8402b5647bd8c274b93c6c0befa4ed116a993e2274bddc36ee15f4f4d462b9a5
6
+ metadata.gz: fcc5a4843465954f936decf0da23c2bdd16fd6683634a791905d700bb18753142b226653d1fcf60b8f695cef103a7f95df81e0d37afce3d9bb58bdcea1d7deff
7
+ data.tar.gz: 73bd020d13232d401c8b0dc77bcff6096a27b16674a4c5f49710cd093b2817a4287ccedca149213cce81de7ddbc3ae853ab7b874af5d015111005253a8d96f5c
data/CHANGELOG.md CHANGED
@@ -10,6 +10,7 @@ that you can set version constraints properly.
10
10
 
11
11
  #### [Unreleased] - now
12
12
 
13
+ * `Changed`: Rule and Rule Type management to be global under Togls
13
14
  * `Changed`: The testing interface to allow for contract enforcement in tests
14
15
  and allow altering existing feature rules within tests.
15
16
  * `Added`: `Togls.rule` method to simplify rule construction from `type_id`
data/README.md CHANGED
@@ -52,13 +52,28 @@ how one would define some basic feature toggles.
52
52
  ```ruby
53
53
  Togls.release do
54
54
  # Set this feature to always be on
55
- feature(:pop_up_login_form, "use pop up login instead of normal login").on
55
+ feature(:pop_up_login_form, "use pop up login instead of normal login").on
56
56
 
57
57
  # Set this feature to always be off
58
58
  feature(:send_follup_email, "send the follow up email").off
59
59
  end
60
60
  ```
61
61
 
62
+ The above defined feature toggles would use
63
+ [default feature target type](https://github.com/codebreakdown/togls/wiki/Abstract-Target-Types#setting-the-default-feature-target-type).
64
+ If we wanted to define them explicitly with other target types it would like as
65
+ follows.
66
+
67
+ ```ruby
68
+ Togls.release do
69
+ # Set this feature to always be on
70
+ feature(:pop_up_login_form, "use pop up login instead of normal login", :user_id).on
71
+
72
+ # Set this feature to always be off
73
+ feature(:send_follup_email, "send the follow up email", :user_email_address).off
74
+ end
75
+ ```
76
+
62
77
  ### Evaluating Feature Toggles
63
78
 
64
79
  Once you have defined your feature toggles. The next thing you would
@@ -83,6 +98,28 @@ end
83
98
  **Note:** Feature toggles that are evaluated but have **not** been
84
99
  defined will default to **off**.
85
100
 
101
+ The above two feature toggles evaluated are written as if the feature toggle has
102
+ a target type of `Togls::TargetTypes::NONE`. If the feature toggles had a
103
+ specific target type and they were evaluted as shown above an exception would be
104
+ raised notifying you that they expect an entity of that type as the target for
105
+ evaluation. To better match the explicit target type example from Defining
106
+ Feature Toggles it would look something like the following.
107
+
108
+
109
+ ```ruby
110
+ if Togls.feature(:pop_up_login_form).on?(current_user.id)
111
+ # Use pop up login form
112
+ else
113
+ # Use normal non-pop up login form
114
+ end
115
+
116
+ ...
117
+
118
+ if Togls.feature(:send_follup_email).on?(current_user.email)
119
+ # send the follow up email
120
+ end
121
+ ```
122
+
86
123
  ### Override Feature Toggles
87
124
 
88
125
  Toggles can be overriden using environment variables following the
@@ -106,7 +143,11 @@ We could override this by setting the value of the
106
143
  to override a feature toggle to an on state you can set the
107
144
  `TOGLS_POP_UP_LOGIN_FORM` environment variable to `"true"`.
108
145
 
109
- ### Toggle Features based on Group Membership
146
+ **Note:** This feature is explicitly designed for use in your development
147
+ environment. If you use this feature in other environments (qa, staging,
148
+ production, etc.) it may not behave as you expect.
149
+
150
+ ### Toggle Features based on Group Membership
110
151
 
111
152
  `togls` provides out of the box support for toggling features based on
112
153
  group membership. This basically allows you to have a feature **on** for
@@ -115,10 +156,10 @@ extremely useful if you want to enable features for a small alpha test
115
156
  group for example.
116
157
 
117
158
  **Note:** This is implemented using `togls` extremely robust [custom
118
- rules](https://github.com/codebreakdown/togls/wiki/Custom-Rules) system.
159
+ rules](https://github.com/codebreakdown/togls/wiki/Custom-Rule-Types-&-Rules) system.
119
160
  The following example is just one of the many powerful things you can do
120
161
  with `togls` and [custom
121
- rules](https://github.com/codebreakdown/togls/wiki/Custom-Rules).
162
+ rules](https://github.com/codebreakdown/togls/wiki/Custom-Rule-Types-&-Rules).
122
163
 
123
164
  #### Defining Group based Feature Toggles
124
165
 
@@ -128,11 +169,10 @@ based on group membership.
128
169
  ```ruby
129
170
  # Create a group rule so the feature is on if the user is a member of
130
171
  # the group.
131
- alpha_testers = Togls::Rules::Group.new(["user1@email.com",
132
- "user2@example.com"])
172
+ alpha_testers = Togls.rule(:group, ["user1@email.com", "user2@example.com"], target_type: :user_email_address)
133
173
 
134
174
  Togls.release do
135
- feature(:new_contact_form, "use new contact form").on(alpha_testers)
175
+ feature(:new_contact_form, "use new contact form", target_type: :user_email_address).on(alpha_testers)
136
176
  end
137
177
  ```
138
178
 
@@ -181,10 +221,10 @@ in the example above and it would look something like the following:
181
221
  ```ruby
182
222
  # Create a group rule so the feature is on if the user is a member of
183
223
  # the group.
184
- alpha_testers = Togls::Rules::Group.new([1, 23, 42, 83])
224
+ alpha_testers = Togls.rule(:group, [1, 23, 42, 83], :user_id)
185
225
 
186
226
  Togls.release do
187
- feature(:new_contact_form, "use new contact form").on(alpha_testers)
227
+ feature(:new_contact_form, "use new contact form", :user_id).on(alpha_testers)
188
228
  end
189
229
  ```
190
230
 
@@ -213,7 +253,7 @@ Toggles](https://github.com/codebreakdown/togls/wiki/Testing-with-Toggles),
213
253
  [Provided Rules
214
254
  Reference](https://github.com/codebreakdown/togls/wiki/Provided-Rules-Reference),
215
255
  [Custom
216
- Rules](https://github.com/codebreakdown/togls/wiki/Custom-Rules),
256
+ Rules](https://github.com/codebreakdown/togls/wiki/Custom-Rule-Types-&-Rules),
217
257
  [Organize Toggle
218
258
  Definitions](https://github.com/codebreakdown/togls/wiki/Organize-Toggle-Definitions),
219
259
  [Creating Additional Toggle
@@ -24,19 +24,6 @@ module Togls
24
24
  @release_blocks ||= []
25
25
  end
26
26
 
27
- def rule_types(&block)
28
- rule_type_registry.expand(&block) if block
29
- rule_type_registry
30
- end
31
-
32
- def rule_type(type_id)
33
- rule_type_registry.get(type_id)
34
- end
35
-
36
- def rule(type_id, data, target_type: Togls::TargetTypes::NOT_SET)
37
- rule_type(type_id).new(type_id, data, target_type: target_type)
38
- end
39
-
40
27
  def feature(key)
41
28
  Toggler.new(release_toggle_registry.instance_variable_get(:@toggle_repository), release_toggle_registry.get(key))
42
29
  end
@@ -62,38 +49,17 @@ module Togls
62
49
 
63
50
  private
64
51
 
65
- def rule_type_repository
66
- if @rule_type_repository.nil?
67
- rule_type_repository_drivers = [RuleTypeRepositoryDrivers::InMemoryDriver.new]
68
- @rule_type_repository = RuleTypeRepository.new(rule_type_repository_drivers)
69
- end
70
- @rule_type_repository
71
- end
72
-
73
- def rule_type_registry
74
- if @rule_type_registry.nil?
75
- @rule_type_registry = RuleTypeRegistry.new(rule_type_repository)
76
- @rule_type_registry.register(:boolean, Togls::Rules::Boolean)
77
- @rule_type_registry.register(:group, Togls::Rules::Group)
78
- end
79
- @rule_type_registry
80
- end
81
-
82
52
  def test_toggle_registry
83
53
  feature_repository_drivers =
84
54
  [Togls::FeatureRepositoryDrivers::InMemoryDriver.new]
85
55
  test_feature_repository = Togls::FeatureRepository.new(
86
56
  feature_repository_drivers)
87
57
 
88
- rule_repository_drivers =
89
- [Togls::RuleRepositoryDrivers::InMemoryDriver.new]
90
- rule_repository = Togls::RuleRepository.new(rule_type_registry, rule_repository_drivers)
91
-
92
58
  toggle_repository_drivers = [
93
59
  Togls::ToggleRepositoryDrivers::InMemoryDriver.new]
94
60
 
95
61
  toggle_repository = Togls::ToggleRepository.new(
96
- toggle_repository_drivers, test_feature_repository, rule_repository)
62
+ toggle_repository_drivers, test_feature_repository)
97
63
 
98
64
  tr = ToggleRegistry.new(test_feature_repository, toggle_repository)
99
65
  release_blocks.each do |p|
@@ -105,12 +71,6 @@ module Togls
105
71
 
106
72
  def release_toggle_registry
107
73
  if @release_toggle_registry.nil?
108
- rule_repository_drivers = [
109
- Togls::RuleRepositoryDrivers::InMemoryDriver.new,
110
- Togls::RuleRepositoryDrivers::EnvOverrideDriver.new
111
- ]
112
-
113
- rule_repository = Togls::RuleRepository.new(rule_type_registry, rule_repository_drivers)
114
74
 
115
75
  toggle_repository_drivers = [
116
76
  Togls::ToggleRepositoryDrivers::InMemoryDriver.new,
@@ -118,7 +78,7 @@ module Togls
118
78
  ]
119
79
 
120
80
  toggle_repository = Togls::ToggleRepository.new(
121
- toggle_repository_drivers, feature_repository, rule_repository)
81
+ toggle_repository_drivers, feature_repository)
122
82
 
123
83
  @release_toggle_registry = ToggleRegistry.new(feature_repository,
124
84
  toggle_repository)
@@ -0,0 +1,53 @@
1
+ module Togls
2
+ module RuleManager
3
+ def self.included(mod)
4
+ mod.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def rule_types(&block)
9
+ rule_type_registry.expand(&block) if block
10
+ rule_type_registry
11
+ end
12
+
13
+ def rule_type(type_id)
14
+ rule_type_registry.get(type_id)
15
+ end
16
+
17
+ def rule(type_id, data = nil, target_type: Togls::TargetTypes::NOT_SET)
18
+ rule_type(type_id).new(type_id, data, target_type: target_type)
19
+ end
20
+
21
+ private
22
+
23
+ def rule_type_repository
24
+ if @rule_type_repository.nil?
25
+ rule_type_repository_drivers = [RuleTypeRepositoryDrivers::InMemoryDriver.new]
26
+ @rule_type_repository = RuleTypeRepository.new(rule_type_repository_drivers)
27
+ end
28
+ @rule_type_repository
29
+ end
30
+
31
+ def rule_type_registry
32
+ if @rule_type_registry.nil?
33
+ @rule_type_registry = RuleTypeRegistry.new(rule_type_repository)
34
+ @rule_type_registry.register(:boolean, Togls::Rules::Boolean)
35
+ @rule_type_registry.register(:group, Togls::Rules::Group)
36
+ end
37
+ @rule_type_registry
38
+ end
39
+
40
+ def rule_repository
41
+ if @rule_repository.nil?
42
+ rule_repository_drivers = [
43
+ Togls::RuleRepositoryDrivers::InMemoryDriver.new,
44
+ Togls::RuleRepositoryDrivers::EnvOverrideDriver.new
45
+ ]
46
+
47
+ @rule_repository = Togls::RuleRepository.new(rule_repository_drivers)
48
+ end
49
+ @rule_repository
50
+ end
51
+ end
52
+ end
53
+ end
@@ -5,7 +5,7 @@ module Togls
5
5
  # It does these by interfacing with Rule Repository Drivers which are passed
6
6
  # in during construction as an Array.
7
7
  class RuleRepository
8
- def initialize(rule_type_registry, drivers)
8
+ def initialize(drivers)
9
9
  unless drivers.is_a?(Array)
10
10
  raise Togls::InvalidDriver, 'RuleRepository requires a valid driver'
11
11
  end
@@ -13,7 +13,6 @@ module Togls
13
13
  raise Togls::MissingDriver, 'RuleRepository requires a driver'
14
14
  end
15
15
  @drivers = drivers
16
- @rule_type_registry = rule_type_registry
17
16
  end
18
17
 
19
18
  def store(rule)
@@ -25,7 +24,7 @@ module Togls
25
24
 
26
25
  def extract_storage_payload(rule)
27
26
  {
28
- 'type_id' => @rule_type_registry.get_type_id(rule.class.to_s),
27
+ 'type_id' => ::Togls.send(:rule_type_registry).get_type_id(rule.class.to_s),
29
28
  'data' => rule.data,
30
29
  'target_type' => rule.target_type.to_s
31
30
  }
@@ -69,11 +68,12 @@ module Togls
69
68
 
70
69
  def reconstitute_rule(rule_data)
71
70
  if rule_data.has_key?('target_type')
72
- @rule_type_registry.get(rule_data['type_id'])\
71
+ ::Togls.rule_type(rule_data['type_id'])\
73
72
  .new(rule_data['type_id'].to_sym, rule_data['data'],
74
73
  target_type: rule_data['target_type'].to_sym)
75
74
  else
76
- @rule_type_registry.get(rule_data['type_id']).new(rule_data['type_id'].to_sym, rule_data['data'])
75
+ ::Togls.rule_type(rule_data['type_id']).new(rule_data['type_id'].to_sym,
76
+ rule_data['data'])
77
77
  end
78
78
  end
79
79
  end
@@ -3,7 +3,7 @@ module Togls
3
3
  #
4
4
  # Repository interface for storing and retrieving toggles.
5
5
  class ToggleRepository
6
- def initialize(drivers, feature_repository, rule_repository)
6
+ def initialize(drivers, feature_repository)
7
7
  unless drivers.is_a?(Array)
8
8
  raise Togls::InvalidDriver, 'ToggleRepository requires a valid driver'
9
9
  end
@@ -12,12 +12,11 @@ module Togls
12
12
  end
13
13
  @drivers = drivers
14
14
  @feature_repository = feature_repository
15
- @rule_repository = rule_repository
16
15
  end
17
16
 
18
17
  def store(toggle)
19
18
  @feature_repository.store(toggle.feature)
20
- @rule_repository.store(toggle.rule)
19
+ ::Togls.send(:rule_repository).store(toggle.rule)
21
20
  payload = extract_storage_payload(toggle)
22
21
 
23
22
  @drivers.each do |driver|
@@ -43,7 +42,7 @@ module Togls
43
42
  end
44
43
 
45
44
  begin
46
- rule = @rule_repository.get(toggle_data['rule_id'])
45
+ rule = ::Togls.send(:rule_repository).get(toggle_data['rule_id'])
47
46
  rescue Togls::RepositoryRuleDataInvalid => e
48
47
  return Togls::NullToggle.new
49
48
  end
data/lib/togls/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Togls
2
- VERSION = '3.0.0-rc.2'.freeze
2
+ VERSION = '3.0.0-rc.3'.freeze
3
3
  end
data/lib/togls.rb CHANGED
@@ -25,6 +25,7 @@ require 'togls/null_toggle'
25
25
  require 'togls/rule'
26
26
  require 'togls/rules'
27
27
  require 'logger'
28
+ require 'togls/rule_manager'
28
29
  require 'togls/feature_toggle_registry_manager'
29
30
  require 'togls/default_feature_target_type_manager'
30
31
 
@@ -33,6 +34,7 @@ require 'togls/default_feature_target_type_manager'
33
34
  # Togls is the primary interface to the out of the box toggle registry. It is
34
35
  # the namespace the DSL is exposed under.
35
36
  module Togls
37
+ include RuleManager
36
38
  include FeatureToggleRegistryManager
37
39
  include DefaultFeatureTargetTypeManager
38
40
  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: 3.0.0.pre.rc.2
4
+ version: 3.0.0.pre.rc.3
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-06-09 00:00:00.000000000 Z
13
+ date: 2016-06-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -104,6 +104,7 @@ files:
104
104
  - lib/togls/helpers.rb
105
105
  - lib/togls/null_toggle.rb
106
106
  - lib/togls/rule.rb
107
+ - lib/togls/rule_manager.rb
107
108
  - lib/togls/rule_repository.rb
108
109
  - lib/togls/rule_repository_drivers.rb
109
110
  - lib/togls/rule_repository_drivers/env_override_driver.rb