merb 0.4.2 → 0.5.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.
Files changed (108) hide show
  1. data/README +21 -14
  2. data/Rakefile +157 -108
  3. data/SVN_REVISION +1 -0
  4. data/app_generators/merb/templates/Rakefile +20 -4
  5. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +1 -1
  6. data/app_generators/merb/templates/config/boot.rb +1 -1
  7. data/app_generators/merb/templates/config/dependencies.rb +3 -3
  8. data/app_generators/merb/templates/config/merb.yml +5 -0
  9. data/app_generators/merb/templates/config/merb_init.rb +3 -3
  10. data/app_generators/merb/templates/script/destroy +3 -0
  11. data/app_generators/merb/templates/script/generate +1 -1
  12. data/app_generators/merb/templates/spec/spec_helper.rb +2 -2
  13. data/app_generators/merb/templates/test/test_helper.rb +1 -1
  14. data/app_generators/merb_plugin/merb_plugin_generator.rb +4 -0
  15. data/bin/merb +1 -3
  16. data/lib/merb.rb +144 -76
  17. data/lib/merb/abstract_controller.rb +6 -5
  18. data/lib/merb/assets.rb +119 -0
  19. data/lib/merb/boot_loader.rb +217 -0
  20. data/lib/merb/caching.rb +1 -1
  21. data/lib/merb/caching/action_cache.rb +1 -1
  22. data/lib/merb/caching/fragment_cache.rb +1 -1
  23. data/lib/merb/caching/store/file_cache.rb +1 -1
  24. data/lib/merb/config.rb +290 -0
  25. data/lib/merb/controller.rb +5 -5
  26. data/lib/merb/core_ext/get_args.rb +1 -0
  27. data/lib/merb/core_ext/hash.rb +182 -169
  28. data/lib/merb/core_ext/kernel.rb +57 -26
  29. data/lib/merb/dispatcher.rb +6 -6
  30. data/lib/merb/drb_server.rb +1 -1
  31. data/lib/merb/generators/merb_generator_helpers.rb +7 -6
  32. data/lib/merb/logger.rb +1 -1
  33. data/lib/merb/mail_controller.rb +3 -4
  34. data/lib/merb/mailer.rb +2 -2
  35. data/lib/merb/mixins/basic_authentication.rb +2 -2
  36. data/lib/merb/mixins/controller.rb +1 -1
  37. data/lib/merb/mixins/general_controller.rb +13 -20
  38. data/lib/merb/mixins/inline_partial.rb +32 -0
  39. data/lib/merb/mixins/render.rb +3 -3
  40. data/lib/merb/mixins/responder.rb +1 -1
  41. data/lib/merb/mixins/view_context.rb +159 -33
  42. data/lib/merb/mongrel_handler.rb +9 -9
  43. data/lib/merb/plugins.rb +1 -1
  44. data/lib/merb/request.rb +25 -1
  45. data/lib/merb/router.rb +264 -226
  46. data/lib/merb/server.rb +66 -560
  47. data/lib/merb/session/cookie_store.rb +14 -13
  48. data/lib/merb/session/mem_cache_session.rb +20 -10
  49. data/lib/merb/session/memory_session.rb +21 -11
  50. data/lib/merb/template.rb +2 -2
  51. data/lib/merb/template/erubis.rb +3 -33
  52. data/lib/merb/template/haml.rb +8 -3
  53. data/lib/merb/test/fake_request.rb +8 -3
  54. data/lib/merb/test/helper.rb +66 -22
  55. data/lib/merb/test/rspec.rb +9 -155
  56. data/lib/merb/test/rspec_matchers/controller_matchers.rb +117 -0
  57. data/lib/merb/test/rspec_matchers/markup_matchers.rb +98 -0
  58. data/lib/merb/upload_handler.rb +2 -1
  59. data/lib/merb/version.rb +38 -3
  60. data/lib/merb/view_context.rb +1 -2
  61. data/lib/tasks/merb.rake +11 -11
  62. data/merb_generators/part_controller/USAGE +5 -0
  63. data/merb_generators/part_controller/part_controller_generator.rb +27 -0
  64. data/merb_generators/part_controller/templates/controller.rb +8 -0
  65. data/merb_generators/part_controller/templates/helper.rb +5 -0
  66. data/merb_generators/part_controller/templates/index.html.erb +3 -0
  67. data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +1 -1
  68. data/script/destroy +14 -0
  69. data/script/generate +14 -0
  70. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +9 -1
  71. data/spec/fixtures/controllers/render_spec_controllers.rb +5 -5
  72. data/spec/fixtures/models/router_spec_models.rb +10 -0
  73. data/spec/merb/abstract_controller_spec.rb +2 -2
  74. data/spec/merb/assets_spec.rb +207 -0
  75. data/spec/merb/caching_spec.rb +2 -2
  76. data/spec/merb/controller_spec.rb +7 -2
  77. data/spec/merb/cookie_store_spec.rb +1 -1
  78. data/spec/merb/core_ext/class_spec.rb +97 -0
  79. data/spec/merb/core_ext/enumerable_spec.rb +27 -0
  80. data/spec/merb/core_ext/hash_spec.rb +251 -0
  81. data/spec/merb/core_ext/inflector_spec.rb +34 -0
  82. data/spec/merb/core_ext/kernel_spec.rb +25 -0
  83. data/spec/merb/core_ext/numeric_spec.rb +26 -0
  84. data/spec/merb/core_ext/object_spec.rb +47 -0
  85. data/spec/merb/core_ext/string_spec.rb +22 -0
  86. data/spec/merb/core_ext/symbol_spec.rb +7 -0
  87. data/spec/merb/dependency_spec.rb +22 -0
  88. data/spec/merb/dispatch_spec.rb +23 -12
  89. data/spec/merb/fake_request_spec.rb +8 -0
  90. data/spec/merb/generator_spec.rb +140 -21
  91. data/spec/merb/handler_spec.rb +5 -5
  92. data/spec/merb/mail_controller_spec.rb +3 -3
  93. data/spec/merb/render_spec.rb +1 -1
  94. data/spec/merb/responder_spec.rb +3 -3
  95. data/spec/merb/router_spec.rb +260 -191
  96. data/spec/merb/server_spec.rb +5 -5
  97. data/spec/merb/upload_handler_spec.rb +7 -0
  98. data/spec/merb/version_spec.rb +33 -0
  99. data/spec/merb/view_context_spec.rb +217 -59
  100. data/spec/spec_generator_helper.rb +15 -0
  101. data/spec/spec_helper.rb +5 -3
  102. data/spec/spec_helpers/url_shared_behaviour.rb +5 -7
  103. metadata +32 -7
  104. data/lib/merb/caching/store/memcache.rb +0 -20
  105. data/lib/merb/mixins/form_control.rb +0 -332
  106. data/lib/patch +0 -69
  107. data/spec/merb/core_ext_spec.rb +0 -464
  108. data/spec/merb/form_control_mixin_spec.rb +0 -431
