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

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 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