merb-core 0.9.9 → 0.9.10

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 CHANGED
@@ -19,7 +19,35 @@ Goals of this release:
19
19
  To familiarize yourself with how a merb-core application might look,
20
20
  use merb-gen (from merb-more) to generate a few apps:
21
21
 
22
- $ merb-gen app myapp # a "normal" merb app
23
- $ merb-gen app myapp --flat # a flattened app
24
- $ merb-gen app myapp --very-flat # a single-file app
22
+ $ merb-gen app myapp # merb stack app, assuming you are using DM and RSpec
25
23
 
24
+ The only option you can use with stack is --template_engine=(erb|haml).
25
+ Default is erb.
26
+
27
+ $ merb-gen core myapp # a "regular" app without any predefined dependencies
28
+
29
+ Options available:
30
+
31
+ --orm=datamapper
32
+ --orm=sequel
33
+ --orm=activerecord
34
+
35
+ Default is no ORM.
36
+
37
+ --testing_framework=rspec
38
+ --testing_framework=test_unit
39
+
40
+ Default is rspec.
41
+
42
+ --template_enging=erb
43
+ --template_enging=haml
44
+
45
+ Default is erb.
46
+
47
+ $ merb-gen flat myapp # a flattened app: one file and directory for views
48
+
49
+ Options are same as for "regular" app.
50
+
51
+ $ merb-gen very_flat myapp # a single-file app
52
+
53
+ Options are same as for "regular" app.
data/Rakefile CHANGED
@@ -58,7 +58,7 @@ spec = Gem::Specification.new do |s|
58
58
 
59
59
  # Dependencies
60
60
  s.add_dependency "extlib", ">= 0.9.8"
61
- s.add_dependency "erubis"
61
+ s.add_dependency "erubis", ">= 2.6.2"
62
62
  s.add_dependency "rake"
63
63
  s.add_dependency "json_pure"
64
64
  s.add_dependency "rspec"
@@ -336,7 +336,7 @@ def contributors(since_release = nil)
336
336
  git_log(since_release).split("\n").uniq.sort
337
337
  end
338
338
 
339
- PREVIOUS_RELEASE = '0.9.8'
339
+ PREVIOUS_RELEASE = '0.9.9'
340
340
  namespace :history do
341
341
  namespace :update do
342
342
  desc "updates contributors list"
data/lib/merb-core.rb CHANGED
@@ -23,6 +23,8 @@ require "pathname"
23
23
  require "extlib"
24
24
  require "extlib/dictionary"
25
25
 
26
+ Thread.abort_on_exception = true
27
+
26
28
  __DIR__ = File.dirname(__FILE__)
27
29
 
28
30
  $LOAD_PATH.unshift __DIR__ unless
@@ -275,7 +277,7 @@ module Merb
275
277
  #
276
278
  # @api public
277
279
  def root=(value)
278
- @root = value
280
+ @root = File.expand_path(value) + File::SEPARATOR
279
281
  end
280
282
 
281
283
  # ==== Parameters
@@ -710,7 +712,21 @@ module Merb
710
712
  #
711
713
  # @api public
712
714
  def trap(signal, &block)
713
- Kernel.trap(signal, &block) unless Merb.disabled?(:signals)
715
+ if Signal.list.include?(signal)
716
+ Kernel.trap(signal, &block) unless Merb.disabled?(:signals)
717
+ end
718
+ end
719
+
720
+ def forking_environment?
721
+ !on_windows? && !on_jruby?
722
+ end
723
+
724
+ def on_jruby?
725
+ RUBY_PLATFORM =~ Merb::Const::JAVA_PLATFORM_REGEXP
726
+ end
727
+
728
+ def on_windows?
729
+ RUBY_PLATFORM =~ Merb::Const::WIN_PLATFORM_REGEXP
714
730
  end
715
731
 
716
732
  end
@@ -5,9 +5,12 @@ module Merb
5
5
  # def self.subclasses
6
6
  #
7
7
  # @api plugin
8
- cattr_accessor :subclasses, :after_load_callbacks, :before_load_callbacks, :finished
8
+ cattr_accessor :subclasses, :after_load_callbacks, :before_load_callbacks,
9
+ :finished, :before_worker_shutdown_callbacks, :before_master_shutdown_callbacks
10
+
9
11
  self.subclasses, self.after_load_callbacks,
10
- self.before_load_callbacks, self.finished = [], [], [], []
12
+ self.before_load_callbacks, self.finished, self.before_master_shutdown_callbacks,
13
+ self.before_worker_shutdown_callbacks = [], [], [], [], [], []
11
14
 