@@ -1,580 +1,88 @@
1
1
  require 'rubygems'
2
+
3
+ # Make the app's "gems" directory a place where gems are loaded from
4
+ # This needs to go here for using in a shared envirionment where Erubis may not
5
+ # be available
6
+ if File.exists?(File.join(Dir.pwd, "gems")) && File.directory?(File.join(Dir.pwd,"gems"))
7
+ Gem.clear_paths
8
+ Gem.path.unshift(File.join(Dir.pwd,"gems"))
9
+ end
10
+
11
+
2
12
  require 'optparse'
3
13
  require 'ostruct'
4
14
  require 'fileutils'
5
15
  require 'yaml'
6
16
 
7
- require File.join(File.dirname(__FILE__), 'erubis_ext')
8
- require File.join(File.dirname(__FILE__), 'version')
17
+ # this is so we can test for HAML features for HAML partial inlining
18
+ unless Gem.cache.search("haml").empty?
19
+ gem "haml"
20
+ require "haml"
21
+ end
9
22
 
10
- module Merb
11
-
12
- module GlobalHelper
13
- end
23
+ require File.join(File.dirname(__FILE__), 'config')
14
24
 
15
- class Config
16
- class << self
17
- def defaults
18
- @defaults ||= {
19
- :host => "0.0.0.0",
20
- :port => "4000",
21
- :reloader => true,
22
- :cache_templates => false,
23
- :merb_root => Dir.pwd,
24
- :use_mutex => true,
25
- :session_id_cookie_only => true,
26
- :query_string_whitelist => [],
27
- :mongrel_x_sendfile => true
28
- }
29
- end
30
-
31
- def setup(global_merb_yml = nil)
32
- if FileTest.exist? "#{defaults[:merb_root]}/framework"
33
- $LOAD_PATH.unshift( "#{defaults[:merb_root]}/framework" )
34
- end
35
- global_merb_yml ||= "#{defaults[:merb_root]}/config/merb.yml"
36
- apply_configuration_from_file defaults, global_merb_yml
37
- end
25
+ module Merb
38
26
 
