merb 0.4.2 → 0.5.0

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