arturo 1.2.0 → 1.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.
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
-