simple_switch 0.2.0 → 0.3.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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/README.md +175 -58
  4. data/Rakefile +21 -1
  5. data/app/assets/javascripts/simple_switch/application.js +1 -0
  6. data/app/assets/stylesheets/simple_switch/application.css +4 -0
  7. data/app/controllers/simple_switch/application_controller.rb +4 -0
  8. data/app/helpers/simple_switch/application_helper.rb +4 -0
  9. data/app/models/simple_switch/environment.rb +8 -0
  10. data/app/models/simple_switch/feature.rb +8 -0
  11. data/app/models/simple_switch/state.rb +15 -0
  12. data/app/views/layouts/simple_switch/application.html.erb +14 -0
  13. data/config/routes.rb +2 -0
  14. data/db/migrate/20151216180633_create_simple_switch_tables.simple_switch.rb +24 -0
  15. data/lib/generators/simple_switch/initialize_generator.rb +17 -0
  16. data/lib/generators/simple_switch/install_generator.rb +13 -3
  17. data/lib/generators/templates/feature_config_sample.yml +16 -12
  18. data/lib/generators/templates/migration.rb +24 -0
  19. data/lib/generators/templates/simple_switch.rb +9 -2
  20. data/lib/simple_switch.rb +10 -6
  21. data/lib/simple_switch/engine.rb +10 -0
  22. data/lib/simple_switch/feature_manager.rb +15 -0
  23. data/lib/simple_switch/feature_manager_db.rb +88 -0
  24. data/lib/simple_switch/feature_manager_yaml.rb +68 -0
  25. data/lib/simple_switch/manager_shared_methods.rb +52 -0
  26. data/lib/simple_switch/railtie.rb +12 -0
  27. data/lib/simple_switch/shared_controller_methods.rb +2 -2
  28. data/lib/simple_switch/version.rb +1 -1
  29. data/lib/tasks/simple_switch.rake +106 -0
  30. data/spec/config/feature_config.yml +10 -6
  31. data/spec/dummy/README.rdoc +28 -0
  32. data/spec/dummy/Rakefile +6 -0
  33. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  34. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  35. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  36. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  37. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  38. data/spec/dummy/bin/bundle +3 -0
  39. data/spec/dummy/bin/rails +4 -0
  40. data/spec/dummy/bin/rake +4 -0
  41. data/spec/dummy/bin/setup +29 -0
  42. data/spec/dummy/config.ru +4 -0
  43. data/spec/dummy/config/application.rb +26 -0
  44. data/spec/dummy/config/boot.rb +5 -0
  45. data/spec/dummy/config/database.yml +25 -0
  46. data/spec/dummy/config/environment.rb +5 -0
  47. data/spec/dummy/config/environments/development.rb +41 -0
  48. data/spec/dummy/config/environments/production.rb +79 -0
  49. data/spec/dummy/config/environments/test.rb +42 -0
  50. data/spec/dummy/config/initializers/assets.rb +11 -0
  51. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  52. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  53. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  54. data/spec/dummy/config/initializers/inflections.rb +16 -0
  55. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  56. data/spec/dummy/config/initializers/session_store.rb +3 -0
  57. data/spec/dummy/config/initializers/simple_switch.rb +17 -0
  58. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/spec/dummy/config/locales/en.yml +23 -0
  60. data/spec/dummy/config/routes.rb +4 -0
  61. data/spec/dummy/config/secrets.yml +22 -0
  62. data/spec/dummy/db/development.sqlite3 +0 -0
  63. data/spec/dummy/db/schema.rb +44 -0
  64. data/spec/dummy/db/seeds.rb +17 -0
  65. data/spec/dummy/db/test.sqlite3 +0 -0
  66. data/spec/dummy/log/development.log +54 -0
  67. data/spec/dummy/log/test.log +7280 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/factories/simple_switch_environments.rb +5 -0
  70. data/spec/factories/simple_switch_features.rb +5 -0
  71. data/spec/factories/simple_switch_states.rb +5 -0
  72. data/spec/models/simple_switch/environment_spec.rb +11 -0
  73. data/spec/models/simple_switch/feature_spec.rb +11 -0
  74. data/spec/models/simple_switch/state_spec.rb +11 -0
  75. data/spec/route_helper.rb +5 -0
  76. data/spec/simple_switch_feature_managers_spec.rb +282 -0
  77. data/spec/spec_helper.rb +22 -27
  78. metadata +203 -17
  79. data/.gitignore +0 -3
  80. data/.rspec +0 -2
  81. data/.travis.yml +0 -7
  82. data/Gemfile +0 -4
  83. data/LICENSE.txt +0 -22
  84. data/codeclimate.yml +0 -3
  85. data/lib/generators/simple_switch/install_yaml_generator.rb +0 -18
  86. data/lib/simple_switch/switch.rb +0 -77
  87. data/simple_switch.gemspec +0 -26
  88. data/spec/simple_switch_spec.rb +0 -91
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f8379b3f743c3831e33cf764452d91835d03ece
4
- data.tar.gz: 066a6820f1ae9d8dfe3b62870281baab8c4ee904
3
+ metadata.gz: 809dd823c24166538111b727e8cf8a270cbc7cb9
4
+ data.tar.gz: aaa927b1c39fad4af8bd64207aee1c9401a13166
5
5
  SHA512:
6
- metadata.gz: 8110097a9c077e7a8dfc7d00bd4e60c6e49f8acd1f877a1c009e7f7baecc1196b56b8418fb9c495788fad337c42950b31ea66bda24a2673b27ee1d728684630b
7
- data.tar.gz: fbc574f38d60b26b78ecfa5a9895b931b5fc02388e4b573c1b088e9c11b00915f4fd4834a08426cd3cef3e52559abe5936373916a2a76eb6d1cc50c8cc12ecd7
6
+ metadata.gz: e674618fc957becb492c60b92be41ae8d6a4bea8743c217ac85f12745ffd49297a1ff06f1dbe056a22670871c372a431af53fbbd818b089b581d41e994c33f74
7
+ data.tar.gz: 780a68a379e3af34c7c43a7ea5ddc2cc09c515f616084a69940cfb6b73538df7dbd3f4532b6a4167c893a48280cd4f999ad30dd1f5982fd2242f8eef32aa8d35
data/CHANGELOG.md CHANGED
@@ -9,4 +9,13 @@ simple_switch is in a 0.2.0 beta state. This means that its APIs and behavior ar
9
9
  Changes:
10
10
 
11
11
  * Add tests
12
- * Refactor APIs for action_controller
12
+ * Refactor APIs for action_controller
13
+
14
+ ## [0.3.0](https://github.com/Sen-Zhang/simple_switch/releases/tag/v0.3.0) (2015-12-17)
15
+
16
+ Changes:
17
+
18
+ * Minor refactor
19
+ * Add another feature management strategy: store features and configurations in database instead of yml
20
+ * Add turn_on and turn_off APIs
21
+ * Add rake tasks to manage features and configurations for database strategy
data/README.md CHANGED
@@ -8,7 +8,7 @@ Simple Feature Switch Engine
8
8
 
9
9
  ## Requirement
10
10
  * Ruby 2.0+
11
- * Rails 3.0+
11
+ * Rails 4.0+
12
12
 
13
13
  ## Installation
14
14
 
@@ -28,88 +28,198 @@ Or install it yourself as:
28
28
 
29
29
  ## Usage
30
30
 
31
- ### Basic
31
+ ### Database Strategy
32
+ Store and manage features and configurations in database.
32
33
 
33
- Run install generator:
34
+ Run initialize generator:
34
35
 
35
- $ rails generate simple_switch:install
36
+ $ rails generate simple_switch:initialize
36
37
 
37
38
  A initializer file named `simple_switch.rb` will be added into `config/initializers` after running
38
- install generator. In that file, you can customize the feature configuration yaml file's name and
39
- installation place.
39
+ install generator. Set feature store strategy to `:database` and leave configuration for yaml strategy
40
+ commented out.
41
+
42
+ ````ruby
43
+ # feature management strategy
44
+ # the supported strategies are: [:yml, :database]
45
+ # default strategy is [:database]
46
+ config.feature_store = :database
47
+
48
+ # configuration for yml strategy
49
+ # feature switch configuration yaml file stored location, by default it is stored
50
+ # under config directory
51
+ # config.feature_config_file_dir = 'config'
52
+
53
+ # configuration for yml strategy
54
+ # feature switch configuration yaml file name, by default it is 'feature_config.yml'
55
+ # config.feature_config_file_name = 'feature_config.yml'
56
+ ````
57
+ Then run the following commands to copy required migration files to root application and migrate the database.
40
58
 
41
- # feature switch configuration yaml file stored location, by default it is stored
42
- # under config directory
43
- config.feature_config_file_dir = 'config'
59
+ $ rails generate simple_switch:install
60
+ $ bundle exec rake db:migrate
44
61
 
45
- # feature switch configuration yaml file name, by default it is 'feature_config.yml'
46
- config.feature_config_file_name = 'feature_config.yml'
62
+ The data structure for `simple_switch` is described as followed:
47
63
 
