merb 0.3.4 → 0.3.7

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 (62) hide show
  1. data/README +206 -197
  2. data/Rakefile +12 -21
  3. data/bin/merb +1 -1
  4. data/examples/skeleton/Rakefile +6 -20
  5. data/examples/skeleton/dist/app/mailers/layout/application.erb +1 -0
  6. data/examples/skeleton/dist/conf/database.yml +23 -0
  7. data/examples/skeleton/dist/conf/environments/development.rb +1 -0
  8. data/examples/skeleton/dist/conf/environments/production.rb +1 -0
  9. data/examples/skeleton/dist/conf/environments/test.rb +1 -0
  10. data/examples/skeleton/dist/conf/merb.yml +32 -28
  11. data/examples/skeleton/dist/conf/merb_init.rb +16 -13
  12. data/examples/skeleton/dist/conf/router.rb +9 -9
  13. data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +2 -2
  14. data/lib/merb.rb +23 -18
  15. data/lib/merb/caching/fragment_cache.rb +3 -7
  16. data/lib/merb/caching/store/memcache.rb +20 -0
  17. data/lib/merb/core_ext/merb_array.rb +0 -0
  18. data/lib/merb/core_ext/merb_class.rb +44 -4
  19. data/lib/merb/core_ext/merb_enumerable.rb +43 -1
  20. data/lib/merb/core_ext/merb_hash.rb +200 -122
  21. data/lib/merb/core_ext/merb_kernel.rb +2 -0
  22. data/lib/merb/core_ext/merb_module.rb +41 -0
  23. data/lib/merb/core_ext/merb_numeric.rb +57 -5
  24. data/lib/merb/core_ext/merb_object.rb +172 -6
  25. data/lib/merb/generators/merb_app/merb_app.rb +15 -9
  26. data/lib/merb/merb_abstract_controller.rb +193 -0
  27. data/lib/merb/merb_constants.rb +26 -1
  28. data/lib/merb/merb_controller.rb +143 -234
  29. data/lib/merb/merb_dispatcher.rb +28 -20
  30. data/lib/merb/merb_drb_server.rb +2 -3
  31. data/lib/merb/merb_exceptions.rb +194 -49
  32. data/lib/merb/merb_handler.rb +34 -26
  33. data/lib/merb/merb_mail_controller.rb +200 -0
  34. data/lib/merb/merb_mailer.rb +33 -13
  35. data/lib/merb/merb_part_controller.rb +42 -0
  36. data/lib/merb/merb_plugins.rb +293 -0
  37. data/lib/merb/merb_request.rb +6 -4
  38. data/lib/merb/merb_router.rb +99 -65
  39. data/lib/merb/merb_server.rb +65 -21
  40. data/lib/merb/merb_upload_handler.rb +2 -1
  41. data/lib/merb/merb_view_context.rb +36 -15
  42. data/lib/merb/mixins/basic_authentication_mixin.rb +5 -5
  43. data/lib/merb/mixins/controller_mixin.rb +67 -28
  44. data/lib/merb/mixins/erubis_capture_mixin.rb +1 -8
  45. data/lib/merb/mixins/form_control_mixin.rb +280 -42
  46. data/lib/merb/mixins/render_mixin.rb +127 -45
  47. data/lib/merb/mixins/responder_mixin.rb +5 -7
  48. data/lib/merb/mixins/view_context_mixin.rb +260 -94
  49. data/lib/merb/session.rb +23 -0
  50. data/lib/merb/session/merb_ar_session.rb +28 -16
  51. data/lib/merb/session/merb_mem_cache_session.rb +108 -0
  52. data/lib/merb/session/merb_memory_session.rb +65 -20
  53. data/lib/merb/template/erubis.rb +22 -13
  54. data/lib/merb/template/haml.rb +5 -16
  55. data/lib/merb/template/markaby.rb +5 -3
  56. data/lib/merb/template/xml_builder.rb +17 -5
  57. data/lib/merb/test/merb_fake_request.rb +63 -0
  58. data/lib/merb/test/merb_multipart.rb +58 -0
  59. data/lib/tasks/db.rake +2 -0
  60. data/lib/tasks/merb.rake +20 -8
  61. metadata +24 -25
  62. data/examples/skeleton.tar +0 -0
