merb-core 0.9.2 → 0.9.3

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.
Files changed (104) hide show
  1. data/Rakefile +61 -11
  2. data/bin/merb +5 -1
  3. data/lib/merb-core.rb +202 -25
  4. data/lib/merb-core/autoload.rb +19 -17
  5. data/lib/merb-core/bootloader.rb +84 -71
  6. data/lib/merb-core/config.rb +19 -14
  7. data/lib/merb-core/controller/abstract_controller.rb +16 -17
  8. data/lib/merb-core/controller/exceptions.rb +115 -70
  9. data/lib/merb-core/controller/merb_controller.rb +62 -38
  10. data/lib/merb-core/controller/mime.rb +1 -1
  11. data/lib/merb-core/controller/mixins/authentication.rb +87 -0
  12. data/lib/merb-core/controller/mixins/controller.rb +16 -15
  13. data/lib/merb-core/controller/mixins/render.rb +113 -19
  14. data/lib/merb-core/controller/mixins/responder.rb +8 -2
  15. data/lib/merb-core/controller/template.rb +1 -1
  16. data/lib/merb-core/core_ext.rb +1 -0
  17. data/lib/merb-core/core_ext/class.rb +113 -6
  18. data/lib/merb-core/core_ext/hash.rb +43 -39
  19. data/lib/merb-core/core_ext/kernel.rb +75 -38
  20. data/lib/merb-core/core_ext/mash.rb +4 -4
  21. data/lib/merb-core/core_ext/object.rb +18 -7
  22. data/lib/merb-core/core_ext/set.rb +9 -4
  23. data/lib/merb-core/core_ext/string.rb +29 -9
  24. data/lib/merb-core/core_ext/time.rb +13 -0
  25. data/lib/merb-core/dispatch/cookies.rb +1 -2
  26. data/lib/merb-core/dispatch/dispatcher.rb +18 -10
  27. data/lib/merb-core/dispatch/exceptions.html.erb +1 -1
  28. data/lib/merb-core/dispatch/request.rb +3 -0
  29. data/lib/merb-core/dispatch/router.rb +10 -7
  30. data/lib/merb-core/dispatch/router/behavior.rb +36 -27
  31. data/lib/merb-core/dispatch/router/route.rb +7 -2
  32. data/lib/merb-core/dispatch/session/cookie.rb +4 -4
  33. data/lib/merb-core/dispatch/session/memcached.rb +17 -5
  34. data/lib/merb-core/logger.rb +2 -2
  35. data/lib/merb-core/plugins.rb +16 -4
  36. data/lib/merb-core/rack/adapter/ebb.rb +4 -1
  37. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -0
  38. data/lib/merb-core/rack/adapter/fcgi.rb +1 -0
  39. data/lib/merb-core/rack/adapter/mongrel.rb +1 -0
  40. data/lib/merb-core/rack/adapter/runner.rb +1 -0
  41. data/lib/merb-core/rack/adapter/thin.rb +3 -1
  42. data/lib/merb-core/rack/adapter/webrick.rb +1 -0
  43. data/lib/merb-core/rack/application.rb +17 -1
  44. data/lib/merb-core/server.rb +78 -28
  45. data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -3
  46. data/lib/merb-core/test/helpers/request_helper.rb +81 -27
  47. data/lib/merb-core/test/helpers/view_helper.rb +1 -1
  48. data/lib/merb-core/test/matchers/controller_matchers.rb +55 -5
  49. data/lib/merb-core/test/matchers/route_matchers.rb +8 -17
  50. data/lib/merb-core/test/matchers/view_matchers.rb +53 -11
  51. data/lib/merb-core/test/run_specs.rb +22 -14
  52. data/lib/merb-core/test/tasks/spectasks.rb +54 -33
  53. data/lib/merb-core/vendor/facets/inflect.rb +91 -2
  54. data/lib/merb-core/version.rb +2 -2
  55. data/spec/private/config/config_spec.rb +54 -26
  56. data/spec/private/core_ext/class_spec.rb +22 -0
  57. data/spec/private/core_ext/hash_spec.rb +70 -54
  58. data/spec/private/core_ext/kernel_spec.rb +149 -14
  59. data/spec/private/core_ext/object_spec.rb +92 -10
  60. data/spec/private/core_ext/string_spec.rb +162 -4
  61. data/spec/private/core_ext/time_spec.rb +16 -0
  62. data/spec/private/dispatch/bootloader_spec.rb +24 -0
  63. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +1 -1
  64. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +1 -1
  65. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +1 -1
  66. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +1 -1
  67. data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
  68. data/spec/private/dispatch/fixture/log/merb_test.log +138 -0
  69. data/spec/private/plugins/plugin_spec.rb +79 -8
  70. data/spec/private/rack/application_spec.rb +1 -1
  71. data/spec/public/abstract_controller/controllers/filters.rb +26 -0
  72. data/spec/public/abstract_controller/controllers/helpers.rb +2 -2
  73. data/spec/public/abstract_controller/controllers/partial.rb +2 -2
  74. data/spec/public/abstract_controller/controllers/render.rb +16 -4
  75. data/spec/public/abstract_controller/filter_spec.rb +8 -0
  76. data/spec/public/abstract_controller/render_spec.rb +12 -0
  77. data/spec/public/controller/authentication_spec.rb +103 -0
  78. data/spec/public/controller/base_spec.rb +4 -3
  79. data/spec/public/controller/controllers/authentication.rb +47 -0
  80. data/spec/public/controller/controllers/base.rb +1 -0
  81. data/spec/public/controller/controllers/display.rb +30 -0
  82. data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
  83. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
  84. data/spec/public/controller/display_spec.rb +17 -0
  85. data/spec/public/controller/spec_helper.rb +1 -0
  86. data/spec/public/controller/url_spec.rb +25 -7
  87. data/spec/public/core/merb_core_spec.rb +34 -0
  88. data/spec/public/directory_structure/directory/app/controllers/custom.rb +2 -2
  89. data/spec/public/directory_structure/directory/log/merb_test.log +48 -0
  90. data/spec/public/logger/logger_spec.rb +10 -4
  91. data/spec/public/reloading/directory/app/controllers/reload.rb +1 -1
  92. data/spec/public/reloading/directory/log/merb_test.log +13 -0
  93. data/spec/public/reloading/reload_spec.rb +23 -22
  94. data/spec/public/request/request_spec.rb +2 -0
  95. data/spec/public/router/nested_resources_spec.rb +7 -0
  96. data/spec/public/router/resources_spec.rb +46 -1
  97. data/spec/public/router/special_spec.rb +5 -1
  98. data/spec/public/test/controller_matchers_spec.rb +25 -1
  99. data/spec/public/test/controllers/spec_helper_controller.rb +8 -0
  100. data/spec/public/test/request_helper_spec.rb +52 -1
  101. data/spec/public/test/route_matchers_spec.rb +27 -25
  102. data/spec/public/test/view_helper_spec.rb +1 -1
  103. data/spec/public/test/view_matchers_spec.rb +148 -72
  104. metadata +23 -3
