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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +175 -58
- data/Rakefile +21 -1
- data/app/assets/javascripts/simple_switch/application.js +1 -0
- data/app/assets/stylesheets/simple_switch/application.css +4 -0
- data/app/controllers/simple_switch/application_controller.rb +4 -0
- data/app/helpers/simple_switch/application_helper.rb +4 -0
- data/app/models/simple_switch/environment.rb +8 -0
- data/app/models/simple_switch/feature.rb +8 -0
- data/app/models/simple_switch/state.rb +15 -0
- data/app/views/layouts/simple_switch/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20151216180633_create_simple_switch_tables.simple_switch.rb +24 -0
- data/lib/generators/simple_switch/initialize_generator.rb +17 -0
- data/lib/generators/simple_switch/install_generator.rb +13 -3
- data/lib/generators/templates/feature_config_sample.yml +16 -12
- data/lib/generators/templates/migration.rb +24 -0
- data/lib/generators/templates/simple_switch.rb +9 -2
- data/lib/simple_switch.rb +10 -6
- data/lib/simple_switch/engine.rb +10 -0
- data/lib/simple_switch/feature_manager.rb +15 -0
- data/lib/simple_switch/feature_manager_db.rb +88 -0
- data/lib/simple_switch/feature_manager_yaml.rb +68 -0
- data/lib/simple_switch/manager_shared_methods.rb +52 -0
- data/lib/simple_switch/railtie.rb +12 -0
- data/lib/simple_switch/shared_controller_methods.rb +2 -2
- data/lib/simple_switch/version.rb +1 -1
- data/lib/tasks/simple_switch.rake +106 -0
- data/spec/config/feature_config.yml +10 -6
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/simple_switch.rb +17 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +44 -0
- data/spec/dummy/db/seeds.rb +17 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +54 -0
- data/spec/dummy/log/test.log +7280 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/simple_switch_environments.rb +5 -0
- data/spec/factories/simple_switch_features.rb +5 -0
- data/spec/factories/simple_switch_states.rb +5 -0
- data/spec/models/simple_switch/environment_spec.rb +11 -0
- data/spec/models/simple_switch/feature_spec.rb +11 -0
- data/spec/models/simple_switch/state_spec.rb +11 -0
- data/spec/route_helper.rb +5 -0
- data/spec/simple_switch_feature_managers_spec.rb +282 -0
- data/spec/spec_helper.rb +22 -27
- metadata +203 -17
- data/.gitignore +0 -3
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/codeclimate.yml +0 -3
- data/lib/generators/simple_switch/install_yaml_generator.rb +0 -18
- data/lib/simple_switch/switch.rb +0 -77
- data/simple_switch.gemspec +0 -26
- data/spec/simple_switch_spec.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 809dd823c24166538111b727e8cf8a270cbc7cb9
|
4
|
+
data.tar.gz: aaa927b1c39fad4af8bd64207aee1c9401a13166
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
###
|
31
|
+
### Database Strategy
|
32
|
+
Store and manage features and configurations in database.
|
32
33
|
|
33
|
-
Run
|
34
|
+
Run initialize generator:
|
34
35
|
|
35
|
-
$ rails generate simple_switch:
|
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.
|
39
|
-
|
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
|
-
|
42
|
-
|
43
|
-
config.feature_config_file_dir = 'config'
|
59
|
+
$ rails generate simple_switch:install
|
60
|
+
$ bundle exec rake db:migrate
|
44
61
|
|
45
|
-
|
46
|
-
config.feature_config_file_name = 'feature_config.yml'
|
62
|
+
The data structure for `simple_switch` is described as followed:
|
47
63
|
|
48
|
-
|
64
|
+
![ERR Diagram](/images/err_diagram.png)
|
49
65
|
|
50
|
-
|
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
|
-
$
|
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
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
production: false
|
75
|
+
````ruby
|
76
|
+
class TestModel < ActiveRecord::Base
|
77
|
+
...
|
65
78
|
|
66
|
-
|
79
|
+
if feature_on?(:foo)
|
80
|
+
def foo_method
|
81
|
+
...
|
82
|
+
end
|
83
|
+
end
|
67
84
|
|
68
|
-
|
85
|
+
def bar_method
|
86
|
+
if feature_on?(:bar)
|
69
87
|
...
|
88
|
+
end
|
89
|
+
end
|
70
90
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
91
|
+
...
|
92
|
+
end
|
93
|
+
````
|
94
|
+
In controllers like this:
|
76
95
|
|
77
|
-
|
78
|
-
|
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
|
-
|
107
|
+
...
|
108
|
+
end
|
87
109
|
|
88
|
-
|
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
|
-
|
92
|
-
...
|
128
|
+
Run initialize generator:
|
93
129
|
|
94
|
-
|
95
|
-
redirect_to :back
|
96
|
-
end
|
130
|
+
$ rails generate simple_switch:initialize
|
97
131
|
|
98
|
-
|
99
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
214
|
+
````erb
|
215
|
+
<% if feature_on?(:foo) %>
|
216
|
+
<p>Experiment foo is on</p>
|
217
|
+
<% end %>
|
109
218
|
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
121
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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,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,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
|