@@ -13,7 +13,9 @@ module Merb
13
13
  @request.read
14
14
  end
15
15
 
16
- # returns true if the request is an ajax request.
16
+ # Returns true if the request is an Ajax request.
17
+ #
18
+ # Also aliased as the more memorable ajax? and xhr?.
17
19
  def xml_http_request?
18
20
  not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil?
19
21
  end
@@ -24,15 +26,15 @@ module Merb
24
26
  def remote_ip
25
27
  return @env['HTTP_CLIENT_IP'] if @env.include?('HTTP_CLIENT_IP')
26
28
 
27
- if @env.include?(Mongrel::Const::HTTP_X_FORWARDED_FOR) then
28
- remote_ips = @env[Mongrel::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip|
29
+ if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then
30
+ remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip|
29
31
  ip =~ /^unknown$|^(127|10|172\.16|192\.168)\./i
30
32
  end
31
33
 
32
34
  return remote_ips.first.strip unless remote_ips.empty?
33
35
  end
34
36
 
35
- return @env[Mongrel::Const::REMOTE_ADDR]
37
+ return @env[Merb::Const::REMOTE_ADDR]
36
38
  end
37
39
 
38
40
  # returns either 'https://' or 'http://' depending on
@@ -6,7 +6,7 @@ module Merb
6
6
 
7
7
  class << self
8
8
 
9
- def prepare(&block)
9
+ def prepare
10
10
  @@matcher = RouteMatcher.new
11
11
  @@generator = RouteGenerator.new
12
12
 
@@ -31,8 +31,8 @@ module Merb
31
31
  @@matcher.route_request(path)
32
32
  end
33
33
 
34
- def generate(method, options = {})
35
- @@generator.generate(method, options)
34
+ def generate(method, *args)
35
+ @@generator.generate(method, *args)
36
36
  end
37
37
 
38
38
  def resources(res, opts={})
@@ -57,8 +57,8 @@ module Merb
57
57
  end
58
58
  end
59
59
 
60
- def default_routes
61
- @@matcher.default_routes
60
+ def default_routes(*a)
61
+ @@matcher.default_routes(*a)
62
62
  end
63
63
 
64
64
  def compiled_statement
@@ -80,32 +80,33 @@ module Merb
80
80
  end # class << self
81
81
 
82
82
  class RouteMatcher
83
-
83
+ attr_reader :routes, :compiled_statement, :compiled_regexen
84
+
84
85
  def initialize
85
86
  @routes = Array.new
87
+ # The final compiled lambda that gets used as the body of the route_request method.
86
88
  @compiled_statement = String.new
87
89
  @compiled_regexen = Array.new
88
90
  end
89
91
 
90
- # the final compiled lambda that gets used
91
- # as the body of the route_request method.
92
- def compiled_statement
93
- @compiled_statement
92
+ # Add a route to be compiled.
93
+ def add(*route)
94
+ opt = Hash === route.last ? route.pop : {}
95
+ if n = opt[:namespace]
96
+ path = "/#{n}#{route[0]}"
97
+ else
98
+ path = route[0]
99
+ end
100
+ @routes << [path, opt]
94
101
  end
95
102
 
96
- def compiled_regexen
97
- @compiled_regexen
98
- end
99
-
100
- # add a route to be compiled
101
- def add(*route)
102
- @routes << [route[0], (route[1] || {})]
103
+ def raw_add(*route)
104
+ @routes << [route[0], (route[1]||{})]
103
105
  end
104
106
 
105
- # build up a string that defines a lambda
106
- # that does a case statement on the PATH_INFO
107
- # against each of the compiled routes in turn.
108
- # first route that matches wins.
107
+ # Build up a string that defines a lambda that does a case statement on
108
+ # the PATH_INFO against each of the compiled routes in turn. First route
109
+ # that matches wins.
109
110
  def compile_router
110
111
  router_lambda = @routes.inject("lambda{|path| \n sections={}\n case path\n") { |m,r|
111
112
  m << compile(r)
@@ -114,11 +115,10 @@ module Merb
114
115
  meta_def(:route_request, &eval(router_lambda))
115
116
  end
116
117
 
117
- # compile each individual route into a when /.../
118
- # component of the case statement. Takes /:sections
119
- # of the route def that start with : and turns them
120
- # into placeholders for whatever urls match against
121
- # the route in question.
118
+ # Compile each individual route into a when /.../ component of the case
119
+ # statement. Takes /:sections of the route def that start with : and
120
+ # turns them into placeholders for whatever urls match against the route
121
+ # in question.
122
122
  def compile(route)
123
123
  raise ArgumentError unless String === route[0]
124
124
  code, count = '', 0
@@ -143,45 +143,48 @@ module Merb
143
143
  end
144
144
 
145
145
  def generate_resources_routes(res,opt)
146
- with_options :controller => res.to_s, :rest => true do |r|
147
- r.add "#{opt[:prefix]}/#{res}/:id[;/]edit", :allowed => {:get => 'edit'}
148
- r.add "#{opt[:prefix]}/#{res}/new[;/]:action", :allowed => {:get => 'new', :post => 'new', :put => 'new', :delete => 'new'}
149
- r.add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
146
+ with_options opt.merge(:controller => res.to_s, :rest => true) do |r|
147
+ r.raw_add "#{opt[:prefix]}/#{res}/:id[;/]edit", :allowed => {:get => 'edit'}
148
+ r.raw_add "#{opt[:prefix]}/#{res}/new[;/]:action", :allowed => {:get => 'new', :post => 'new', :put => 'new', :delete => 'new'}
149
+ r.raw_add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
150
150
  if mem = opt[:member]
151
151
  mem.keys.sort_by{|x| "#{x}"}.each {|action|
152
152
  allowed = mem[action].injecting({}) {|h, verb| h[verb] = "#{action}"}
153
- r.add "#{opt[:prefix]}/#{res}/:id[;/]+#{action}", :allowed => allowed
153
+ r.raw_add "#{opt[:prefix]}/#{res}/:id[;/]+#{action}", :allowed => allowed
154
154
  }
155
155
  end
156
156
  if coll = opt[:collection]
157
157
  coll.keys.sort_by{|x| "#{x}"}.each {|action|
158
158
  allowed = coll[action].injecting({}) {|h, verb| h[verb] = "#{action}"}
159
- r.add "#{opt[:prefix]}/#{res}[;/]#{action}", :allowed => allowed
159
+ r.raw_add "#{opt[:prefix]}/#{res}[;/]#{action}", :allowed => allowed
160
160
  }
161
161
  end
162
- r.add "#{opt[:prefix]}/#{res}/:id\\.:format", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
163
- r.add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'index', :post => 'create'}
164
- r.add "#{opt[:prefix]}/#{res}/:id", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
165
- r.add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'index', :post => 'create'}
162
+ r.raw_add "#{opt[:prefix]}/#{res}/:id\\.:format", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
163
+ r.raw_add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'index', :post => 'create'}
164
+ r.raw_add "#{opt[:prefix]}/#{res}/:id", :allowed => {:get => 'show', :put => 'update', :delete => 'destroy'}
165
+ r.raw_add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'index', :post => 'create'}
166
166
  end