@@ -1,21 +1,23 @@
1
1
  module Merb
2
- autoload :AbstractController, "merb-core/controller/abstract_controller"
3
- autoload :BootLoader, "merb-core/bootloader"
4
- autoload :Config, "merb-core/config"
5
- autoload :Const, "merb-core/constants"
6
- autoload :ControllerMixin, "merb-core/controller/mixins/controller"
7
- autoload :ControllerExceptions, "merb-core/controller/exceptions"
8
- autoload :Cookies, "merb-core/dispatch/cookies"
9
- autoload :Dispatcher, "merb-core/dispatch/dispatcher"
10
- autoload :ErubisCaptureMixin, "merb-core/controller/mixins/erubis_capture"
11
- autoload :Plugins, "merb-core/plugins"
12
- autoload :Rack, "merb-core/rack"
13
- autoload :RenderMixin, "merb-core/controller/mixins/render"
14
- autoload :Request, "merb-core/dispatch/request"
15
- autoload :ResponderMixin, "merb-core/controller/mixins/responder"
16
- autoload :Router, "merb-core/dispatch/router"
17
- autoload :SessionMixin, "merb-core/dispatch/session"
18
- autoload :Test, "merb-core/test"
2
+ autoload :AbstractController, "merb-core/controller/abstract_controller"
3
+ autoload :BootLoader, "merb-core/bootloader"
4
+ autoload :Config, "merb-core/config"
5
+ autoload :Const, "merb-core/constants"
6
+ autoload :ControllerMixin, "merb-core/controller/mixins/controller"
7
+ autoload :ControllerExceptions, "merb-core/controller/exceptions"
8
+ autoload :Cookies, "merb-core/dispatch/cookies"
9
+ autoload :Dispatcher, "merb-core/dispatch/dispatcher"
10
+ autoload :AuthenticationMixin, "merb-core/controller/mixins/authentication"
11
+ autoload :BasicAuthenticationMixin, "merb-core/controller/mixins/authentication/basic"
12
+ autoload :ErubisCaptureMixin, "merb-core/controller/mixins/erubis_capture"
13
+ autoload :Plugins, "merb-core/plugins"
14
+ autoload :Rack, "merb-core/rack"
15
+ autoload :RenderMixin, "merb-core/controller/mixins/render"
16
+ autoload :Request, "merb-core/dispatch/request"
17
+ autoload :ResponderMixin, "merb-core/controller/mixins/responder"
18
+ autoload :Router, "merb-core/dispatch/router"
19
+ autoload :SessionMixin, "merb-core/dispatch/session"
20
+ autoload :Test, "merb-core/test"
19
21
  end