48
- Then run the following commands to copy feature configuration yaml file to the target directory.
64
+ ![ERR Diagram](/images/err_diagram.png)
49
65
 
50
- Run install generator:
66
+ The following rake tasks are created to generate data for features, environments and configurations. You can also
67
+ add data through rails console.
51
68
 
52
- $ rails generate simple_switch:install_yaml
69
+ $ bundle exec rake simple_switch:add_feature name='Foo' description='Foo feature'
70
+ $ bundle exec rake simple_switch:add_environment name='test'
71
+ $ bundle exec rake simple_switch:add_feature_config feature='foo' environment='test' status=true
53
72
 
54
- Now you are ready to define features:
55
-
56
- foo:
57
- development: true
58
- test: true
59
- production: false
73
+ Now you can use it in models like this:
60
74
 
61
- bar:
62
- development: false
63
- test: true
64
- production: false
75
+ ````ruby
76
+ class TestModel < ActiveRecord::Base
77
+ ...
65
78
 
66
- Now you can use it in models like this:
79
+ if feature_on?(:foo)
80
+ def foo_method
81
+ ...
82
+ end
83
+ end
67
84
 
68
- class TestModel < ActiveRecord::Base
85
+ def bar_method
86
+ if feature_on?(:bar)
69
87
  ...
88
+ end
89
+ end
70
90
 
71
- if feature_on?(:foo)
72
- def foo_method
73
- ...
74
- end
75
- end
91
+ ...
92
+ end
93
+ ````
94
+ In controllers like this:
76
95
 
77
- def bar_method
78
- if feature_on?(:bar)
79
- ...
80
- end
81
- end
96
+ ````ruby
97
+ class TestController < ApplicationController
98
+ ...
82
99
 
83
- ...
100
+ def index
101
+ ...
102
+
103
+ if feature_on?(:foo)
104
+ redirect_to :back
84
105
  end
85
106
 
86
- In controllers like this:
107
+ ...
108
+ end
87
109
 
88
- class TestController < ApplicationController
89
- ...
110
+ ...
111
+ end
112
+ ````
113
+ And in views like this:
114
+
115
+ ````erb
116
+ <% if feature_on?(:foo) %>
117
+ <p>Experiment foo is on</p>
118
+ <% end %>
119
+
120
+ <% if feature_off?(:bar) %>
121
+ <p>Experiment bar is off</p>
122
+ <% end %>
123
+ ````
124
+
125
+ ### YML Strategy
126
+ Store and manage features and configurations all in a single yaml file.
90
127
 
91
- def index
92
- ...
128
+ Run initialize generator:
93
129
 
94
- if feature_on?(:foo)
95
- redirect_to :back
96
- end
130
+ $ rails generate simple_switch:initialize
97
131
 
98
- ...
99
- end
132
+ A initializer file named `simple_switch.rb` will be added into `config/initializers` after running
133
+ install generator. Set feature store strategy to `:yml` and customize the feature configuration yaml
134
+ file's name and installation place in this file.
135
+
136
+ ````ruby
137
+ # feature management strategy
138
+ # the supported strategies are: [:yml, :database]
139
+ # default strategy is [:database]
140
+ config.feature_store = :yml
141
+
142
+ # configuration for yml strategy
143
+ # feature switch configuration yaml file stored location, by default it is stored
144
+ # under config directory
145
+ config.feature_config_file_dir = 'config'
146
+
147
+ # configuration for yml strategy
148
+ # feature switch configuration yaml file name, by default it is 'feature_config.yml'
149
+ config.feature_config_file_name = 'feature_config.yml'
150
+ ````
151
+ Then run the following commands to copy feature configuration yaml file to the target directory.
152
+
153
+ Run install generator:
154
+
155
+ $ rails generate simple_switch:install
100
156
 
157
+ Now you are ready to define features:
158
+ ````yml
159
+ foo:
160
+ description: Foo Feature
161
+ states:
162
+ development: true
163
+ test: true
164
+ production: false
165
+ bar:
166
+ description: Bar Feature
167
+ states:
168
+ development: true
169
+ test: true
170
+ production: true
171
+ ````
172
+ Now you can use it in models like this:
173
+
174
+ ````ruby
175
+ class TestModel < ActiveRecord::Base
176
+ ...
177
+
178
+ if feature_on?(:foo)
179
+ def foo_method
101
180
  ...
102
181
  end
182
+ end
103
183
 
