arturo 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -239,6 +239,11 @@ The latter can be used like so:
239
239
  widgets
240
240
  end
241
241
 
242
+ #### Rack Middleware
243
+
244
+ require 'arturo'
245
+ use Arturo::Middleware, :feature => :my_feature
246
+
242
247
  #### Outside a Controller
243
248
 
244
249
  If you want to check availability outside of a controller or view (really
data/lib/arturo.rb CHANGED
@@ -5,6 +5,7 @@ module Arturo
5
5
  require 'arturo/feature_management'
6
6
  require 'arturo/feature_caching'
7
7
  require 'arturo/controller_filters'
8
+ require 'arturo/middleware'
8
9
  require 'arturo/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
9
10
 
10
11
  class <<self
@@ -0,0 +1,60 @@
1
+ module Arturo
2
+ # A Rack middleware that requires a feature to be present. By default,
3
+ # checks feature availability against an `arturo.recipient` object
4
+ # in the `env`. If that object is missing, this middleware always fails,
5
+ # even if the feature is available for everyone.
6
+ #
7
+ # ## Usage
8
+ #
9
+ # use Arturo::Middleware, :feature => :foo
10
+ #
11
+ # ## Options
12
+ #
13
+ # * feature -- the name of the feature to require, as a Symbol; required
14
+ #
15
+ # * recipient -- the key in the `env` hash under which the feature
16
+ # recipient can be found; defaults to "arturo.recipient".
17
+ # * on_unavailable -- a Rack-like object
18
+ # (has `#call(Hash) -> [status, headers, body]`) that
19
+ # is called when the feature is unavailable; defaults
20
+ # to returning `[ 404, {}, ['Not Found'] ]`.
21
+ class Middleware
22
+
23
+ MISSING_FEATURE_ERROR = "Cannot create an Arturo::Middleware without a :feature"
24
+
25
+ DEFAULT_RECIPIENT_KEY = 'arturo.recipient'
26
+
27
+ DEFAULT_ON_UNAVAILABLE = lambda { |env| [ 404, {}, ['Not Found'] ] }
28
+
29
+ def initialize(app, options = {})
30
+ @app = app
31
+ @feature = options[:feature]
32
+ raise ArgumentError.new(MISSING_FEATURE_ERROR) unless @feature
33
+ @recipient_key = options[:recipient] || DEFAULT_RECIPIENT_KEY
34
+ @on_unavailable = options[:on_unavailable] || DEFAULT_ON_UNAVAILABLE
35
+ end
36
+
37
+ def call(env)
38
+ if enabled_for_recipient?(env)
39
+ @app.call(env)
40
+ else
41
+ fail(env)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def enabled_for_recipient?(env)
48
+ ::Arturo.feature_enabled_for?(@feature, recipient(env))
49
+ end
50
+
51
+ def recipient(env)
52
+ env[@recipient_key]
53
+ end
54
+
55
+ def fail(env)
56
+ @on_unavailable.call(env)
57
+ end
58
+
59
+ end
60
+ end
@@ -1,4 +1,4 @@
1
- Arturo.class_eval do
1
+ Arturo.instance_eval do
2
2
 
3
3
  # Enable a feature; create it if necessary.
4
4
  # For use in testing. Not auto-required on load. To load,
@@ -7,11 +7,11 @@ Arturo.class_eval do
7
7
  #
8
8
  # @param [Symbol, String] name the feature name
9
9
  def enable_feature!(name)
10
- feature = Arturo::Feature.find_by_symbol(name)
10
+ feature = Arturo::Feature.to_feature(name)
11
11
  if feature
12
12
  feature.update_attributes(:deployment_percentage => 100)
13
13
  else
14
- Arturo::Feature.create(:symbol => name, :deployment_percentage => 100)
14
+ Arturo::Feature.create!(:symbol => name, :deployment_percentage => 100)
15
15
  end
16
16
  end
17
17
 
@@ -22,7 +22,7 @@ Arturo.class_eval do
22
22
  #
23
23
  # @param [Symbol, String] name the feature name
24
24
  def disable_feature!(name)
25
- if (feature = Arturo::Feature.find_by_symbol(name))
25
+ if (feature = Arturo::Feature.to_feature(name))
26
26
  feature.update_attributes(:deployment_percentage => 0)
27
27
  end
28
28
  end
metadata CHANGED
@@ -1,110 +1,106 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: arturo
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.0
4
5
  prerelease:
5
- version: 1.2.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - James A. Rosen
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-04-05 00:00:00 -07:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-11-01 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: rails
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2154174960 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
18
+ requirements:
22
19
  - - ~>
23
- - !ruby/object:Gem::Version
24
- version: "3.0"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: mocha
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2154174960
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &2154174560 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
36
33
  type: :development
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rake
40
34
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2154174560
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &2154174100 !ruby/object:Gem::Requirement
42
39
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
47
44
  type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: redgreen
51
45
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2154174100
47
+ - !ruby/object:Gem::Dependency
48
+ name: redgreen
49
+ requirement: &2154173600 !ruby/object:Gem::Requirement
53
50
  none: false
54
- requirements:
51
+ requirements:
55
52
  - - ~>
56
- - !ruby/object:Gem::Version
57
- version: "1.2"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
58
55
  type: :development
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
61
- name: sqlite3-ruby
62
56
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *2154173600
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3-ruby
60
+ requirement: &2154173100 !ruby/object:Gem::Requirement
64
61
  none: false
65
- requirements:
62
+ requirements:
66
63
  - - ~>
67
- - !ruby/object:Gem::Version
68
- version: "1.3"
64
+ - !ruby/object:Gem::Version
65
+ version: '1.3'
69
66
  type: :development
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
72
- name: factory_girl
73
67
  prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *2154173100
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_girl
71
+ requirement: &2154172640 !ruby/object:Gem::Requirement
75
72
  none: false
76
- requirements:
73
+ requirements:
77
74
  - - ~>
78
- - !ruby/object:Gem::Version
79
- version: "1.3"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.3'
80
77
  type: :development
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
83
- name: timecop
84
78
  prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
79
+ version_requirements: *2154172640
80
+ - !ruby/object:Gem::Dependency
81
+ name: timecop
82
+ requirement: &2154172180 !ruby/object:Gem::Requirement
86
83
  none: false
87
- requirements:
84
+ requirements:
88
85
  - - ~>
89
- - !ruby/object:Gem::Version
90
- version: "0.3"
86
+ - !ruby/object:Gem::Version
87
+ version: '0.3'
91
88
  type: :development
92
- version_requirements: *id007
89
+ prerelease: false
90
+ version_requirements: *2154172180
93
91
  description: Deploy features incrementally to your users
94
92
  email: james.a.rosen@gmail.com
95
93
  executables: []
96
-
97
94
  extensions: []
98
-
99
95
  extra_rdoc_files: []
100
-
101
- files:
96
+ files:
102
97
  - lib/arturo/controller_filters.rb
103
98
  - lib/arturo/engine.rb
104
99
  - lib/arturo/feature_availability.rb
105
100
  - lib/arturo/feature_caching.rb
106
101
  - lib/arturo/feature_factories.rb
107
102
  - lib/arturo/feature_management.rb
103
+ - lib/arturo/middleware.rb
108
104
  - lib/arturo/special_handling.rb
109
105
  - lib/arturo/test_support.rb
110
106
  - lib/arturo.rb
@@ -132,34 +128,29 @@ files:
132
128
  - config/routes.rb
133
129
  - README.md
134
130
  - HISTORY.md
135
- has_rdoc: true
136
131
  homepage: http://github.com/jamesarosen/arturo
137
132
  licenses: []
138
-
139
133
  post_install_message:
140
134
  rdoc_options: []
141
-
142
- require_paths:
135
+ require_paths:
143
136
  - .
144
137
  - lib
145
- required_ruby_version: !ruby/object:Gem::Requirement
138
+ required_ruby_version: !ruby/object:Gem::Requirement
146
139
  none: false
147
- requirements:
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- version: "0"
151
- required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
145
  none: false
153
- requirements:
154
- - - ">="
155
- - !ruby/object:Gem::Version
156
- version: "0"
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
157
150
  requirements: []
158
-
159
151
  rubyforge_project:
160
- rubygems_version: 1.6.1
152
+ rubygems_version: 1.8.6
161
153
  signing_key:
162
154
  specification_version: 2
163
155
  summary: Feature sliders, wrapped up in an engine
164
156
  test_files: []
165
-