simple_switch 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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