12
15
  class << self
13
16
 
@@ -34,7 +37,7 @@ module Merb
34
37
  #
35
38
  # ==== Returns
36
39
  # nil
37
- #
40
+ #
38
41
  # @api plugin
39
42
  def after(klass)
40
43
  move_klass(klass, 1)
@@ -131,7 +134,7 @@ module Merb
131
134
  Merb.push_path(:config, Merb.root_path("config"), nil)
132
135
  Merb.push_path(:router, Merb.dir_for(:config), (Merb::Config[:router_file] || "router.rb"))
133
136
  Merb.push_path(:lib, Merb.root_path("lib"), nil)
134
- Merb.push_path(:merb, Merb.root_path("merb"))
137
+ Merb.push_path(:merb_session, Merb.root_path("merb" / "session"))
135
138
  Merb.push_path(:log, Merb.log_path, nil)
136
139
  Merb.push_path(:public, Merb.root_path("public"), nil)
137
140
  Merb.push_path(:stylesheet, Merb.dir_for(:public) / "stylesheets", nil)
@@ -163,6 +166,14 @@ module Merb
163
166
  def before_app_loads(&block)
164
167
  before_load_callbacks << block
165
168
  end
169
+
170
+ def before_master_shutdown(&block)
171
+ before_master_shutdown_callbacks << block
172
+ end
173
+
174
+ def before_worker_shutdown(&block)
175
+ before_worker_shutdown_callbacks << block
176
+ end
166
177
  end
167
178
 
168
179
  end
@@ -193,7 +204,7 @@ class Merb::BootLoader::Logger < Merb::BootLoader
193
204
  Merb::Config[:log_stream] = Merb.log_stream
194
205
 
195
206
  print_warnings
196
-
207
+
197
208
  nil
198
209
  end
199
210
 
@@ -234,10 +245,10 @@ end
234
245
  # Setup some useful defaults
235
246
  class Merb::BootLoader::Defaults < Merb::BootLoader
236
247
  # Sets up the defaults
237
- #
248
+ #
238
249
  # ==== Returns
239
250
  # nil
240
- #
251
+ #
241
252
  # @api plugin
242
253
  def self.run
