merb-core 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
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"