20
22
 
21
23
  # Require this rather than autoloading it so we can be sure the default template
@@ -1,7 +1,7 @@
1
1
  module Merb
2
2
 
3
3
  class BootLoader
4
-
4
+
5
5
  # def self.subclasses
6
6
  #---
7
7
  # @semipublic
@@ -9,7 +9,7 @@ module Merb
9
9
  self.subclasses = []
10
10
  self.after_load_callbacks = []
11
11
  self.before_load_callbacks = []
12
-
12
+
13
13
  class << self
14
14
 
15
15
  # Adds the inheriting class to the list of subclasses in a position
@@ -41,8 +41,8 @@ module Merb
41
41
  def before(klass)
42
42
  move_klass(klass, 0)
43
43
  end
44
-
45
- # Move a class that is inside the bootloader to some place in the Array,
44
+
45
+ # Move a class that is inside the bootloader to some place in the Array,
46
46
  # relative to another class.
47
47
  #
48
48
  # ==== Parameters
@@ -53,7 +53,7 @@ module Merb
53
53
  def move_klass(klass, where)
54
54
  index = Merb::BootLoader.subclasses.index(klass.to_s)
55
55
  if index
56
- Merb::BootLoader.subclasses.delete(self.to_s)
56
+ Merb::BootLoader.subclasses.delete(self.to_s)
57
57
  Merb::BootLoader.subclasses.insert(index + where, self.to_s)
58
58
  end
59
59
  end
@@ -65,7 +65,7 @@ module Merb
65
65
  bootloader = subclasses.shift
66
66
  Merb.logger.debug!("Loading: #{bootloader}") if ENV['DEBUG']
67
67
  Object.full_const_get(bootloader).run
68
- end
68
+ end
69
69
  self.subclasses = subklasses
70
70
  end
71
71
 
@@ -89,7 +89,7 @@ module Merb
89
89
  Merb.push_path(:stylesheet, Merb.dir_for(:public) / "stylesheets", nil)
90
90
  Merb.push_path(:javascript, Merb.dir_for(:public) / "javascripts", nil)
91
91
  Merb.push_path(:image, Merb.dir_for(:public) / "images", nil)
92
- nil
92
+ nil
93
93
  end
94
94
 
95
95
  # ==== Parameters
@@ -102,7 +102,7 @@ module Merb
102
102
  def after_app_loads(&block)
103
103
  after_load_callbacks << block
104
104
  end