39
- def apply_configuration_from_file(configuration, file)
40
- if File.exists?(file)
41
- configuration.merge(Erubis.load_yaml_file(file))
42
- else
43
- configuration
44
- end
45
- end
46
- end
47
- end
48
-
49
27
  class Server
50
28
 
51
29
  class << self
52
30
 
53
- def merb_config(argv = ARGV)
54
- # Our primary configuration hash for the length of this method
55
- options = {}
56
-
57
- # Environment variables always win
58
- options[:environment] = ENV['MERB_ENV']
59
-
60
- # Build a parser for the command line arguements
61
- opts = OptionParser.new do |opts|
62
- opts.version = Merb::VERSION
63
- opts.release = Merb::RELEASE
64
-
65
- opts.banner = "Usage: merb [fdcepghmisluMG] [argument]"
66
- opts.define_head "Merb Mongrel+ Erb. Lightweight replacement for ActionPack."
67
- opts.separator '*'*80
68
- opts.separator 'If no flags are given, Merb starts in the foreground on port 4000.'
69
- opts.separator '*'*80
70
-
71
- opts.on("-u", "--user USER", "This flag is for having merb run as a user other than the one currently logged in. Note: if you set this you must also provide a --group option for it to take effect.") do |config|
72
- options[:user] = config
73
- end
74
-
75
- opts.on("-G", "--group GROUP", "This flag is for having merb run as a group other than the one currently logged in. Note: if you set this you must also provide a --user option for it to take effect.") do |config|
76
- options[:group] = config
77
- end
78
-
79
- opts.on("-f", "--config-file FILENAME", "This flag is for adding extra config files for things like the upload progress module.") do |config|
80
- options[:config] = config
81
- end
82
-
83
- opts.on("-d", "--daemonize", "This will run a single merb in the background.") do |config|
84
- options[:daemonize] = true
85
- end
86
-
87
- opts.on("-c", "--cluster-nodes NUM_MERBS", "Number of merb daemons to run.") do |nodes|
88
- options[:cluster] = nodes
89
- end
90
-
91
- opts.on("-p", "--port PORTNUM", "Port to run merb on, defaults to 4000.") do |port|
92
- options[:port] = port
93
- end
94
-
95
- opts.on("-h", "--host HOSTNAME", "Host to bind to (default is all IP's).") do |host|
96
- if host
97
- options[:host] = host
98
- else
99
- # If no host was given, assume they meant they wanted help.
100
- puts opts
101
- exit
102
- end
103
- end
104
-
105
- opts.on("-m", "--merb-root MERB_ROOT", "The path to the MERB_ROOT for the app you want to run (default is current working dir).") do |merb_root|
106
- options[:merb_root] = File.expand_path(merb_root)
107
- end
108
-
109
- opts.on("-i", "--irb-console", "This flag will start merb in irb console mode. All your models and other classes will be available for you in an irb session.") do |console|
110
- options[:console] = true
111
- end
112
-
113
- opts.on("-s", "--start-drb PORTNUM", "This is the port number to run the drb daemon on for sessions and upload progress monitoring.") do |drb_port|
114
- options[:start_drb] = true
115
- options[:only_drb] = true
116
- options[:drb_server_port] = drb_port
117
- end
118
-
119
- opts.on("-l", "--log-level LEVEL", "Log levels can be set to any of these options: DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN") do |loglevel|
120
- options[:log_level] = loglevel
121
- end
122
-
123
- opts.on("-e", "--environment STRING", "Run merb in the correct mode(development, production, testing)") do |env|
124
- options[:environment] ||= env
125
- end
126
-
127
- opts.on("-r", "--script-runner ['RUBY CODE'| FULL_SCRIPT_PATH]",
128
- "Command-line option to run scripts and/or code in the merb app.") do |stuff_to_run|
129
- options[:runner] = stuff_to_run
130
- end
131
-
132
- opts.on("-g", "--generate-app PATH", "Generate a fresh merb app at PATH.") do |path|
133
- options[:generate] = path || Dir.pwd
134
- end
135
-
136
- opts.on("-P","--generate-plugin PATH", "Generate a fresh merb plugin at PATH.") do |path|
137
- options[:generate_plugin] = path || Dir.pwd
138
- end
139
-
140
- opts.on("-k", "--kill PORT or all", "Kill one merb proceses by port number. Use merb -k all to kill all merbs.") do |ports|
141
- options[:kill] = ports
142
- end
143
-
144
- opts.on("-K", "--graceful PORT or all", "Gracefully kill one merb proceses by port number. Use merb -K all to gracefully kill all merbs.") do |ports|
145
- options[:graceful] = ports
146
- end
147
-
148
- opts.on("-M", "--merb-config FILENAME", "This flag is for explicitly declaring the merb app's config file.") do |config|
149
- options[:merb_config] = config
150
- end
151
-
152
- opts.on("-w", "--webrick", "Run merb using Webrick Rack Adapter instead of mongrel.") do |webport|
153
- options[:webrick] = true
154
- end
155
-
156
- opts.on("-F", "--fastcgi", "Run merb using FastCGI Rack Adapter instead of mongrel.") do
157
- options[:fastcgi] = true
158
- end
159
-
160
- opts.on("-X", "--mutex on/off", "This flag is for turning the mutex lock on and off.") do |mutex|
161
- if mutex == 'off'
162
- options[:use_mutex] = false
163
- else
164
- options[:use_mutex] = true
165
- end
166
- end
167
-
168
- opts.on("-?", "-H", "--help", "Show this help message") do
169
- puts opts
170
- exit
171
- end
172
- end
173
-
174
- # Parse what we have on the command line
175
- opts.parse!(argv)
176
-
177
- # merb <argument> is same as merb -g <argument>
178
- if argv.size == 1
179
- options[:generate] = File.expand_path(argv.last)
180
- end
181
-
182
- # If we run merb with no arguments and we are not inside a merb root
183
- # show the help message
184
- if (argv.size == 0) && !File.exists?("#{options[:merb_root] || Merb::Config.defaults[:merb_root]}/config/merb_init.rb") && !$TESTING
185
- puts "You are not in the root of a merb application...\n"
186
- puts opts
187
- exit
188
- end
189
- # Load up the configuration from file, but keep the command line
190
- # options that may have been chosen. Also, pass-through if we have
191
- # a new merb_config path.
192
- options = Merb::Config.setup(options[:merb_config]).merge(options)
193
-
194
- # Finally, if all else fails... set the environment to 'development'
195
- options[:environment] ||= 'development'
196
-
197
- environment_merb_yml = "#{options[:merb_root]}/config/environments/#{options[:environment]}.yml"
198
- options = Merb::Config.apply_configuration_from_file options, environment_merb_yml
199
-
200
- @@merb_opts = options
201
- end
202
-
203
- def max_mtime( files = [] )
204
- files.map{ |file| File.mtime(file) rescue @mtime }.max
205
- end
206
-
207
- def register_session_type(name, file, description = nil)
208
- @registered_session_types ||= YAML::Omap.new
209
- @registered_session_types[name] = {
210
- :file => file,
211
- :description => (description || "Using #{name} sessions")
212
- }
213
- end
214
-
215
- def add_controller_mixins
216
- types = @registered_session_types
217
- Merb::Controller.class_eval do
218
- lib = File.join(__DIR__, 'merb')
219
- session_store = Merb::Server.config[:session_store].to_s
220
- if ["", "false"].include?(session_store)
221
- puts "Not Using Sessions"
222
- elsif reg = types[session_store]
223
- if session_store == "cookie"
224
- unless @@merb_opts[:session_secret_key] && (@@merb_opts[:session_secret_key].length >= 16)
225
- puts("You must specify a session_secret_key in your merb.yml, and it must be at least 16 characters\nbailing out...")
226
- exit!
227
- end
228
- Merb::Controller.session_secret_key = @@merb_opts[:session_secret_key]
229
- end
230
- require reg[:file]
231
- include ::Merb::SessionMixin
232
- puts reg[:description]
233
- else
234
- puts "Session store not found, '#{Merb::Server.config[:session_store]}'."
235
- puts "Defaulting to CookieStore Sessions"
236
- unless @@merb_opts[:session_secret_key] && (@@merb_opts[:session_secret_key].length >= 16)
237
- puts("You must specify a session_secret_key in your merb.yml, and it must be at least 16 characters\nbailing out...")
238
- exit!
239
- end
240
- Merb::Controller.session_secret_key = @@merb_opts[:session_secret_key]
241
- require types['cookie'][:file]
242
- include ::Merb::SessionMixin
243
- puts "(plugin not installed?)"
244
- end
245
-
246
- if Merb::Server.config[:basic_auth]
247
- require lib + "/mixins/basic_authentication"
248
- include ::Merb::AuthenticationMixin
249
- puts "Basic Authentication mixed in"
250
- end
251
- end
252
- end
253
-
254
- def initialize_merb
255
- require 'merb'
256
- @mtime = Time.now if @@merb_opts[:reloader] == true
257
- # Register session types before merb_init.rb so that any additional
258
- # session stores will be added to the end of the list and become the
259
- # default.
260
- register_session_type('memory',
261
- __DIR__ / "merb" / "session" / "memory_session",
262
- "Using in-memory sessions; sessions will be lost whenever the server stops.")
263
- register_session_type('mem_cache',
264
- __DIR__ / "merb" / "session" / "mem_cache_session",
265
- "Using MemCache distributed memory sessions")
266
- register_session_type('cookie', # Last session type becomes the default
267
- __DIR__ / "merb" / "session" / "cookie_store",
268
- "Using 'share-nothing' cookie sessions (4kb limit per client)")
269
- require @@merb_opts[:merb_root] / 'config/merb_init.rb'
270
- add_controller_mixins
271
- end
272
-
273
- def after_app_loads(&block)
274
- @after_app_blocks ||= []
275
- @after_app_blocks << block
276
- end
277
-
278
- def app_loaded?
279
- @app_loaded
280
- end
281
-
282
- def load_action_arguments(klasses = Merb::Controller._subclasses)
283
- begin
284
- klasses.each do |controller|
285
- controller = Object.full_const_get(controller)
286
- controller.action_argument_list = {}
287
- controller.callable_actions.each do |action, bool|
288
- controller.action_argument_list[action.to_sym] = ParseTreeArray.translate(controller, action).get_args
289
- end
290
- end
291
- rescue
292
- klasses.each { |controller| controller.action_arguments = {} }
293
- end if defined?(ParseTreeArray)
294
- end
295
-
296
- def template_paths(type = "*")
297
- # This gets all templates set in the controllers template roots
298
- template_paths = Merb::AbstractController._abstract_subclasses.map do |klass|
299
- Object.full_const_get(klass)._template_root
300
- end.uniq.map do |path|
301
- Dir["#{path}/**/#{type}"]
302
- end
303
-
304
- # This gets the templates that might be created outside controllers
305
- # template roots. eg app/views/shared/*
306
- template_paths << Dir["#{MERB_ROOT}/app/views/**/*"] if type == "*"
307
-
308
- template_paths.flatten.compact.uniq || []
309
- end
310
-
311
- def load_controller_template_path_cache
312
- Merb::AbstractController.reset_template_path_cache!
313
-
314
- template_paths.each do |template|
315
- Merb::AbstractController.add_path_to_template_cache(template)
316
- end
317
- end
318
-
319
- def load_erubis_inline_helpers
320
- partials = template_paths("_*.erb")
321
-
322
- partials.each do |partial|
323
- eruby = Erubis::Eruby.new(File.read(partial))
324
- eruby.def_method(Merb::GlobalHelper, partial.gsub(/[^\.a-zA-Z0-9]/, "__").gsub(/\./, "_"), partial)
325
- end
326
- end
327
-
328
- def load_application
329
- MERB_PATHS.each do |glob|
330
- Dir[MERB_ROOT + glob].each { |m| require m }
331
- end
332
- load_action_arguments
333
- load_controller_template_path_cache
334
- load_erubis_inline_helpers
335
- @app_loaded = true
336
- (@after_app_blocks || []).each { |b| b.call }
337
- end
338
-
339
- def remove_constant(const)
340
- parts = const.to_s.split("::")
341
- base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::"))
342
- object = parts[-1].intern
343
- MERB_LOGGER.info("Removing constant #{object} from #{base}")
344
- base.send(:remove_const, object) if object
345
- Merb::Controller._subclasses.delete(const)
346
- end
347
-
348
- def reload
349
- return if !@@merb_opts[:reloader] || !Object.const_defined?(:MERB_PATHS)
350
-
351
- # First we collect all files in the project (this will also grab newly added files)
352
- project_files = MERB_PATHS.map { |path| Dir[@@merb_opts[:merb_root] + path] }.flatten.uniq
353
- erb_partials = template_paths("_*.erb").map { |path| Dir[path] }.flatten.uniq
354
- project_mtime = max_mtime(project_files + erb_partials) # Latest changed time of all project files
355
-
356
- return if @mtime.nil? || @mtime >= project_mtime # Only continue if a file has changed
357
-
358
- project_files.each do |file|
359
- if File.mtime(file) >= @mtime
360
- # If the file has changed or been added since the last project reload time
361
- # remove any cannonical constants, based on what type of project file it is
362
- # and then reload the file
363
- begin
364
- constant = case file
365
- when %r[/app/(models|controllers|parts|mailers)/(.+)\.rb$]
366
- $2.to_const_string
367
- when %r[/app/(helpers)/(.+)\.rb$]
368
- "Merb::" + $2.to_const_string
369
- end
370
- remove_constant(constant)
371
- rescue NameError => e
372
- MERB_LOGGER.warn "Couldn't remove constant #{constant}"
373
- end
374
-
375
- begin
376
- MERB_LOGGER.info("Reloading file #{file}")
377
- old_subclasses = Merb::Controller._subclasses.dup
378
- load(file)
379
- loaded_classes = Merb::Controller._subclasses - old_subclasses
380
- load_action_arguments(loaded_classes)
381
- rescue Exception => e
382
- puts "Error reloading file #{file}: #{e}"
383
- MERB_LOGGER.warn " Error: #{e}"
384
- end
385
-
386
- # constant = file =~ /\/(controllers|models|mailers|helpers|parts)\/(.*).rb/ ? $2.to_const_string : nil
387
- # remove_constant($2.to_const_string, ($1 == "helpers") ? Merb : nil)
388
- # load file and puts "loaded file: #{file}"
389
- end
390
- end
391
-
392
- # Rebuild the glob cache and erubis inline helpers
393
- load_controller_template_path_cache
394
- load_erubis_inline_helpers
395
-
396
- @mtime = project_mtime # As the last action, update the current @mtime
397
- end
398
-
399
31
  def run