167
167
  end
168
168
 
169
169
  def generate_singleton_routes(res,opt)
170
- with_options :controller => res.to_s, :rest => true do |r|
171
- r.add "#{opt[:prefix]}/#{res}[;/]edit", :allowed => {:get => 'edit'}
172
- r.add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'show'}
173
- r.add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
174
- r.add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'show', :post => 'create', :put => 'update', :delete => 'destroy'}
170
+ with_options opt.merge(:controller => res.to_s, :rest => true ) do |r|
171
+ r.raw_add "#{opt[:prefix]}/#{res}[;/]edit", :allowed => {:get => 'edit'}
172
+ r.raw_add "#{opt[:prefix]}/#{res}\\.:format", :allowed => {:get => 'show'}
173
+ r.raw_add "#{opt[:prefix]}/#{res}/new" , :allowed => {:get => 'new'}
174
+ r.raw_add "#{opt[:prefix]}/#{res}/?", :allowed => {:get => 'show', :post => 'create', :put => 'update', :delete => 'destroy'}
175
175
  end
176
176
  end
177
177
 
178
- def default_routes
179
- add "/:controller/:action/:id\\.:format"
180
- add "/:controller/:action/:id"
181
- add "/:controller/:action\\.:format"
182
- add "/:controller/:action"
183
- add "/:controller\\.:format", :action => 'index'
184
- add "/:controller", :action => 'index'
178
+ def default_routes(opt={})
179
+ namespace = opt[:namespace] ? "/#{opt[:namespace]}" : ""
180
+ with_options opt do |r|
181
+ r.raw_add namespace + "/:controller/:action/:id\\.:format"
182
+ r.raw_add namespace + "/:controller/:action/:id"
183
+ r.raw_add namespace + "/:controller/:action\\.:format"
184
+ r.raw_add namespace + "/:controller/:action"
185
+ r.raw_add namespace + "/:controller\\.:format", :action => 'index'
186
+ r.raw_add namespace + "/:controller", :action => 'index'
187
+ end
185
188
  end