105
-
105
+
106
106
  # ==== Parameters
107
107
  # &block::
108
108
  # A block to be added to the callbacks that will be executed before the
@@ -114,9 +114,9 @@ module Merb
114
114
  before_load_callbacks << block
115
115
  end
116
116
  end
117
-
117
+
118
118
  end
119
-
119
+
120
120
  end
121
121
 
122
122
  # Set up the logger.
@@ -127,7 +127,7 @@ class Merb::BootLoader::Logger < Merb::BootLoader
127
127
 
128
128
  # Sets Merb.logger to a new logger created based on the config settings.
129
129
  def self.run
130
- Merb.logger = Merb::Logger.new(Merb.log_file, Merb::Config[:log_level], Merb::Config[:log_delimiter], Merb::Config[:log_auto_flush])
130
+ Merb.logger = Merb::Logger.new(Merb.log_file, Merb::Config[:log_level], Merb::Config[:log_delimiter], Merb::Config[:log_auto_flush])
131
131
  end
132
132
  end
133
133
 
@@ -160,17 +160,17 @@ end
160
160
  # path, and whose values can be passed into Merb.push_path (see Merb.push_path
161
161
  # for full details).
162
162
  #
163
- # ==== Note
163
+ # ==== Notes
164
164
  # All paths will default to Merb.root, so you can get a flat-file structure by
165
165
  # doing Merb::Config[:framework] = {}.
166
- #
166
+ #
167
167
  # ==== Example
168
168
  # Merb::Config[:framework] = {
169
169
  # :view => Merb.root / "views"
170
170
  # :model => Merb.root / "models"
171
171
  # :lib => Merb.root / "lib"
172
172
  # }
173
- #
173
+ #
174
174
  # That will set up a flat directory structure with the config files and
175
175
  # controller files under Merb.root, but with models, views, and lib with their
176
176
  # own folders off of Merb.root.
@@ -181,7 +181,7 @@ class Merb::BootLoader::BuildFramework < Merb::BootLoader
181
181
  def run
182
182
  build_framework
183
183
  end
184
-
184
+
185
185
  # This method should be overridden in init.rb before Merb.start to set up
186
186
  # a different framework structure.
187
187
  def build_framework
@@ -201,10 +201,10 @@ class Merb::BootLoader::BuildFramework < Merb::BootLoader
201
201
  end
202
202
 
203
203
  class Merb::BootLoader::Dependencies < Merb::BootLoader
204
-
204
+
205
205
  cattr_accessor :dependencies
206
206
  self.dependencies = []
207
-
207
+
208
208
  # Load the init_file specified in Merb::Config or if not specified, the
209
209
  # init.rb file from the Merb configuration directory, and any environment
210
210
  # files, which register the list of necessary dependencies and any
@@ -214,48 +214,49 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
214
214
  # before or after insertion methods. Since these are loaded from this
215
215
  # bootloader (Dependencies), they can only adapt the bootloaders that
216
216
  # haven't been loaded up until this point.
217
-
217
+
218
218
  def self.run
219
219
  load_initfile
220
- load_env_config
220
+ load_env_config
221
221
  enable_json_gem unless Merb::disabled?(:json)
222
222
  load_dependencies
223
223
  update_logger
224
224
  end
225
-
225
+
226
226
  def self.load_dependencies
227
227
  dependencies.each { |name, ver| Kernel.load_dependency(name, *ver) }
228
228
  end
229
-
229
+
230
230
  def self.enable_json_gem
231
231
  require "json/ext"
232
232
  rescue LoadError
233
233
  require "json/pure"
234
234
  end
235
-
235
+
236
236
  def self.update_logger
237
237
  updated_logger_options = [ Merb.log_file, Merb::Config[:log_level], Merb::Config[:log_delimiter], Merb::Config[:log_auto_flush] ]
238
238
  Merb::BootLoader::Logger.run if updated_logger_options != Merb.logger.init_args
239
239
  end
240
-
240
+
241
241
  private
242
-
242
+
243
243
  # Determines the path for the environment configuration file
244
244
  def self.env_config