400
- load_config
401
-
402
- if @@merb_opts[:generate] #|| @@merb_opts.size == 1
403
- require 'merb/generators/merb_app/merb_app'
404
- ::Merb::AppGenerator.run @@merb_opts[:generate]
405
- exit!
406
- end
407
-
408
- if ENV['EVENT'] || ENV['SWIFT']
409
- @@merb_opts[:use_mutex] = false
410
- end
411
-
412
- if @@merb_opts[:graceful]
413
- @@merb_opts[:kill] = @@merb_opts[:graceful]
414
- graceful = true
415
- end
416
-
417
- if k = @@merb_opts[:kill]
418
- begin
419
- Dir[@@merb_opts[:merb_root] + "/log/merb.#{k == 'all' ? '*' : k }.pid"].each do |f|
420
- puts f
421
- pid = IO.read(f).chomp.to_i
422
- signal = graceful ? 1 : 9
423
- Process.kill(signal, pid)
424
- FileUtils.rm f
425
- puts "killed PID #{pid} with signal #{signal}"
426
- end
427
- rescue
428
- puts "Failed to kill! #{k}"
429
- ensure
430
- exit
431
- end
432
- end
433
-
434
- case @@merb_opts[:environment].to_s
435
- when 'production'
436
- @@merb_opts[:reloader] = @@merb_opts.fetch(:reloader, false)
437
- @@merb_opts[:exception_details] = @@merb_opts.fetch(:exception_details, false)
438
- @@merb_opts[:cache_templates] = true
439
- else
440
- @@merb_opts[:reloader] = @@merb_opts.fetch(:reloader, true)
441
- @@merb_opts[:exception_details] = @@merb_opts.fetch(:exception_details, true)
442
- end
443
-
444
- @@merb_opts[:reloader_time] ||= 0.5 if @@merb_opts[:reloader] == true
445
-
446
- $LOAD_PATH.unshift( File.join(@@merb_opts[:merb_root] , '/app/models') )
447
- $LOAD_PATH.unshift( File.join(@@merb_opts[:merb_root] , '/app/controllers') )
448
- $LOAD_PATH.unshift( File.join(@@merb_opts[:merb_root] , '/lib') )
449
-
450
- if @@merb_opts[:generate_plugin]
451
- require 'merb/generators/merb_plugin'
452
- ::Merb::PluginGenerator.run @@merb_opts[:generate_plugin]
453
- exit!
454
- end
455
-
456
- if @@merb_opts[:reloader]
457
- Thread.abort_on_exception = true
458
- Thread.new do
459
- loop do
460
- sleep( @@merb_opts[:reloader_time] )
461
- reload if app_loaded?
462
- end
463
- Thread.exit
464
- end
465
- end
466
-
467
- if @@merb_opts[:console]
468
- initialize_merb
469
- _merb = Class.new do
470
- def self.show_routes(all_opts = false)
471
- seen = []
472
- unless Merb::Router.named_routes.empty?
473
- puts "Named Routes"
474
- Merb::Router.named_routes.each do |name,route|
475
- puts " #{name}: #{route}"
476
- seen << route
477
- end
478
- end
479
- puts "Anonymous Routes"
480
- (Merb::Router.routes - seen).each do |route|
481
- puts " #{route}"
482
- end
483
- nil
484
- end
485
-
486
- def self.url(path, *args)
487
- Merb::Router.generate(path,*args)
488
- end
489
- end
490
-
491
- Object.send(:define_method, :merb) {
492
- _merb
493
- }
494
-
495
- ARGV.clear # Avoid passing args to IRB
496
- require 'irb'
497
- require 'irb/completion'
498
- def exit
499
- exit!
500
- end
501
- if File.exists? ".irbrc"
502
- ENV['IRBRC'] = ".irbrc"
503
- end
504
- IRB.start
505
- exit!
506
- end
507
-
508
- if @@merb_opts[:runner]
509
- initialize_merb
510
- code_or_file = @@merb_opts[:runner]
511
- if File.exists?(code_or_file)
512
- eval(File.read(code_or_file))
513
- else
514
- eval(code_or_file)
515
- end
516
- exit!
517
- end
518
-
519
- if @@merb_opts[:start_drb]
520
- puts "Starting merb drb server on port: #{@@merb_opts[:drb_server_port]}"
521
- start(@@merb_opts[:drb_server_port], :drbserver_start)
522
- exit if @@merb_opts[:only_drb]
523
- end
524
-
525
- if @@merb_opts[:webrick]
526
- puts "Starting merb webrick server on port: #{@@merb_opts[:port]}"
527
- trap('TERM') { exit }
528
- webrick_start(@@merb_opts[:port])
529
- end
530
-
531
- if @@merb_opts[:fastcgi]
532
- trap('TERM') { exit }
533
- fastcgi_start
534
- end
535
-
536
-
537
- if @@merb_opts[:cluster]
32
+ ::Merb::Config.parse_args
33
+
34
+ if Merb::Config[:cluster]
538
35
  delete_pidfiles
