arturo 1.6.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +84 -0
- data/LICENSE +13 -0
- data/README.md +36 -8
- data/{lib/generators/arturo/templates/semicolon.png → app/assets/images/colon.png} +0 -0
- data/{lib/generators/arturo/templates → app/assets/javascripts}/arturo.js +0 -0
- data/{lib/generators/arturo/templates → app/assets/stylesheets}/arturo.css +3 -3
- data/app/helpers/arturo/features_helper.rb +10 -1
- data/app/views/arturo/features/_form.html.erb +2 -2
- data/lib/arturo/feature_caching.rb +10 -0
- data/lib/generators/arturo/assets_generator.rb +9 -5
- metadata +7 -6
- metadata.gz.sig +2 -1
- data/HISTORY.md +0 -16
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
## v1.6.1
|
2
|
+
|
3
|
+
`Arturo::FeaturesHelper#error_messages_for` has been deprecated in favor of
|
4
|
+
`error_messages_for_feature` because it conflicts with a Rails and DynamicForm
|
5
|
+
method. It will be removed in v1.7.0. This only affects people who have written
|
6
|
+
their own feature-management pages that use this helper.
|
7
|
+
|
8
|
+
## v1.6.0
|
9
|
+
|
10
|
+
Formerly, whitelists and blacklists had to be *feature-specific*:
|
11
|
+
|
12
|
+
Arturo::Feature.whitelist(:foo) do |recipient|
|
13
|
+
recipient.plan.has_foo?
|
14
|
+
end
|
15
|
+
|
16
|
+
Now whitelists and blacklists can be global. The block takes the feature
|
17
|
+
as the first argument:
|
18
|
+
|
19
|
+
Arturo::Feature.whitelist do |feature, recipient|
|
20
|
+
recipient.plan.has?(feature.to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
## v1.5.3
|
24
|
+
|
25
|
+
Set `signing_key` in gemspec only if the file exists.
|
26
|
+
|
27
|
+
The `FeaturesController` docs erroneously said to override `#permitted?`.
|
28
|
+
The correct method name is `may_manage_features?`.
|
29
|
+
|
30
|
+
## v1.5.2
|
31
|
+
|
32
|
+
The gem is now signed. The public key is
|
33
|
+
[gem-public_cert.pem](./gem-public_cert.pem).
|
34
|
+
|
35
|
+
## v1.5.1
|
36
|
+
|
37
|
+
Use just ActiveRecord, not all of Rails, when defining different behavior
|
38
|
+
for different versions.
|
39
|
+
|
40
|
+
Unify interface of `Feature` and `NoSuchFeature` so the latter fulfills the
|
41
|
+
null-object pattern.
|
42
|
+
|
43
|
+
## v1.5.0
|
44
|
+
|
45
|
+
This project is now licensed under the
|
46
|
+
[APLv2](https://www.apache.org/licenses/LICENSE-2.0.html).
|
47
|
+
|
48
|
+
Arturo now works on Rails 3.0 and Rails 4.0. Helpers are no longer mixed into
|
49
|
+
the global view, but are under the `arturo_engine` namespace, as is the
|
50
|
+
convention in Rails 3.1+.
|
51
|
+
|
52
|
+
The feature cache will return `NoSuchFeature` for cache misses instead of `nil`,
|
53
|
+
which clients can treat like a `Feature` that is always off.
|
54
|
+
|
55
|
+
Better error messages when managing features, and the addition of the
|
56
|
+
`arturo_flash_messages` helper method.
|
57
|
+
|
58
|
+
Add `Feature.last_updated_at` to get the most recent `updated_at` among all
|
59
|
+
`Feature`s.
|
60
|
+
|
61
|
+
## v1.3.0
|
62
|
+
|
63
|
+
Add `Arturo::Middleware`, which passes requests down the stack if an only if
|
64
|
+
a particular feature is available.
|
65
|
+
|
66
|
+
`TestSupport` methods use `Feature.to_feature`.
|
67
|
+
|
68
|
+
## v 1.1.0 - cleanup
|
69
|
+
|
70
|
+
* changed `require_feature!` to `require_feature`
|
71
|
+
* replaced `Arturo.permit_management` and `Arturo.feature_recipient`
|
72
|
+
blocks with instance methods
|
73
|
+
`Arturo::FeatureManagement.may_manage_features?` and
|
74
|
+
`Arturo::FeatureAvailability.feature_recipient`
|
75
|
+
|
76
|
+
## v 1.0.0 - Initial Release
|
77
|
+
|
78
|
+
* `require_feature!` controller filter
|
79
|
+
* `if_feature_enabled` controller and view method
|
80
|
+
* `feature_enabled?` controller and view method
|
81
|
+
* CRUD for features
|
82
|
+
* `Arturo.permit_management` to configure management permission
|
83
|
+
* `Arturo.feature_recipient` to configure on what basis features are deployed
|
84
|
+
* whitelists and blacklists
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2012-2013 James A. Rosen
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -66,19 +66,18 @@ feature and deploy it to all users.
|
|
66
66
|
|
67
67
|
## Installation
|
68
68
|
|
69
|
-
### In Rails 3, with Bundler
|
69
|
+
### In Rails 3 or 4, with Bundler
|
70
70
|
|
71
71
|
gem 'arturo', '~> 1.0'
|
72
72
|
|
73
|
-
### In Rails 3, without Bundler
|
73
|
+
### In Rails 3 or 4, without Bundler
|
74
74
|
|
75
75
|
$ gem install arturo --version="~> 1.0"
|
76
76
|
|
77
77
|
### In Rails 2.3
|
78
78
|
|
79
|
-
|
80
|
-
[`rails_2_3` branch](http://github.com/jamesarosen/arturo/tree/rails_2_3)
|
81
|
-
of Arturo.
|
79
|
+
Rails 2.3 is no longer supported and has been archived on the
|
80
|
+
[`rails_2_3` branch](http://github.com/jamesarosen/arturo/tree/rails_2_3).
|
82
81
|
|
83
82
|
## Configuration
|
84
83
|
|
@@ -195,6 +194,13 @@ If, on the other hand, no users on the free plan should have the
|
|
195
194
|
user.account.free?
|
196
195
|
end
|
197
196
|
|
197
|
+
If you want to whitelist or blacklist large groups of features at once, you
|
198
|
+
can move the feature argument into the block:
|
199
|
+
|
200
|
+
Arturo::Feature.whitelist do |feature, user|
|
201
|
+
user.account.has?(feature.to_sym)
|
202
|
+
end
|
203
|
+
|
198
204
|
### Feature Conditionals
|
199
205
|
|
200
206
|
All that configuration is just a waste of time if Arturo didn't modify the
|
@@ -260,11 +266,27 @@ Both check whether the `foo` feature exists and is enabled for `recipient`.
|
|
260
266
|
|
261
267
|
#### Caching
|
262
268
|
|
263
|
-
**Note**: Arturo
|
269
|
+
**Note**: Arturo has support for caching `Feature` lookups, but doesn't yet
|
270
|
+
integrate with Rails's caching. This means you should be very careful when
|
264
271
|
caching actions or pages that involve feature detection as you will get
|
265
272
|
strange behavior when a user who has access to a feature requests a page
|
266
|
-
just after one who does not (and vice versa).
|
267
|
-
|
273
|
+
just after one who does not (and vice versa).
|
274
|
+
|
275
|
+
To enable caching `Feature` lookups, mix `Arturo::FeatureCaching` into
|
276
|
+
`Arturo::Feature` and set the `cache_ttl`. This is best done in an
|
277
|
+
initializer:
|
278
|
+
|
279
|
+
Arturo::Feature.extend(Arturo::FeatureCaching)
|
280
|
+
Arturo::Feature.cache_ttl = 10.minutes
|
281
|
+
|
282
|
+
You can also warm the cache on startup:
|
283
|
+
|
284
|
+
Arturo::Feature.warm_cache!
|
285
|
+
|
286
|
+
This will pre-fetch all `Feature`s and put them in the cache.
|
287
|
+
|
288
|
+
|
289
|
+
The following is the **intended** support for integration with view caching:
|
268
290
|
|
269
291
|
Both the `require_feature` before filter and the `if_feature_enabled` block
|
270
292
|
evaluation automatically append a string based on the feature's
|
@@ -277,3 +299,9 @@ percentage. See `Arturo::CacheSupport` for more information.
|
|
277
299
|
Arturo gets its name from
|
278
300
|
[Professor Maximillian Arturo](http://en.wikipedia.org/wiki/Maximillian_Arturo)
|
279
301
|
on [Sliders](http://en.wikipedia.org/wiki/Sliders).
|
302
|
+
|
303
|
+
## Quality Metrics
|
304
|
+
|
305
|
+
[![Build Status](https://travis-ci.org/jamesarosen/arturo.png?branch=master)](https://travis-ci.org/jamesarosen/arturo)
|
306
|
+
|
307
|
+
[![Code Quality](https://codeclimate.com/github/jamesarosen/arturo.png)](https://codeclimate.com/github/jamesarosen/arturo)
|
File without changes
|
File without changes
|
@@ -43,12 +43,12 @@ output.deployment_percentage:after { content: "%"; }
|
|
43
43
|
display: block;
|
44
44
|
}
|
45
45
|
|
46
|
-
.feature_new label + input, .feature_new label + textarea, .feature_new label + select,
|
46
|
+
.feature_new label + input, .feature_new label + textarea, .feature_new label + select,
|
47
47
|
.feature_edit label + input, .feature_edit label + textarea, .feature_edit label + select {
|
48
48
|
margin-top: 0.5em;
|
49
49
|
}
|
50
50
|
|
51
|
-
.feature_new input + label, .feature_new textarea + label, .feature_new select + label,
|
51
|
+
.feature_new input + label, .feature_new textarea + label, .feature_new select + label,
|
52
52
|
.feature_edit input + label, .feature_edit textarea + label, .feature_edit select + label {
|
53
53
|
margin-top: 1.5em;
|
54
54
|
}
|
@@ -56,7 +56,7 @@ output.deployment_percentage:after { content: "%"; }
|
|
56
56
|
.feature_new input[type=text], .feature_edit input[type=text] { padding: 0.5em; }
|
57
57
|
|
58
58
|
.feature_new input.symbol, .feature_edit input.symbol {
|
59
|
-
background: transparent url('/images/
|
59
|
+
background: transparent url('/images/colon.png') no-repeat 3px 4px;
|
60
60
|
font-family: "DejaVu Sans Mono", "Droid Sans Mono", "Mondale", monospace;
|
61
61
|
padding-left: 9px;
|
62
62
|
}
|
@@ -37,7 +37,16 @@ module Arturo
|
|
37
37
|
content_tag(:output, value, { 'for' => id, 'class' => 'deployment_percentage no_js' })
|
38
38
|
end
|
39
39
|
|
40
|
-
def error_messages_for(feature, attribute)
|
40
|
+
def error_messages_for(feature, attribute, *args, &block)
|
41
|
+
if feature.kind_of?(Arturo::Feature)
|
42
|
+
warn 'Arturo::FeaturesHelper#error_messages_for has been deprecated; use #error_messages_for_feature.'
|
43
|
+
error_messages_for_feature(feature, attribute)
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_messages_for_feature(feature, attribute)
|
41
50
|
if feature.errors[attribute].any?
|
42
51
|
content_tag(:ul, :class => 'errors') do
|
43
52
|
feature.errors[attribute].map { |msg| content_tag(:li, msg, :class => 'error') }.join('').html_safe
|
@@ -4,12 +4,12 @@
|
|
4
4
|
|
5
5
|
<%= form.label(:symbol) %>
|
6
6
|
<%= form.text_field(:symbol, :required => 'required', :pattern => Arturo::Feature::SYMBOL_REGEX.source, :class => 'symbol') %>
|
7
|
-
<%=
|
7
|
+
<%= error_messages_for_feature(feature, :symbol) %>
|
8
8
|
|
9
9
|
<%= form.label(:deployment_percentage) %>
|
10
10
|
<%= form.range_field(:deployment_percentage, :min => '0', :max => '100', :step => '1', :class => 'deployment_percentage') %>
|
11
11
|
<%= deployment_percentage_output_tag 'feature_deployment_percentage', feature.deployment_percentage %>
|
12
|
-
<%=
|
12
|
+
<%= error_messages_for_feature(feature, :deployment_percentage) %>
|
13
13
|
|
14
14
|
<footer><%= form.submit %></footer>
|
15
15
|
</fieldset>
|
@@ -48,6 +48,16 @@ module Arturo
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
# Warms the cache by fetching all `Feature`s and caching them.
|
52
|
+
# This is perfect for use in an initializer.
|
53
|
+
def warm_cache!
|
54
|
+
raise "Cannot warm Feature Cache; caching is disabled" unless caches_features?
|
55
|
+
|
56
|
+
all.each do |feature|
|
57
|
+
feature_cache.write(feature.symbol.to_sym, feature, :expires_in => cache_ttl)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
51
61
|
protected
|
52
62
|
|
53
63
|
# Quack like a Rails cache.
|
@@ -2,15 +2,19 @@ require 'rails/generators'
|
|
2
2
|
|
3
3
|
module Arturo
|
4
4
|
class AssetsGenerator < Rails::Generators::Base
|
5
|
+
|
5
6
|
def self.source_root
|
6
|
-
|
7
|
+
Arturo::Engine.root_path
|
7
8
|
end
|
8
9
|
|
9
10
|
def copy_assets
|
10
|
-
copy_file 'arturo.css',
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
copy_file 'lib/generators/arturo/templates/arturo_customizations.css', 'public/stylesheets/arturo_customizations.css', :skip => true
|
12
|
+
|
13
|
+
unless defined?(Sprockets)
|
14
|
+
copy_file 'app/assets/stylesheets/arturo.css', 'public/stylesheets/arturo.css', :force => true
|
15
|
+
copy_file 'app/assets/javascripts/arturo.js', 'public/javascripts/arturo.js'
|
16
|
+
copy_file 'app/assets/images/colon.png', 'public/images/colon.png'
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arturo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
eExwbFhYR2tTdDNOUzhSRmhRRkNPSWRnc1hFbGpFdlpwVnh1cmk1T2JIMHpx
|
38
38
|
eFVOWE9scQo1bEVpNTZuM0tra0tSaHUxY0U2MWdBPT0KLS0tLS1FTkQgQ0VS
|
39
39
|
VElGSUNBVEUtLS0tLQo=
|
40
|
-
date: 2013-
|
40
|
+
date: 2013-07-08 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rails
|
@@ -195,12 +195,12 @@ files:
|
|
195
195
|
- lib/generators/arturo/initializer_generator.rb
|
196
196
|
- lib/generators/arturo/migration_generator.rb
|
197
197
|
- lib/generators/arturo/routes_generator.rb
|
198
|
-
- lib/generators/arturo/templates/arturo.css
|
199
|
-
- lib/generators/arturo/templates/arturo.js
|
200
198
|
- lib/generators/arturo/templates/arturo_customizations.css
|
201
199
|
- lib/generators/arturo/templates/initializer.rb
|
202
200
|
- lib/generators/arturo/templates/migration.rb
|
203
|
-
-
|
201
|
+
- app/assets/images/colon.png
|
202
|
+
- app/assets/javascripts/arturo.js
|
203
|
+
- app/assets/stylesheets/arturo.css
|
204
204
|
- app/controllers/arturo/features_controller.rb
|
205
205
|
- app/helpers/arturo/features_helper.rb
|
206
206
|
- app/models/arturo/feature.rb
|
@@ -214,7 +214,8 @@ files:
|
|
214
214
|
- config/locales/en.yml
|
215
215
|
- config/routes.rb
|
216
216
|
- README.md
|
217
|
-
-
|
217
|
+
- CHANGELOG.md
|
218
|
+
- LICENSE
|
218
219
|
homepage: http://github.com/jamesarosen/arturo
|
219
220
|
licenses:
|
220
221
|
- APLv2
|
metadata.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
x$
|
2
|
+
���y�֘E��*��Ml])�@z�����T�6s�A8-q�E��4yu�� 0}�~L���8���z���k7۲K����k��3��$��"W�RM��Y�~�� uMBPO�cC�rp��~
|
data/HISTORY.md
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
## v 1.1.0 - cleanup
|
2
|
-
* changed `require_feature!` to `require_feature`
|
3
|
-
* replaced `Arturo.permit_management` and `Arturo.feature_recipient`
|
4
|
-
blocks with instance methods
|
5
|
-
`Arturo::FeatureManagement.may_manage_features?` and
|
6
|
-
`Arturo::FeatureAvailability.feature_recipient`
|
7
|
-
|
8
|
-
## v 1.0.0 - Initial Release
|
9
|
-
* `require_feature!` controller filter
|
10
|
-
* `if_feature_enabled` controller and view method
|
11
|
-
* `feature_enabled?` controller and view method
|
12
|
-
* CRUD for features
|
13
|
-
* `Arturo.permit_management` to configure management permission
|
14
|
-
* `Arturo.feature_recipient` to configure on what basis features are deployed
|
15
|
-
* whitelists and blacklists
|
16
|
-
|