245
245
  Merb.dir_for(:config) / "environments" / (Merb.environment + ".rb")
246
246
  end
247
-
247
+
248
248
  # Checks to see whether or not an environment configuration exists
249
249
  def self.env_config?
250
250
  Merb.environment && File.exist?(env_config)
251
251
  end
252
-
252
+
253
253
  # Loads the environment configuration file, if any
254
254
  def self.load_env_config
255
255
  load(env_config) if env_config?
256
256
  end
257
-
258
- # Determines the init file to use, if any
257
+
258
+ # Determines the init file to use, if any.
259
+ # By default Merb uses init.rb from application config directory.
259
260
  def self.initfile
260
261
  if Merb::Config[:init_file]
261
262
  Merb::Config[:init_file].chomp(".rb") + ".rb"
@@ -263,12 +264,12 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
263
264
  Merb.dir_for(:config) / "init.rb"
264
265
  end
265
266
  end
266
-
267
+
267
268
  # Loads the init file, should one exist
268
269
  def self.load_initfile
269
270
  load(initfile) if File.exists?(initfile)
270
271
  end
271
-
272
+
272
273
  end
273
274
 
274
275
  class Merb::BootLoader::BeforeAppRuns < Merb::BootLoader
@@ -291,24 +292,24 @@ end
291
292
  class Merb::BootLoader::LoadClasses < Merb::BootLoader
292
293
  LOADED_CLASSES = {}
293
294
  MTIMES = {}
294
-
295
+
295
296
  class << self
296
297
 
297
298
  # Load all classes inside the load paths.
298
299
  def run
299
300
  orphaned_classes = []
300
301
  # Add models, controllers, and lib to the load path
301
- $LOAD_PATH.unshift Merb.dir_for(:model)
302
+ $LOAD_PATH.unshift Merb.dir_for(:model)
302
303
  $LOAD_PATH.unshift Merb.dir_for(:controller)
303
- $LOAD_PATH.unshift Merb.dir_for(:lib)
304
-
304
+ $LOAD_PATH.unshift Merb.dir_for(:lib)
305
+
305
306
  load_file Merb.dir_for(:application) if File.file?(Merb.dir_for(:application))
306
-
307
+
307
308
  # Require all the files in the registered load paths
308
309
  Merb.load_paths.each do |name, path|
309
310
  next unless path.last && name != :application
310
311
  Dir[path.first / path.last].each do |file|
311
-
312
+
312
313
  begin
313
314
  load_file file
314
315
  rescue NameError => ne
@@ -317,7 +318,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
317
318
  end
318
319
  end
319
320
  Merb::Controller.send :include, Merb::GlobalHelpers
320
-
321
+
321
322
  load_classes_with_requirements(orphaned_classes)
322
323
  end
323
324
 
@@ -329,7 +330,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
329
330
  LOADED_CLASSES[file] = ObjectSpace.classes - klasses
330
331
  MTIMES[file] = File.mtime(file)
331
332
  end
332
-
333
+
333
334
  # "Better loading" of classes. If a class fails to load due to a NameError
334
335
  # it will be added to the failed_classs stack.
335
336
  #
@@ -337,29 +338,36 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
337
338
  # klasses<Array[Class]>:: Classes to load.
338
339
  def load_classes_with_requirements(klasses)
339
340
  klasses.uniq!
340
-
341
+
341
342
  while klasses.size > 0
342
- # note size to make sure things are loading
343
+ # Note size to make sure things are loading
343
344
  size_at_start = klasses.size
344
-
345
- #list of failed classes
345
+
346
+ # List of failed classes
346
347
  failed_classes = []
347
-
348
+ # Map classes to exceptions
349
+ error_map = {}
350
+
348
351
  klasses.each do |klass|
349
352
  klasses.delete(klass)
350
353
  begin
351
354
  load_file klass
352
355
  rescue NameError => ne
356
+ error_map[klass] = ne
353
357
  failed_classes.push(klass)
354
358
  end
355
359
  end