539
- @@merb_opts[:port].to_i.upto(@@merb_opts[:port].to_i+@@merb_opts[:cluster].to_i-1) do |port|
36
+ Merb::Config[:port].to_i.upto(Merb::Config[:port].to_i+Merb::Config[:cluster].to_i-1) do |port|
540
37
  puts "Starting merb server on port: #{port}"
541
38
  start(port)
542
39
  end
543
- elsif @@merb_opts[:daemonize]
544
- delete_pidfiles(@@merb_opts[:port])
545
- start(@@merb_opts[:port])
40
+ elsif Merb::Config[:daemonize]
41
+ delete_pidfiles(Merb::Config[:port])
42
+ start(Merb::Config[:port])
546
43
  else
547
44
  trap('TERM') { exit }
548
- mongrel_start(@@merb_opts[:port])
45
+ mongrel_start(Merb::Config[:port])
549
46
  end
550
-
47
+
551
48
  end
552
49
 
553
50
  def store_pid(pid,port)
554
- File.open("#{@@merb_opts[:merb_root]}/log/merb.#{port}.pid", 'w'){|f| f.write("#{Process.pid}\n")}
51
+ File.open("#{Merb::Config[:merb_root]}/log/merb.#{port}.pid", 'w'){|f| f.write("#{Process.pid}\n")}
555
52
  end