186
189
  end
187
190
 
@@ -194,14 +197,29 @@ module Merb
194
197
  end
195
198
 
196
199
  def add(name, path)
197
- name = name.intern unless Symbol === name
198
- @paths[name] = path
200
+ @paths[name.to_sym] = path
199
201
  end
200
-
201
- def generate(name, options = {})
202
+
203
+ def generate(name, *args)
204
+ options = Hash === args.last ? args.pop : {}
205
+ obj = args[0]
206
+ options.each do |key, value|
207
+ next unless value.respond_to?(:to_param)
208
+ unless key.to_s =~ /_?id$/
209
+ old_key = key
210
+ options[old_key] = value.to_param
211
+ key = "#{key}_id".intern
212
+ end
213
+ options[key] = value.to_param
214
+ end
215
+
202
216
  path = @paths[name].dup
203
217
  while path =~ Router::SECTION_REGEXP
204
- path.sub!(Router::SECTION_REGEXP, options[$~[1].intern].to_s)
218
+ if obj.respond_to?($1) && ! obj.nil?
219
+ path.sub!(Router::SECTION_REGEXP, obj.send($1).to_s)
220
+ else
221
+ path.sub!(Router::SECTION_REGEXP, options[$1.intern].to_s)
222
+ end
205
223
  end
206
224
  if f = options[:format]
207
225
  "#{path}.#{f}"
@@ -209,28 +227,44 @@ module Merb
209
227
  path
210
228
  end
211
229
  end
212
-
230
+
213
231
  def generate_singleton_routes(res,opt)
214
- add "edit_#{res}", "#{opt[:prefix]}/#{res}/edit"
215
- add "new_#{res}","#{opt[:prefix]}/#{res}/new"
216
- add res, "#{opt[:prefix]}/#{res}"
232
+ res = res.to_s
233
+ if opt[:namespace]
234
+ namespace = "#{opt[:namespace]}_"
235
+ name = "/#{opt[:namespace]}"
236
+ else
237
+ namespace = ''
238
+ name = ''
239
+ end
240
+ add namespace + "edit_#{res}", name + "#{opt[:prefix]}/#{res}/edit"
241
+ add namespace + "new_#{res}", name + "#{opt[:prefix]}/#{res}/new"
242
+ add namespace + res, name + "#{opt[:prefix]}/#{res}"
217
243
  end