356
-
357
- # keep list of classes unique
360
+
361
+ # Keep list of classes unique
358
362
  failed_classes.each { |k| klasses.push(k) unless klasses.include?(k) }
359
-
360
- #stop processing if nothing loads or if everything has loaded
363
+
364
+ # Stop processing if nothing loads or if everything has loaded
361
365
  if klasses.size == size_at_start && klasses.size != 0
362
- raise LoadError, "Could not load #{failed_classes.inspect}."
366
+ # Write all remaining failed classes and their exceptions to the log
367
+ error_map.only(*failed_classes).each do |klass, e|
368
+ Merb.logger.fatal! "Could not load #{klass}:\n\n#{e.message} - (#{e.class})\n\n#{(e.backtrace || []).join("\n")}"
369
+ end
370
+ raise LoadError, "Could not load #{failed_classes.inspect} (see log for details)."
363
371
  end
364
372
  break if(klasses.size == size_at_start || klasses.size == 0)
365
373
  end
@@ -373,7 +381,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
373
381
  klasses.each { |klass| remove_constant(klass) unless klass.to_s =~ /Router/ }
374
382
  end
375
383
  load_file file
376
- Merb.klass_hashes.each {|x| x.unprotect_keys!}
384
+ Merb.klass_hashes.each {|x| x.unprotect_keys!}
377
385
  end
378
386
 
379
387
  # ==== Parameters
@@ -387,10 +395,10 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
387
395
  until (superklass = superklass.superclass).nil?
388
396
  if superklass.respond_to?(:_subclasses_list)
389
397
  superklass.send(:_subclasses_list).delete(klass)
390
- superklass.send(:_subclasses_list).delete(klass.to_s)
398
+ superklass.send(:_subclasses_list).delete(klass.to_s)
391
399
  end
392
400
  end
393
-
401
+
394
402
  parts = const.to_s.split("::")
395
403
  base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::"))
396
404
  object = parts[-1].to_s
@@ -401,8 +409,9 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
401
409
  Merb.logger.debug("Failed to remove constant #{object} from #{base}")
402
410
  end
403
411
  end
412
+
404
413
  end
405
-
414
+
406
415
  end
407
416
 
408
417
  class Merb::BootLoader::Templates < Merb::BootLoader
@@ -420,18 +429,18 @@ class Merb::BootLoader::Templates < Merb::BootLoader
420
429
  def template_paths
421
430
  extension_glob = "{#{Merb::Template::EXTENSIONS.keys.join(',')}}"
422
431
 
423
- # This gets all templates set in the controllers template roots
432
+ # This gets all templates set in the controllers template roots
424
433
  # We separate the two maps because most of controllers will have
425
434
  # the same _template_root, so it's silly to be globbing the same
426
435
  # path over and over.
427
- template_paths = Merb::AbstractController._abstract_subclasses.map do |klass|
436
+ template_paths = Merb::AbstractController._abstract_subclasses.map do |klass|
428
437
  Object.full_const_get(klass)._template_root
429
438
  end.uniq.compact.map {|path| Dir["#{path}/**/*.#{extension_glob}"] }
430
-
439
+
431
440
  # This gets the templates that might be created outside controllers
432
441
  # template roots. eg app/views/shared/*
433
442
  template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view)
434
-
443
+
435
444
  template_paths.flatten.compact.uniq
436
445
  end
437
446
  end
@@ -457,7 +466,7 @@ class Merb::BootLoader::MimeTypes < Merb::BootLoader
457
466
  Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html])
458
467
  Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8")
459
468
  Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript])
460
- Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json])
469
+ Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json])
461
470
  end
462
471
  end
463
472
 
@@ -481,13 +490,13 @@ class Merb::BootLoader::MixinSessionContainer < Merb::BootLoader
481
490
  Merb.register_session_type('memcache',
482
491
  Merb.framework_root / "merb-core" / "dispatch" / "session" / "memcached",
483
492
  "Using 'memcached' sessions")
484
-
493
+
485
494
  Merb.register_session_type('cookie', # Last session type becomes the default
486
495
  Merb.framework_root / "merb-core" / "dispatch" / "session" / "cookie",
487
496
  "Using 'share-nothing' cookie sessions (4kb limit per client)")
