wycats-merb-core 0.9.8 → 0.9.9
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/CHANGELOG +136 -2
- data/CONTRIBUTORS +6 -0
- data/PUBLIC_CHANGELOG +15 -0
- data/Rakefile +12 -14
- data/lib/merb-core.rb +82 -43
- data/lib/merb-core/bootloader.rb +268 -60
- data/lib/merb-core/config.rb +119 -34
- data/lib/merb-core/controller/abstract_controller.rb +58 -18
- data/lib/merb-core/controller/exceptions.rb +2 -15
- data/lib/merb-core/controller/merb_controller.rb +28 -1
- data/lib/merb-core/controller/mime.rb +4 -0
- data/lib/merb-core/controller/mixins/controller.rb +14 -17
- data/lib/merb-core/controller/mixins/render.rb +23 -28
- data/lib/merb-core/controller/mixins/responder.rb +0 -1
- data/lib/merb-core/controller/template.rb +44 -20
- data/lib/merb-core/core_ext/kernel.rb +8 -3
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +1 -1
- data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +3 -1
- data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +71 -67
- data/lib/merb-core/dispatch/default_exception/views/index.html.erb +6 -2
- data/lib/merb-core/dispatch/dispatcher.rb +5 -9
- data/lib/merb-core/dispatch/request.rb +46 -57
- data/lib/merb-core/dispatch/router.rb +83 -6
- data/lib/merb-core/dispatch/router/behavior.rb +87 -27
- data/lib/merb-core/dispatch/router/resources.rb +281 -167
- data/lib/merb-core/dispatch/router/route.rb +141 -27
- data/lib/merb-core/logger.rb +213 -202
- data/lib/merb-core/rack.rb +3 -1
- data/lib/merb-core/rack/adapter.rb +7 -4
- data/lib/merb-core/rack/adapter/ebb.rb +12 -13
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -15
- data/lib/merb-core/rack/adapter/irb.rb +3 -2
- data/lib/merb-core/rack/adapter/mongrel.rb +22 -15
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +4 -16
- data/lib/merb-core/rack/adapter/thin.rb +21 -22
- data/lib/merb-core/rack/adapter/thin_turbo.rb +4 -11
- data/lib/merb-core/rack/adapter/webrick.rb +54 -18
- data/lib/merb-core/rack/handler/mongrel.rb +12 -13
- data/lib/merb-core/rack/middleware/csrf.rb +1 -1
- data/lib/merb-core/server.rb +135 -98
- data/lib/merb-core/tasks/gem_management.rb +50 -12
- data/lib/merb-core/tasks/merb.rb +1 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +9 -38
- data/lib/merb-core/tasks/stats.rake +2 -2
- data/lib/merb-core/test.rb +9 -3
- data/lib/merb-core/test/helpers.rb +1 -0
- data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -2
- data/lib/merb-core/test/helpers/request_helper.rb +40 -372
- data/lib/merb-core/test/helpers/route_helper.rb +15 -7
- data/lib/merb-core/test/matchers.rb +1 -0
- data/lib/merb-core/test/matchers/controller_matchers.rb +4 -247
- data/lib/merb-core/test/matchers/view_matchers.rb +22 -4
- data/lib/merb-core/test/run_specs.rb +117 -25
- data/lib/merb-core/version.rb +1 -1
- metadata +1 -1
- data/lib/merb-core/vendor/facets.rb +0 -2
- data/lib/merb-core/vendor/facets/dictionary.rb +0 -433
- data/lib/merb-core/vendor/facets/inflect.rb +0 -342
data/lib/merb-core/bootloader.rb
CHANGED
@@ -6,7 +6,8 @@ module Merb
|
|
6
6
|
#---
|
7
7
|
# @semipublic
|
8
8
|
cattr_accessor :subclasses, :after_load_callbacks, :before_load_callbacks, :finished
|
9
|
-
self.subclasses, self.after_load_callbacks,
|
9
|
+
self.subclasses, self.after_load_callbacks,
|
10
|
+
self.before_load_callbacks, self.finished = [], [], [], []
|
10
11
|
|
11
12
|
class << self
|
12
13
|
|
@@ -74,7 +75,7 @@ module Merb
|
|
74
75
|
end
|
75
76
|
self.subclasses = subklasses
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
# Determines whether or not a specific bootloader has finished yet.
|
79
80
|
#
|
80
81
|
# ==== Parameters
|
@@ -144,13 +145,23 @@ class Merb::BootLoader::Logger < Merb::BootLoader
|
|
144
145
|
|
145
146
|
# Sets Merb.logger to a new logger created based on the config settings.
|
146
147
|
def self.run
|
147
|
-
Merb
|
148
|
+
Merb::Config[:log_level] ||= begin
|
149
|
+
if Merb.environment == "production"
|
150
|
+
Merb::Logger::Levels[:warn]
|
151
|
+
else
|
152
|
+
Merb::Logger::Levels[:debug]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
Merb::Config[:log_stream] = Merb.log_stream
|
157
|
+
|
148
158
|
print_warnings
|
149
159
|
end
|
150
|
-
|
160
|
+
|
151
161
|
def self.print_warnings
|
152
162
|
if Gem::Version.new(Gem::RubyGemsVersion) < Gem::Version.new("1.1")
|
153
|
-
Merb.
|
163
|
+
Merb.fatal! "Merb requires Rubygems 1.1 and later. " \
|
164
|
+
"Please upgrade RubyGems with gem update --system."
|
154
165
|
end
|
155
166
|
end
|
156
167
|
end
|
@@ -159,12 +170,12 @@ end
|
|
159
170
|
#
|
160
171
|
# Only run if daemonization or clustering options specified on start.
|
161
172
|
# Port is taken from Merb::Config and must be already set at this point.
|
162
|
-
class Merb::BootLoader::DropPidFile <
|
173
|
+
class Merb::BootLoader::DropPidFile < Merb::BootLoader
|
163
174
|
class << self
|
164
175
|
|
165
176
|
# Stores a PID file if Merb is running daemonized or clustered.
|
166
177
|
def run
|
167
|
-
Merb::Server.store_pid(
|
178
|
+
Merb::Server.store_pid("main") #if Merb::Config[:daemonize] || Merb::Config[:cluster]
|
168
179
|
end
|
169
180
|
end
|
170
181
|
end
|
@@ -257,6 +268,10 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
|
|
257
268
|
# haven't been loaded up until this point.
|
258
269
|
|
259
270
|
def self.run
|
271
|
+
set_encoding
|
272
|
+
# this is crucial: load init file with all the preferences
|
273
|
+
# then environment init file, then start enabling specific
|
274
|
+
# components, load dependencies and update logger.
|
260
275
|
load_initfile
|
261
276
|
load_env_config
|
262
277
|
enable_json_gem unless Merb::disabled?(:json)
|
@@ -269,14 +284,29 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
|
|
269
284
|
end
|
270
285
|
|
271
286
|
def self.enable_json_gem
|
287
|
+
gem "json"
|
272
288
|
require "json/ext"
|
273
289
|
rescue LoadError
|
290
|
+
gem "json_pure"
|
274
291
|
require "json/pure"
|
275
292
|
end
|
276
293
|
|
277
294
|
def self.update_logger
|
278
|
-
|
279
|
-
|
295
|
+
Merb.logger = nil
|
296
|
+
|
297
|
+
# If log file is given, use it and not log stream we have.
|
298
|
+
if Merb::Config[:log_file]
|
299
|
+
raise "log file should be a string, got: #{Merb::Config[:log_file].inspect}" unless Merb::Config[:log_file].is_a?(String)
|
300
|
+
STDOUT.puts "Logging to file at #{Merb::Config[:log_file]}" unless Merb.testing?
|
301
|
+
Merb::Config[:log_stream] = File.open(Merb::Config[:log_file], "w+")
|
302
|
+
# but if it's not given, fallback to log stream or stdout
|
303
|
+
else
|
304
|
+
Merb::Config[:log_stream] ||= STDOUT
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def self.set_encoding
|
309
|
+
$KCODE = 'UTF8' if $KCODE == 'NONE' || $KCODE.blank?
|
280
310
|
end
|
281
311
|
|
282
312
|
private
|
@@ -293,7 +323,10 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
|
|
293
323
|
|
294
324
|
# Loads the environment configuration file, if any
|
295
325
|
def self.load_env_config
|
296
|
-
|
326
|
+
if env_config?
|
327
|
+
STDOUT.puts "Loading #{env_config}" unless Merb.testing?
|
328
|
+
load(env_config)
|
329
|
+
end
|
297
330
|
end
|
298
331
|
|
299
332
|
# Determines the init file to use, if any.
|
@@ -308,9 +341,11 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
|
|
308
341
|
|
309
342
|
# Loads the init file, should one exist
|
310
343
|
def self.load_initfile
|
311
|
-
|
344
|
+
if File.exists?(initfile)
|
345
|
+
STDOUT.puts "Loading init file from #{initfile}" unless Merb.testing?
|
346
|
+
load(initfile)
|
347
|
+
end
|
312
348
|
end
|
313
|
-
|
314
349
|
end
|
315
350
|
|
316
351
|
class Merb::BootLoader::MixinSession < Merb::BootLoader
|
@@ -320,7 +355,7 @@ class Merb::BootLoader::MixinSession < Merb::BootLoader
|
|
320
355
|
# plugin session stores for example - these need to be loaded in a
|
321
356
|
# before_app_loads block or a BootLoader that runs after MixinSession.
|
322
357
|
#
|
323
|
-
# Note: access to Merb::Config is needed, so it needs to run after
|
358
|
+
# Note: access to Merb::Config is needed, so it needs to run after
|
324
359
|
# Merb::BootLoader::Dependencies is done.
|
325
360
|
def self.run
|
326
361
|
require 'merb-core/dispatch/session'
|
@@ -356,32 +391,174 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
|
|
356
391
|
# Load all classes from Merb's native load paths.
|
357
392
|
def run
|
358
393
|
# Add models, controllers, helpers and lib to the load path
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
394
|
+
unless @ran
|
395
|
+
$LOAD_PATH.unshift Merb.dir_for(:model)
|
396
|
+
$LOAD_PATH.unshift Merb.dir_for(:controller)
|
397
|
+
$LOAD_PATH.unshift Merb.dir_for(:lib)
|
398
|
+
$LOAD_PATH.unshift Merb.dir_for(:helper)
|
399
|
+
end
|
400
|
+
|
401
|
+
@ran = true
|
402
|
+
$0 = "merb#{" : " + Merb::Config[:name] if Merb::Config[:name]} : master"
|
403
|
+
|
404
|
+
if Merb::Config[:fork_for_class_load] && !Merb.testing?
|
405
|
+
start_transaction
|
406
|
+
else
|
407
|
+
Merb.trap('INT') do
|
408
|
+
Merb.logger.warn! "Killing children"
|
409
|
+
kill_children
|
410
|
+
end
|
411
|
+
end
|
363
412
|
|
364
413
|
# Load application file if it exists - for flat applications
|
365
414
|
load_file Merb.dir_for(:application) if File.file?(Merb.dir_for(:application))
|
366
|
-
|
415
|
+
|
367
416
|
# Load classes and their requirements
|
368
417
|
Merb.load_paths.each do |component, path|
|
369
|
-
next
|
418
|
+
next if path.last.blank? || component == :application || component == :router
|
370
419
|
load_classes(path.first / path.last)
|
371
420
|
end
|
372
421
|
|
373
422
|
Merb::Controller.send :include, Merb::GlobalHelpers
|
374
423
|
end
|
375
|
-
|
424
|
+
|
425
|
+
# Wait for any children to exit, remove the "main" PID, and
|
426
|
+
# exit.
|
427
|
+
def exit_gracefully
|
428
|
+
Process.waitall
|
429
|
+
Merb::Server.remove_pid("main")
|
430
|
+
exit
|
431
|
+
end
|
432
|
+
|
433
|
+
# If using fork-based code reloading, set up the BEGIN
|
434
|
+
# point and set up any signals in the parent and child.
|
435
|
+
def start_transaction
|
436
|
+
Merb.logger.warn! "Parent pid: #{Process.pid}"
|
437
|
+
reader, writer = nil, nil
|
438
|
+
|
439
|
+
if GC.respond_to?(:copy_on_write_friendly=)
|
440
|
+
GC.copy_on_write_friendly = true
|
441
|
+
end
|
442
|
+
|
443
|
+
loop do
|
444
|
+
reader, @writer = IO.pipe
|
445
|
+
pid = Kernel.fork
|
446
|
+
|
447
|
+
# pid means we're in the parent; only stay in the loop in that case
|
448
|
+
break unless pid
|
449
|
+
@writer.close
|
450
|
+
|
451
|
+
Merb::Server.store_pid("main")
|
452
|
+
|
453
|
+
if Merb::Config[:console_trap]
|
454
|
+
Merb.trap("INT") {}
|
455
|
+
else
|
456
|
+
Merb.trap("INT") do
|
457
|
+
Merb.logger.warn! "Killing children"
|
458
|
+
begin
|
459
|
+
Process.kill("ABRT", pid)
|
460
|
+
rescue SystemCallError
|
461
|
+
end
|
462
|
+
exit_gracefully
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
Merb.trap("HUP") do
|
467
|
+
Merb.logger.warn! "Doing a fast deploy\n"
|
468
|
+
Process.kill("HUP", pid)
|
469
|
+
end
|
470
|
+
|
471
|
+
reader_ary = [reader]
|
472
|
+
loop do
|
473
|
+
if exit_status = Process.wait2(pid, Process::WNOHANG)
|
474
|
+
exit_status[1] == 128 ? break : exit
|
475
|
+
end
|
476
|
+
if select(reader_ary, nil, nil, 0.25)
|
477
|
+
begin
|
478
|
+
next if reader.eof?
|
479
|
+
msg = reader.readline
|
480
|
+
if msg =~ /128/
|
481
|
+
break
|
482
|
+
else
|
483
|
+
exit_gracefully
|
484
|
+
end
|
485
|
+
rescue SystemCallError
|
486
|
+
exit_gracefully
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
reader.close
|
493
|
+
|
494
|
+
# add traps to the child
|
495
|
+
if Merb::Config[:console_trap]
|
496
|
+
Merb::Server.add_irb_trap
|
497
|
+
at_exit { kill_children }
|
498
|
+
else
|
499
|
+
Merb.trap('INT') {}
|
500
|
+
Merb.trap('ABRT') { kill_children }
|
501
|
+
Merb.trap('HUP') { kill_children(128) }
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
# Kill any children of the spawner process and exit with
|
506
|
+
# an appropriate status code.
|
507
|
+
#
|
508
|
+
# Note that exiting the spawner process with a status code
|
509
|
+
# of 128 when a master process exists will cause the
|
510
|
+
# spawner process to be recreated, and the app code reloaded.
|
511
|
+
#
|
512
|
+
# @param status<Integer> The status code to exit with
|
513
|
+
def kill_children(status = 0)
|
514
|
+
Merb.exiting = true unless status == 128
|
515
|
+
|
516
|
+
begin
|
517
|
+
@writer.puts(status.to_s) if @writer
|
518
|
+
rescue SystemCallError
|
519
|
+
end
|
520
|
+
|
521
|
+
threads = []
|
522
|
+
|
523
|
+
($CHILDREN || []).each do |p|
|
524
|
+
threads << Thread.new do
|
525
|
+
begin
|
526
|
+
Process.kill("ABRT", p)
|
527
|
+
Process.wait2(p)
|
528
|
+
rescue SystemCallError
|
529
|
+
end
|
530
|
+
end
|
531
|
+
end
|
532
|
+
threads.each {|t| t.join }
|
533
|
+
exit(status)
|
534
|
+
end
|
535
|
+
|
376
536
|
# ==== Parameters
|
377
537
|
# file<String>:: The file to load.
|
378
538
|
def load_file(file)
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
539
|
+
# Don't do this expensive operation unless we need to
|
540
|
+
unless Merb::Config[:fork_for_class_load]
|
541
|
+
klasses = ObjectSpace.classes.dup
|
542
|
+
end
|
543
|
+
|
544
|
+
# Ignore the file for syntax errors. The next time
|
545
|
+
# the file is changed, it'll be reloaded again
|
546
|
+
begin
|
547
|
+
load file
|
548
|
+
rescue SyntaxError
|
549
|
+
return
|
550
|
+
ensure
|
551
|
+
if Merb::Config[:reload_classes]
|
552
|
+
MTIMES[file] = File.mtime(file)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
# Don't do this expensive operation unless we need to
|
557
|
+
unless Merb::Config[:fork_for_class_load]
|
558
|
+
LOADED_CLASSES[file] = ObjectSpace.classes - klasses
|
559
|
+
end
|
383
560
|
end
|
384
|
-
|
561
|
+
|
385
562
|
# Load classes from given paths - using path/glob pattern.
|
386
563
|
#
|
387
564
|
# *paths<Array>::
|
@@ -403,22 +580,18 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
|
|
403
580
|
# ==== Parameters
|
404
581
|
# file<String>:: The file to reload.
|
405
582
|
def reload(file)
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
def reload_router!
|
411
|
-
if File.file?(router_file = Merb.dir_for(:router) / Merb.glob_for(:router))
|
412
|
-
Merb::Router.reset!
|
413
|
-
reload router_file
|
583
|
+
if Merb::Config[:fork_for_class_load]
|
584
|
+
kill_children(128)
|
585
|
+
else
|
586
|
+
remove_classes_in_file(file) { |f| load_file(f) }
|
414
587
|
end
|
415
588
|
end
|
416
|
-
|
589
|
+
|
417
590
|
# ==== Parameters
|
418
591
|
# file<String>:: The file to remove classes for.
|
419
592
|
# &block:: A block to call with the file that has been removed.
|
420
593
|
def remove_classes_in_file(file, &block)
|
421
|
-
Merb.klass_hashes.each {|x| x.protect_keys!}
|
594
|
+
Merb.klass_hashes.each { |x| x.protect_keys! }
|
422
595
|
if klasses = LOADED_CLASSES.delete(file)
|
423
596
|
klasses.each { |klass| remove_constant(klass) unless klass.to_s =~ /Router/ }
|
424
597
|
end
|
@@ -451,7 +624,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
|
|
451
624
|
Merb.logger.debug("Failed to remove constant #{object} from #{base}")
|
452
625
|
end
|
453
626
|
end
|
454
|
-
|
627
|
+
|
455
628
|
private
|
456
629
|
|
457
630
|
# "Better loading" of classes. If a class fails to load due to a NameError
|
@@ -489,10 +662,11 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
|
|
489
662
|
if klasses.size == size_at_start && klasses.size != 0
|
490
663
|
# Write all remaining failed classes and their exceptions to the log
|
491
664
|
messages = error_map.only(*failed_classes).map do |klass, e|
|
492
|
-
["Could not load #{klass}:\n\n#{e.message} - (#{e.class})",
|
665
|
+
["Could not load #{klass}:\n\n#{e.message} - (#{e.class})",
|
666
|
+
"#{(e.backtrace || []).join("\n")}"]
|
493
667
|
end
|
494
668
|
messages.each { |msg, trace| Merb.logger.fatal!("#{msg}\n\n#{trace}") }
|
495
|
-
|
669
|
+
Merb.fatal! "#{failed_classes.join(", ")} failed to load."
|
496
670
|
end
|
497
671
|
break if(klasses.size == size_at_start || klasses.size == 0)
|
498
672
|
end
|
@@ -502,6 +676,31 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
|
|
502
676
|
|
503
677
|
end
|
504
678
|
|
679
|
+
class Merb::BootLoader::Router < Merb::BootLoader
|
680
|
+
class << self
|
681
|
+
|
682
|
+
def run
|
683
|
+
Merb::BootLoader::LoadClasses.load_file(router_file) if router_file
|
684
|
+
end
|
685
|
+
|
686
|
+
def reload!
|
687
|
+
if router_file
|
688
|
+
Merb::Router.reset!
|
689
|
+
Merb::BootLoader::LoadClasses.reload(router_file)
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
def router_file
|
694
|
+
@router_file ||= begin
|
695
|
+
if File.file?(router = Merb.dir_for(:router) / Merb.glob_for(:router))
|
696
|
+
router
|
697
|
+
end
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
505
704
|
class Merb::BootLoader::Templates < Merb::BootLoader
|
506
705
|
class << self
|
507
706
|
|
@@ -532,7 +731,9 @@ class Merb::BootLoader::Templates < Merb::BootLoader
|
|
532
731
|
# template roots. eg app/views/shared/*
|
533
732
|
template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view)
|
534
733
|
|
535
|
-
|
734
|
+
# This ignores templates for partials, which need to be compiled at use time to generate
|
735
|
+
# a preamble that assigns local variables
|
736
|
+
template_paths.flatten.compact.uniq.grep(%r{^.*/[^_][^/]*$})
|
536
737
|
end
|
537
738
|
end
|
538
739
|
end
|
@@ -562,13 +763,13 @@ class Merb::BootLoader::MimeTypes < Merb::BootLoader
|
|
562
763
|
end
|
563
764
|
|
564
765
|
class Merb::BootLoader::Cookies < Merb::BootLoader
|
565
|
-
|
766
|
+
|
566
767
|
def self.run
|
567
768
|
require 'merb-core/dispatch/cookies'
|
568
769
|
Merb::Controller.send(:include, Merb::CookiesMixin)
|
569
770
|
Merb::Request.send(:include, Merb::CookiesMixin::RequestMixin)
|
570
771
|
end
|
571
|
-
|
772
|
+
|
572
773
|
end
|
573
774
|
|
574
775
|
class Merb::BootLoader::SetupSession < Merb::BootLoader
|
@@ -581,22 +782,22 @@ class Merb::BootLoader::SetupSession < Merb::BootLoader
|
|
581
782
|
base_name = File.basename(file, ".rb")
|
582
783
|
require file unless base_name == "container" || base_name == "store_container"
|
583
784
|
end
|
584
|
-
|
785
|
+
|
585
786
|
# Set some defaults.
|
586
787
|
Merb::Config[:session_id_key] ||= "_session_id"
|
587
|
-
|
788
|
+
|
588
789
|
# List of all session_stores from :session_stores and :session_store config options.
|
589
790
|
config_stores = Merb::Config.session_stores
|
590
|
-
|
791
|
+
|
591
792
|
# Register all configured session stores - any loaded session container class
|
592
793
|
# (subclassed from Merb::SessionContainer) will be available for registration.
|
593
794
|
Merb::SessionContainer.subclasses.each do |class_name|
|
594
|
-
if(store = Object.full_const_get(class_name)) &&
|
795
|
+
if(store = Object.full_const_get(class_name)) &&
|
595
796
|
config_stores.include?(store.session_store_type)
|
596
797
|
Merb::Request.register_session_type(store.session_store_type, class_name)
|
597
798
|
end
|
598
799
|
end
|
599
|
-
|
800
|
+
|
600
801
|
# Mixin the Merb::Session module to add app-level functionality to sessions
|
601
802
|
Merb::SessionContainer.send(:include, Merb::Session)
|
602
803
|
end
|
@@ -669,7 +870,7 @@ class Merb::BootLoader::RackUpApplication < Merb::BootLoader
|
|
669
870
|
run Merb::Rack::Application.new
|
670
871
|
}.to_app
|
671
872
|
end
|
672
|
-
|
873
|
+
|
673
874
|
end
|
674
875
|
end
|
675
876
|
|
@@ -681,7 +882,7 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
|
|
681
882
|
Thread.new do
|
682
883
|
loop do
|
683
884
|
sleep( seconds )
|
684
|
-
|
885
|
+
yield
|
685
886
|
end
|
686
887
|
Thread.exit
|
687
888
|
end
|
@@ -692,14 +893,6 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
|
|
692
893
|
def self.run
|
693
894
|
return unless Merb::Config[:reload_classes]
|
694
895
|
|
695
|
-
TimedExecutor.every(Merb::Config[:reload_time] || 0.5) do
|
696
|
-
reload
|
697
|
-
end
|
698
|
-
|
699
|
-
end
|
700
|
-
|
701
|
-
# Reloads all files.
|
702
|
-
def self.reload
|
703
896
|
paths = []
|
704
897
|
Merb.load_paths.each do |path_name, file_info|
|
705
898
|
path, glob = file_info
|
@@ -707,11 +900,26 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
|
|
707
900
|
paths << Dir[path / glob]
|
708
901
|
end
|
709
902
|
|
710
|
-
|
903
|
+
if Merb.dir_for(:application) && File.file?(Merb.dir_for(:application))
|
904
|
+
paths << Merb.dir_for(:application)
|
905
|
+
end
|
906
|
+
|
907
|
+
paths.flatten!
|
908
|
+
|
909
|
+
TimedExecutor.every(Merb::Config[:reload_time] || 0.5) do
|
910
|
+
GC.start
|
911
|
+
reload(paths)
|
912
|
+
end
|
913
|
+
|
914
|
+
end
|
915
|
+
|
916
|
+
# Reloads all files.
|
917
|
+
def self.reload(paths)
|
918
|
+
paths.each do |file|
|
919
|
+
next if LoadClasses::MTIMES[file] &&
|
920
|
+
LoadClasses::MTIMES[file] == File.mtime(file)
|
711
921
|
|
712
|
-
|
713
|
-
next if Merb::BootLoader::LoadClasses::MTIMES[file] && Merb::BootLoader::LoadClasses::MTIMES[file] == File.mtime(file)
|
714
|
-
Merb::BootLoader::LoadClasses.reload(file)
|
922
|
+
LoadClasses.reload(file)
|
715
923
|
end
|
716
924
|
end
|
717
925
|
end
|