556
53
 
54
+ def kill(ports, sig=9)
55
+ begin
56
+ Dir[Merb::Config[:merb_root] + "/log/merb.#{ports == 'all' ? '*' : ports }.pid"].each do |f|
57
+ pid = IO.read(f).chomp.to_i
58
+ Process.kill(sig, pid)
59
+ FileUtils.rm f
60
+ puts "killed PID #{pid} with signal #{sig}"
61
+ end
62
+ rescue
63
+ puts "Failed to kill! #{k}"
64
+ ensure
65
+ exit
66
+ end
67
+ end
68
+
557
69
  def start(port,what=:mongrel_start)
558
70
  fork do
559
71
  Process.setsid
560
72
  exit if fork
561
- if what == :mongrel_start
562
- store_pid(Process.pid, port)
563
- else
564
- store_pid(Process.pid, "drb.#{port}")
565
- end
566
- Dir.chdir @@merb_opts[:merb_root]
567
73
  File.umask 0000
568
74
  STDIN.reopen "/dev/null"
569
75
  STDOUT.reopen "/dev/null", "a"
570
76
  STDERR.reopen STDOUT
571
77
  trap("TERM") { exit }
78
+ Dir.chdir Merb::Config[:merb_root]
572
79
  send(what, port)
573
80
  end