184
+ def bar_method
185
+ if feature_on?(:bar)
186
+ ...
187
+ end
188
+ end
189
+
190
+ ...
191
+ end
192
+ ````
193
+ In controllers like this:
194
+
195
+ ````ruby
196
+ class TestController < ApplicationController
197
+ ...
198
+
199
+ def index
200
+ ...
201
+
202
+ if feature_on?(:foo)
203
+ redirect_to :back
204
+ end
205
+
206
+ ...
207
+ end
208
+
209
+ ...
210
+ end
211
+ ````
104
212
  And in views like this:
105
213
 
106
- <% if feature_on?(:foo) %>
107
- <p>Experiment foo is on</p>
108
- <% end %>
214
+ ````erb
215
+ <% if feature_on?(:foo) %>
216
+ <p>Experiment foo is on</p>
217
+ <% end %>
109
218
 
110
- <% if feature_off?(:bar) %>
111
- <p>Experiment bar is off</p>
112
- <% end %>
219
+ <% if feature_off?(:bar) %>
220
+ <p>Experiment bar is off</p>
221
+ <% end %>
222
+ ````
113
223
 
114
224
  ### Toggle Features
115
225
 
@@ -117,10 +227,17 @@ The following methods are only accessible in controllers:
117
227
 
118
228
  `feature_config_info` return a hash represents the current feature configuration condition.
119
229
 
120
- `turn_on(feature, env)` turn on a feature on a indicated environment.
121
-
122
- turn_on(:foo, :development)
230
+ `turn_on(feature, env)` turn on a feature on an indicated environment.
231
+ ````ruby
232
+ turn_on(:foo, :development)
233
+ ````
234
+ `turn_off(feature, env)` turn off a feature on an indicated environment.
235
+ ````ruby
236
+ turn_off(:foo, :development)
237
+ ````
123
238
 
124
- `turn_off(feature, env)` turn off a feature on a indicated environment.
239
+ The following rake tasks are created to toggle features for database strategy only, and feature
240
+ name and environment name are required:
125
241
 
126
- turn_off(:foo, :development)
242
+ $ bundle exec rake simple_switch:turn_on feature='foo' environment='test'
243
+ $ bundle exec rake simple_switch:turn_off feature='foo' environment='test'
data/Rakefile CHANGED
@@ -1 +1,21 @@
1
- require 'bundler/gem_tasks'
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SimpleSwitch'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+ load 'rails/tasks/statistics.rake'
20
+
21
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1 @@
1
+ //= require_tree .
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require_tree .
3
+ *= require_self
4
+ */
@@ -0,0 +1,4 @@
1
+ module SimpleSwitch
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SimpleSwitch
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleSwitch
2
+ class Environment < ActiveRecord::Base
3
+ has_many :states, dependent: :destroy
4
+ has_many :features, through: :states
5
+
6
+ validates :name, presence: true, uniqueness: true
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleSwitch
2
+ class Feature < ActiveRecord::Base
3
+ has_many :states, dependent: :destroy
4
+ has_many :environments, through: :states
5
+
6
+ validates :name, presence: true, uniqueness: true
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module SimpleSwitch
2
+ class State < ActiveRecord::Base
3
+ before_save :set_default_status, if: proc { |s| s.status.nil? }
4
+
5
+ belongs_to :feature
6
+ belongs_to :environment
7
+
8
+ validates_presence_of :feature_id, :environment_id
9
+
10
+ private
11
+ def set_default_status
12
+ status = false;
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>SimpleSwitch</title>
5
+ <%= stylesheet_link_tag 'simple_switch/application', media: 'all' %>
6
+ <%= javascript_include_tag 'simple_switch/application' %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ SimpleSwitch::Engine.routes.draw do
2
+ end
@@ -0,0 +1,24 @@
1
+ class CreateSimpleSwitchTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :simple_switch_features do |t|
4
+ t.string :name, null: false, index: true
5
+ t.string :description, limit: 500
6
+
7
+ t.timestamps null: false
8
+ end
9
+
10
+ create_table :simple_switch_environments do |t|
11
+ t.string :name, null: false, index: true
12
+
13
+ t.timestamps null: false
14
+ end
15
+
16
+ create_table :simple_switch_states do |t|
17
+ t.boolean :status, default: false
18
+ t.belongs_to :feature, index: true
19
+ t.belongs_to :environment, index: true
20
+
21
+ t.timestamps null: false
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SimpleSwitch
4
+ module Generators
5
+
6
+ class InitializeGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('../../templates', __FILE__)
8
+
9
+ desc 'Copy initializer file simple_switch.rb to config/initializers.'
10
+
11
+ def copy_initializer
12
+ copy_file 'simple_switch.rb', 'config/initializers/simple_switch.rb'
13
+ end
14
+ end
15
+
16
+ end
17
+ end