218
244
 
219
245
  def generate_resources_routes(res,opt)
220
- res_singular = res.to_s.singularize
221
- add res, "#{opt[:prefix]}/#{res}"
222
- add res_singular, "#{opt[:prefix]}/#{res}/:id"
223
- add "new_#{res_singular}", "#{opt[:prefix]}/#{res}/new"
224
- add "custom_new_#{res_singular}", "#{opt[:prefix]}/#{res}/new/:action"
225
- add "edit_#{res_singular}", "#{opt[:prefix]}/#{res}/:id/edit"
246
+ res = res.to_s
247
+ res_singular = res.singularize
248
+ if opt[:namespace]
249
+ namespace = "#{opt[:namespace]}_"
250
+ name = "/#{opt[:namespace]}"
251
+ else
252
+ namespace = ''
253
+ name = ''
254
+ end
255
+ add namespace + res, name + "#{opt[:prefix]}/#{res}"
256
+ add namespace + res_singular, name + "#{opt[:prefix]}/#{res}/:id"
257
+ add namespace + "new_#{res_singular}", name + "#{opt[:prefix]}/#{res}/new"
258
+ add namespace + "custom_new_#{res_singular}", name + "#{opt[:prefix]}/#{res}/new/:action"
259
+ add namespace + "edit_#{res_singular}", name + "#{opt[:prefix]}/#{res}/:id/edit"
226
260
  if mem = opt[:member]
227
261
  mem.keys.sort_by{|x| "#{x}"}.each {|action|
228
- add "#{action}_#{res_singular}", "#{opt[:prefix]}/#{res}/:id/#{action}"
262
+ add namespace + "#{action}_#{res_singular}", name + "#{opt[:prefix]}/#{res}/:id/#{action}"
229
263
  }
230
264
  end
231
265
  if coll = opt[:collection]
232
266
  coll.keys.sort_by{|x| "#{x}"}.each {|action|
233
- add "#{action}_#{res_singular}", "#{opt[:prefix]}/#{res}/#{action}"
267
+ add namespace + "#{action}_#{res_singular}", name + "#{opt[:prefix]}/#{res}/#{action}"
234
268
  }
235
269
  end
236
270
  end
@@ -15,7 +15,9 @@ module Merb
15
15
  :allow_reloading => true,
16
16
  :merb_root => Dir.pwd,
17
17
  :cache_templates => false,
18
- :use_mutex => true
18
+ :use_mutex => true,
19
+ :session_id_cookie_only => true,
20
+ :query_string_whitelist => []
19
21
  }
20
22
  begin
21
23
  options = defaults.merge(YAML.load(Erubis::Eruby.new(IO.read("#{defaults[:merb_root]}/dist/conf/merb.yml")).result))
@@ -36,9 +38,9 @@ module Merb
36
38
 
37
39
  opts = OptionParser.new do |opts|
38
40
  opts.banner = "Usage: merb [fdcepghmisluMG] [argument]"
39
- opts.define_head "Merb Mongrel+ Erb. Lightweight replacement for ActionPack"
41
+ opts.define_head "Merb Mongrel+ Erb. Lightweight replacement for ActionPack."
40
42
  opts.separator '*'*80
41
- opts.separator 'If no flags are given, Merb starts in the foreground on port 4000'
43
+ opts.separator 'If no flags are given, Merb starts in the foreground on port 4000.'
42
44
  opts.separator '*'*80
43
45
 
44
46
  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|
@@ -49,27 +51,27 @@ module Merb
49
51
  options[:group] = config
50
52
  end
51
53
 
52
- opts.on("-f", "--config-file FILENAME", "This flag is for adding extra config files for things like the upload progress module") do |config|
54
+ opts.on("-f", "--config-file FILENAME", "This flag is for adding extra config files for things like the upload progress module.") do |config|
53
55
  options[:config] = config
54
56
  end
55
57
 