574
81
  end
575
82
 
576
83
  def webrick_start(port)
577
- initialize_merb
84
+ Merb::BootLoader.initialize_merb
85
+ store_pid(Process.pid, port)
578
86
  require 'rack'
579
87
  require 'merb/rack_adapter'
580
88
  ::Rack::Handler::WEBrick.run Merb::Rack::Adapter.new,
@@ -582,63 +90,61 @@ module Merb
582
90
  end
583
91
 
584
92
  def fastcgi_start
585
- initialize_merb
93
+ Merb::BootLoader.initialize_merb
586
94
  require 'rack'
587
95
  require 'merb/rack_adapter'
588
96
  ::Rack::Handler::FastCGI.run Merb::Rack::Adapter.new
589
97
  end
590
98
 
591
99
  def delete_pidfiles(portor_star='*')
592
- Dir["#{@@merb_opts[:merb_root]}/log/merb.#{portor_star}.pid"].each do |pid|
100
+ Dir["#{Merb::Config[:merb_root]}/log/merb.#{portor_star}.pid"].each do |pid|
593
101
  FileUtils.rm(pid) rescue nil
594
102
  end
595
103
  end
596
104
 
597
105
  def drbserver_start(port)
598
106
  puts "Starting merb drb server on port: #{port}"
599
- require 'merb/merb_drb_server'
600
- drb_init = File.join(@@merb_opts[:merb_root], "/config/merb_drb_init")
107
+ require 'merb/drb_server'
108
+ Merb::BootLoader.initialize_merb
109
+ store_pid(Process.pid, "drb.#{port}")
110
+ drb_init = File.join(Merb.root, "/config/drb_init")
601
111
  require drb_init if File.exist?(drb_init)