243
254
  Merb::Request.http_method_overrides.concat([
@@ -352,7 +363,7 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
352
363
  # then environment init file, then start enabling specific
353
364
  # components, load dependencies and update logger.
354
365
  unless Merb::disabled?(:initfile)
355
- load_initfile
366
+ load_initfile
356
367
  load_env_config
357
368
  end
358
369
  enable_json_gem unless Merb::disabled?(:json)
@@ -362,7 +373,7 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
362
373
  end
363
374
 
364
375
  # Load each dependency that has been declared so far.
365
- #
376
+ #
366
377
  # ==== Returns
367
378
  # nil
368
379
  #
@@ -384,7 +395,7 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
384
395
  require "json/pure"
385
396
  end
386
397
 
387
- # Resets the logger and sets the log_stream to Merb::Config[:log_file]
398
+ # Resets the logger and sets the log_stream to Merb::Config[:log_file]
388
399
  # if one is specified, falling back to STDOUT.
389
400
  #
390
401
  # ==== Returns
@@ -403,7 +414,7 @@ class Merb::BootLoader::Dependencies < Merb::BootLoader
403
414
  else
404
415
  Merb::Config[:log_stream] ||= STDOUT
405
416
  end
406
-
417
+
407
418
  nil
408
419
  end
409
420
 
@@ -589,7 +600,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
589
600
  end
590
601
 
591
602
  Merb::Controller.send :include, Merb::GlobalHelpers
592
-
603
+
593
604
  nil
594
605
  end
595
606
 
@@ -607,14 +618,22 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
607
618
  Merb::Server.remove_pid("main")
608
619
  # terminate, workers remove their own pids
609
620
  # in on exit hook
621
+
622
+ Merb::BootLoader.before_master_shutdown_callbacks.each do |cb|
623
+ begin
624
+ cb.call
625
+ rescue Exception => e
626
+ Merb.logger.fatal "before_master_shutdown callback crashed: #{e.message}"
627
+ end
628
+ end
610
629
  exit
611
630
  end
612
631
 
613
- # Set up the BEGIN point for fork-based loading and sets up
632
+ # Set up the BEGIN point for fork-based loading and sets up
614
633
  # any signals in the parent and child. This is done by forking
615
634
  # the app. The child process continues on to run the app. The parent
616
635
  # process waits for the child process to finish and either forks again
617
- #
636
+ #
618
637
  #
619
638
  # ==== Returns
620
639
  # Parent Process:
@@ -668,7 +687,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
668
687
  reader_ary = [reader]
669
688
  loop do
670
689
  # wait for worker to exit and capture exit status
671
- #
690
+ #
672
691
  #
673
692
  # WNOHANG specifies that wait2 exists without waiting
674
693
  # if no worker processes are ready to be noticed.
@@ -705,13 +724,13 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
705
724
  Merb::Server.add_irb_trap
706
725
  at_exit { reap_workers }
707
726
  else
708
- Merb.trap('INT') {}
727
+ Merb.trap('INT') { Merb::BootLoader.before_worker_shutdown_callbacks.each { |cb| cb.call } }
709
728
  Merb.trap('ABRT') { reap_workers }
710
729
  Merb.trap('HUP') { reap_workers(128) }
711
730
  end
712
731
  end
713
732
 
714
- # Reap any workers of the spawner process and
733
+ # Reap any workers of the spawner process and
715
734
  # exit with an appropriate status code.
716
735
  #
717
736
  # Note that exiting the spawner process with a status code
@@ -728,6 +747,16 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
728
747
  # @param status<Integer> The status code to exit with
729
748
  # @param sig<String> The signal to send to workers
730
749
  def reap_workers(status = 0, sig = "ABRT")
750
+ Merb.logger.info "Executed all before worker shutdown callbacks..."
751
+ Merb::BootLoader.before_worker_shutdown_callbacks.each do |cb|
752
+ begin
753
+ cb.call
754
+ rescue Exception => e
755
+ Merb.logger.fatal "before worker shutdown callback crashed: #{e.message}"
756
+ end
757
+
758
+ end
759
+
731
760
  Merb.exiting = true unless status == 128
732
761
 
733
762
  begin
@@ -781,7 +810,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
781
810
  unless Merb::Config[:fork_for_class_load]
782
811
  LOADED_CLASSES[file] = ObjectSpace.classes - klasses
783
812
  end
784
-
813
+
785
814
  nil
786
815
  end
787
816
 
@@ -808,7 +837,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
808
837
  end
809
838
  load_classes_with_requirements(orphaned_classes)
810
839
  end
811
-
840
+
812
841
  # Reloads the classes in the specified file. If fork-based loading is used,
813
842
  # this causes the current processes to be killed and and all classes to be
814
843
  # reloaded. If class-based loading is not in use, the classes declared in that file
@@ -856,7 +885,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
856
885
  nil
857
886
  end
858
887
 
859
- # Removes the specified class.
888
+ # Removes the specified class.
860
889
  #
861
890
  # Additionally, removes the specified class from the subclass list of every superclass that
862
891
  # tracks it's subclasses in an array returned by _subclasses_list. Classes that wish to use this
@@ -943,7 +972,7 @@ class Merb::BootLoader::LoadClasses < Merb::BootLoader
943
972
  end
944
973
  break if(klasses.size == size_at_start || klasses.size == 0)
945
974
  end
946
-
975
+
947
976
  nil
948
977
  end
949
978
 
@@ -955,7 +984,7 @@ end
955
984
  # the router has everything it needs to run.
956
985
  class Merb::BootLoader::Router < Merb::BootLoader
957
986
  class << self
958
-
987
+
959
988
  # load the router file
960
989
  #
961
990
  # ==== Returns
@@ -964,7 +993,7 @@ class Merb::BootLoader::Router < Merb::BootLoader
964
993
  # @api plugin
965
994
  def run
966
995
  Merb::BootLoader::LoadClasses.load_file(router_file) if router_file
967
-
996
+
968
997
  nil
969
998
  end
970
999
 
@@ -1110,29 +1139,20 @@ class Merb::BootLoader::SetupSession < Merb::BootLoader
1110
1139
  end
1111
1140
 
1112
1141
  # Mixin the Merb::Session module to add app-level functionality to sessions
1142
+ overrides = (Merb::Session.instance_methods & Merb::SessionContainer.instance_methods)
1143
+ overrides.each do |m|
1144
+ Merb.logger.warn!("Warning: Merb::Session##{m} overrides existing " \
1145
+ "Merb::SessionContainer##{m}")
1146
+ end
1113
1147
  Merb::SessionContainer.send(:include, Merb::Session)
1114
1148
  nil
1115
1149
  end
1116
1150
 
1117
1151
  end
1118
1152
 
1119
- class Merb::BootLoader::AfterAppLoads < Merb::BootLoader
1120
-
1121
- # Call any after_app_loads hooks that were registered via after_app_loads in
1122
- # init.rb.
1123
- #
1124
- # ==== Returns
1125
- # nil
1126
- #
1127
- # @api plugin
1128
- def self.run
1129
- Merb::BootLoader.after_load_callbacks.each {|x| x.call }
1130
- nil
1131
- end
1132
- end
1133
-
1134
1153
  # In case someone's running a sparse app, the default exceptions require the
1135
- # Exceptions class.
1154
+ # Exceptions class. This must run prior to the AfterAppLoads BootLoader
1155
+ # So that plugins may have ensured access in the after_app_loads block
1136
1156
  class Merb::BootLoader::SetupStubClasses < Merb::BootLoader
1137
1157
  # Declares empty Application and Exception controllers.
1138
1158
  #
@@ -1147,7 +1167,7 @@ class Merb::BootLoader::SetupStubClasses < Merb::BootLoader
1147
1167
  abstract!
1148
1168
  end
1149
1169
 
1150
- class Exceptions < Application
1170
+ class Exceptions < Merb::Controller
1151
1171
  end
1152
1172
  RUBY
1153
1173
  end
@@ -1155,6 +1175,21 @@ class Merb::BootLoader::SetupStubClasses < Merb::BootLoader
1155
1175
  end
1156
1176
  end
1157
1177
 
1178
+ class Merb::BootLoader::AfterAppLoads < Merb::BootLoader
1179
+
1180
+ # Call any after_app_loads hooks that were registered via after_app_loads in
1181
+ # init.rb.
1182
+ #
1183
+ # ==== Returns
1184
+ # nil
1185
+ #
1186
+ # @api plugin
1187
+ def self.run
1188
+ Merb::BootLoader.after_load_callbacks.each {|x| x.call }
1189
+ nil
1190
+ end
1191
+ end
1192
+
1158
1193
  class Merb::BootLoader::ChooseAdapter < Merb::BootLoader
1159
1194
 
1160
1195
  # Choose the Rack adapter/server to use and set Merb.adapter.
@@ -1197,7 +1232,7 @@ class Merb::BootLoader::RackUpApplication < Merb::BootLoader
1197
1232
  run Merb::Rack::Application.new
1198
1233
  }.to_app
1199
1234
  end
1200
-
1235
+
1201
1236
  nil
1202
1237
  end
1203
1238
  end
@@ -1216,7 +1251,6 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
1216
1251
  #
1217
1252
  # @api private
1218
1253
  def self.every(seconds, &block)
1219
- Thread.abort_on_exception = true
1220
1254
  Thread.new do
1221
1255
  loop do
1222
1256
  sleep( seconds )
@@ -1227,10 +1261,10 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
1227
1261
  end
1228
1262
  end
1229
1263
 
1230
- # Set up the class reloader if class reloading is enabled. This checks periodically
1264
+ # Set up the class reloader if class reloading is enabled. This checks periodically
1231
1265
  # for modifications to files loaded by the LoadClasses BootLoader and reloads them
1232
1266
  # when they are modified.
1233
- #
1267
+ #
1234
1268
  # ==== Returns
1235
1269
  # nil
1236
1270
  #
@@ -1255,7 +1289,7 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
1255
1289
  GC.start
1256
1290
  reload(paths)
1257
1291
  end
1258
-
1292
+
1259
1293
  nil
1260
1294
  end
1261
1295
 
@@ -1272,7 +1306,7 @@ class Merb::BootLoader::ReloadClasses < Merb::BootLoader
1272
1306
 
1273
1307
  LoadClasses.reload(file)
1274
1308
  end
1275
-
1309
+
1276
1310
  nil
1277
1311
  end
1278
1312
  end
@@ -18,7 +18,7 @@ module Merb
18
18
  :port => "4000",
19
19
  :adapter => "runner",
20
20
  :reload_classes => true,
21
- :fork_for_class_load => !(RUBY_PLATFORM =~ /(:?mswin|mingw|java)/),
21
+ :fork_for_class_load => Merb.forking_environment?,
22
22
  :environment => "development",
23
23
  :merb_root => Dir.pwd,
24
24
  :use_mutex => true,
@@ -26,7 +26,7 @@ module Merb
26
26
  :log_auto_flush => false,
27
27
  :log_level => :info,
28
28
  :log_stream => STDOUT,
29
- :disabled_components => [],
29
+ :disabled_components => Merb.on_windows? ? [:signals] : [],
30
30
  :deferred_actions => [],
31
31
  :verbose => false,
32
32
  :name => "merb"