56
- opts.on("-d", "--daemonize", "This will run a single merb in the background") do |config|
58
+ opts.on("-d", "--daemonize", "This will run a single merb in the background.") do |config|
57
59
  options[:daemonize] = true
58
60
  end
59
61
 
60
- opts.on("-c", "--cluster-nodes NUM_MERBS", "Number of merb daemons to run") do |nodes|
62
+ opts.on("-c", "--cluster-nodes NUM_MERBS", "Number of merb daemons to run.") do |nodes|
61
63
  options[:cluster] = nodes
62
64
  end
63
65
 
64
- opts.on("-p", "--port PORTNUM", "Port to run merb on, defaults to 4000") do |port|
66
+ opts.on("-p", "--port PORTNUM", "Port to run merb on, defaults to 4000.") do |port|
65
67
  options[:port] = port
66
68
  end
67
69
 
68
- opts.on("-h", "--host HOSTNAME", "Host to bind to(default is all IP's)") do |host|
70
+ opts.on("-h", "--host HOSTNAME", "Host to bind to (default is all IP's).") do |host|
69
71
  options[:host] = host
70
72
  end
71
73
 
72
- opts.on("-m", "--merb-root MERB_ROOT", "the path to the MERB_ROOT for the app you want to run") do |merb_root|
74
+ 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|
73
75
  options[:merb_root] = File.expand_path(merb_root)
74
76
  end
75
77
 
@@ -77,7 +79,7 @@ module Merb
77
79
  options[:console] = true
78
80
  end
79
81
 
80
- opts.on("-s", "--start-drb PORTNUM", "This is the port number to run the drb daemon on for sessions and uplod progress monitoring.") do |drb_port|
82
+ 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|
81
83
  options[:start_drb] = true
82
84
  options[:only_drb] = true
83
85
  options[:drb_server_port] = drb_port
@@ -91,19 +93,23 @@ module Merb
91
93
  options[:environment] = env
92
94
  end
93
95
 
94
- opts.on("-r", "--script-runner ['RUBY CODE'| FULL_SCRIPT_PATH]", "Command-line option to run scripts and/or code in the merb app") do |stuff_to_run|
96
+ opts.on("-r", "--script-runner ['RUBY CODE'| FULL_SCRIPT_PATH]", "Command-line option to run scripts and/or code in the merb app.") do |stuff_to_run|
95
97
  options[:runner] = stuff_to_run
96
98
  end
97
99
 
98
- opts.on("-g", "--generate-app PATH", "Generate a fresh merb app at PATH") do |path|
100
+ opts.on("-g", "--generate-app PATH", "Generate a fresh merb app at PATH.") do |path|
99
101
  options[:generate] = path || Dir.pwd
100
102
  end
101
103
 
102
- opts.on("-k", "--kill PORT or all", "Kill one merb proceses by port number. use merb -k all to kill all merbs") do |ports|
104
+ opts.on("-P", "--plugin ACTION NAME", "Do ACTION with a plugin called NAME.") do |action|
105
+ options[:plugin] = [action, ARGV] || nil
106
+ end
107
+
108
+ opts.on("-k", "--kill PORT or all", "Kill one merb proceses by port number. use merb -k all to kill all merbs.") do |ports|
103
109
  options[:kill] = ports
104
110
  end
105
111
 
106
- opts.on("-M", "--merb-config FILENAME", "This flag is for explicitly declaring the merb app's config file") do |config|
112
+ opts.on("-M", "--merb-config FILENAME", "This flag is for explicitly declaring the merb app's config file.") do |config|
107
113
  options[:merb_config] = config
108
114
  end
109
115
 
@@ -131,9 +137,28 @@ module Merb
131
137
  # or if we add :merb_root: /path/to/merb/app in the merb.yml we can now only call it
132
138
  # like so: merb --merb-config /path/to/dist/conf/merb.yml
133
139
  if options[:merb_config]