602
- DRb.start_service("druby://#{@@merb_opts[:host]}:#{port}", Merb::DrbServiceProvider)
112
+ DRb.start_service("druby://#{Merb::Config[:host]}:#{port}", Merb::DrbServiceProvider)
603
113
  DRb.thread.join
604
114
  end
605
115
 
606
116
  def mongrel_start(port)
607
- @@merb_opts[:port] = port
608
- unless @@merb_opts[:generate] || @@merb_opts[:console] || @@merb_opts[:only_drb] || @@merb_opts[:kill]
117
+ store_pid(Process.pid, port)
118
+ Merb::Config[:port] = port
119
+ unless Merb::Config[:generate] || Merb::Config[:console] || Merb::Config[:only_drb] || Merb::Config[:kill]
609
120
  puts %{Merb started with these options:}
610
- puts @@merb_opts.to_yaml; puts
121
+ puts Merb::Config.to_yaml; puts
611
122
  end
612
- initialize_merb
123
+ Merb::BootLoader.initialize_merb
613
124
 
614
- mconf_hash = {:host => (@@merb_opts[:host]||"0.0.0.0"), :port => (port ||4000)}
615
- if @@merb_opts[:user] and @@merb_opts[:group]
616
- mconf_hash[:user] = @@merb_opts[:user]
617
- mconf_hash[:group] = @@merb_opts[:group]
125
+ mconf_hash = {:host => (Merb::Config[:host]||"0.0.0.0"), :port => (port ||4000)}
126
+ if Merb::Config[:user] and Merb::Config[:group]
127
+ mconf_hash[:user] = Merb::Config[:user]
128
+ mconf_hash[:group] = Merb::Config[:group]
618
129
  end
619
130
  mconfig = Mongrel::Configurator.new(mconf_hash) do
620
131
  listener do
621
- uri( "/", :handler => MerbUploadHandler.new(@@merb_opts), :in_front => true) if @@merb_opts[:upload_path_match]
622
- uri "/", :handler => MerbHandler.new(@@merb_opts[:merb_root]+'/public', @@merb_opts[:mongrel_x_sendfile])
132
+ uri( "/", :handler => MerbUploadHandler.new(Merb::Config), :in_front => true) if Merb::Config[:upload_path_match]
133
+ uri "/", :handler => MerbHandler.new(Merb.root+'/public', Merb::Config[:mongrel_x_sendfile])
623
134
  uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("")
624
135
  end
625
- MerbHandler.path_prefix = @@merb_opts[:path_prefix]
136
+ MerbHandler.path_prefix = Merb::Config[:path_prefix]
626
137
 
627
138
  trap("INT") { stop }
628
139
  run
629
140
  end
630
141
  mconfig.join
631
- end
142
+ end
632
143
 
633
144
  def config
634
- @@merb_opts
145
+ Merb::Config
635
146
  end
636
147
 
637
- def load_config
638
- @@merb_raw_opts = ARGV
639
- merb_config
640
- end
641
-
642
148
  end # class << self
643
149
 
644
150
  end # Server