488
497
 
489
498
 
490
-
499
+
491
500
  Merb::Controller.class_eval do
492
501
  session_store = Merb::Config[:session_store].to_s
493
502
  if ["", "false", "none"].include?(session_store)
@@ -510,8 +519,8 @@ class Merb::BootLoader::MixinSessionContainer < Merb::BootLoader
510
519
  Merb.logger.warn "(plugin not installed?)"
511
520
  end
512
521
  end
513
-
514
- Merb.logger.flush
522
+
523
+ Merb.logger.flush
515
524
  end
516
525
 
517
526
  # Sets the controller session ID key if it has been set in config.
@@ -520,14 +529,14 @@ class Merb::BootLoader::MixinSessionContainer < Merb::BootLoader
520
529
  Merb::Controller._session_id_key = Merb::Config[:session_id_key]
521
530
  end
522
531
  end
523
-
532
+
524
533
  # Attempts to set the session secret key. This method will exit if the key
525
534
  # does not exist or is shorter than 16 charaters.
526
535
  def self.check_for_secret_key
527
536
  unless Merb::Config[:session_secret_key] && (Merb::Config[:session_secret_key].length >= 16)
528
537
  Merb.logger.warn("You must specify a session_secret_key in your merb.yml, and it must be at least 16 characters\nbailing out...")
529
538
  exit!
530
- end
539
+ end
531
540
  Merb::Controller._session_secret_key = Merb::Config[:session_secret_key]
532
541
  end
533
542
  end
@@ -541,15 +550,19 @@ class Merb::BootLoader::ChooseAdapter < Merb::BootLoader
541
550
  end
542
551
 
543
552
  class Merb::BootLoader::RackUpApplication < Merb::BootLoader
544
-
545
- # Setup the Merb Rack App or read a rack.rb config file located at the
546
- # Merb.root or Merb.root / config / rack.rb with the same syntax as the
547
- # rackup tool that comes with rack. Automatically evals the rack.rb file in
553
+ # Setup the Merb Rack App or read a rackup file located at
554
+ # Merb::Config[:rackup] with the same syntax as the
555
+ # rackup tool that comes with rack. Automatically evals the file in
548
556
  # the context of a Rack::Builder.new { } block. Allows for mounting
549
557
  # additional apps or middleware.
550
558
  def self.run
551
559
  if File.exists?(Merb.dir_for(:config) / "rack.rb")
552
- Merb::Config[:app] = eval("::Rack::Builder.new {( #{IO.read(Merb.dir_for(:config) / 'rack.rb')}\n )}.to_app", TOPLEVEL_BINDING, __FILE__, __LINE__)
560
+ Merb::Config[:rackup] ||= Merb.dir_for(:config) / "rack.rb"
561
+ end
562
+
563
+ if Merb::Config[:rackup]
564
+ rackup_code = File.read(Merb::Config[:rackup])
565
+ Merb::Config[:app] = eval("::Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, Merb::Config[:rackup])
553
566
  else
554
567
  Merb::Config[:app] = ::Merb::Rack::Application.new
555
568
  end
@@ -580,13 +593,13 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
580
593
  next unless glob
581
594
  paths << Dir[path / glob]
582
595
  end
583
-
596
+
584
597
  paths << Merb.dir_for(:application) if Merb.dir_for(:application) && File.file?(Merb.dir_for(:application))
585
598
 
586
599
  paths.flatten.each do |file|
587
600
  next if Merb::BootLoader::LoadClasses::MTIMES[file] && Merb::BootLoader::LoadClasses::MTIMES[file] == File.mtime(file)
588
601
  Merb::BootLoader::LoadClasses.reload(file)
589
- end
602
+ end
590
603
  end
591
604
  end
592
605
 
@@ -598,4 +611,4 @@ class Merb::BootLoader::ReloadTemplates < Merb::BootLoader
598
611
  Merb::Config[:reload_templates] = (Merb.environment == "development")
599
612
  end
600
613
  end
601
- end
614
+ end