140
+ # Check and see if an environment has been set through the CLI
141
+ # if so, save it in a temp. In this case, if merb.yml has an :environment:
142
+ # set... it will be overwritten by the CLI. [Rogelio J. Samour] 2007-06-07
143
+ if options[:environment]
144
+ temp_env = options[:environment]
145
+ end
134
146
  options = options.merge(YAML.load(Erubis::Eruby.new(IO.read("#{options[:merb_config]}")).result))
147
+ if temp_env
148
+ options[:environment] = temp_env
149
+ end
135
150
  end
136
151
 
152
+ if ENV['MERB_ENV']
153
+ # ENV['MERB_ENV'] has precedence over all
154
+ options[:environment] = ENV['MERB_ENV']
155
+ end
156
+
157
+ # Finally, if all else fails... set the environment to 'development'
158
+ if options[:environment].nil?
159
+ options[:environment] = 'development'
160
+ end
161
+
137
162
  @@merb_opts = options
138
163
  end
139
164
 
@@ -141,6 +166,7 @@ module Merb
141
166
  require 'merb'
142
167
  require @@merb_opts[:merb_root] / 'dist/conf/router.rb'
143
168
  require @@merb_opts[:merb_root] / 'dist/conf/merb_init.rb'
169
+
144
170
  end
145
171
 
146
172
  def run
@@ -180,8 +206,8 @@ module Merb
180
206
  end
181
207
 
182
208
  @@merb_opts[:dist_root] = @@merb_opts[:merb_root]+'/dist'
183
- $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/app/controllers') )
184
209
  $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/app/models') )
210
+ $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/app/controllers') )
185
211
  $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/lib') )
186
212
  if File.exist? File.join(@@merb_opts[:dist_root] , '/framework')
187
213
  $LOAD_PATH.unshift( File.join(@@merb_opts[:dist_root] , '/framework') )
@@ -193,17 +219,35 @@ module Merb
193
219
  exit!
194
220
  end
195
221
 
222
+ if @@merb_opts[:plugin]
223
+ require 'merb/merb_plugins'
224
+ ::Merb::PluginManager.action(@@merb_opts[:plugin].shift, @@merb_opts[:plugin][0].shift, @@merb_opts[:plugin])
225
+ exit!
226
+ end
227
+
196
228
  if @@merb_opts[:console]
197
229
  initialize_merb
198
- Object.class_eval do
199
- def show_routes
200
- Merb::Router.generator.paths.each {|p| puts p.inspect}
230
+ _merb = Class.new do
231
+ def self.show_routes(all_opts = false)
232
+ puts "== show_routes(all_opts = #{all_opts}) =="
233
+ puts "RouteMatcher:"
234
+ Merb::Router.matcher.routes.each {|route,opts| puts " #{route}" + (all_opts ? " " + opts.inspect : "") }
235
+ puts
236
+ puts "RouteGenerator:"
237
+ # Sort alphabetically by the url part of the route for easier reading.
238
+ Merb::Router.generator.paths.sort {|a,b| a.last <=> b.last }.each {|p| puts " " + p.inspect}
201
239
  nil
202
240
  end
203
- def url(path, o={})
204
- Merb::Router.generator.generate(path,o)
241
+
242
+ def self.url(path, *args)
243
+ Merb::Router.generate(path,*args)
205
244
  end
206
245
  end
246
+
247
+ Object.send(:define_method, :merb) {
248
+ _merb
249
+ }
250
+
207
251
  ARGV.clear # Avoid passing args to IRB
208
252
  require 'irb'
209
253
  require 'irb/completion'
@@ -306,7 +350,7 @@ module Merb
306
350
  listener do
307
351
  uri( "/", :handler => MerbUploadHandler.new(yconfig), :in_front => true) if @@merb_opts[:config]
308
352
  uri "/", :handler => MerbHandler.new(@@merb_opts[:dist_root]+'/public')
309
- uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("")
353
+ uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("")
310
354
  end
311
355
 
312
356
  trap("INT") { stop }