wycats-merb-core 0.9.8

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 (98) hide show
  1. data/CHANGELOG +992 -0
  2. data/CONTRIBUTORS +94 -0
  3. data/LICENSE +20 -0
  4. data/PUBLIC_CHANGELOG +142 -0
  5. data/README +21 -0
  6. data/Rakefile +458 -0
  7. data/TODO +0 -0
  8. data/bin/merb +11 -0
  9. data/bin/merb-specs +5 -0
  10. data/lib/merb-core.rb +598 -0
  11. data/lib/merb-core/autoload.rb +31 -0
  12. data/lib/merb-core/bootloader.rb +717 -0
  13. data/lib/merb-core/config.rb +305 -0
  14. data/lib/merb-core/constants.rb +45 -0
  15. data/lib/merb-core/controller/abstract_controller.rb +568 -0
  16. data/lib/merb-core/controller/exceptions.rb +315 -0
  17. data/lib/merb-core/controller/merb_controller.rb +256 -0
  18. data/lib/merb-core/controller/mime.rb +107 -0
  19. data/lib/merb-core/controller/mixins/authentication.rb +123 -0
  20. data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
  21. data/lib/merb-core/controller/mixins/controller.rb +319 -0
  22. data/lib/merb-core/controller/mixins/render.rb +513 -0
  23. data/lib/merb-core/controller/mixins/responder.rb +469 -0
  24. data/lib/merb-core/controller/template.rb +254 -0
  25. data/lib/merb-core/core_ext.rb +9 -0
  26. data/lib/merb-core/core_ext/hash.rb +7 -0
  27. data/lib/merb-core/core_ext/kernel.rb +340 -0
  28. data/lib/merb-core/dispatch/cookies.rb +130 -0
  29. data/lib/merb-core/dispatch/default_exception/default_exception.rb +93 -0
  30. data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +198 -0
  31. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +73 -0
  32. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +94 -0
  33. data/lib/merb-core/dispatch/dispatcher.rb +176 -0
  34. data/lib/merb-core/dispatch/request.rb +729 -0
  35. data/lib/merb-core/dispatch/router.rb +151 -0
  36. data/lib/merb-core/dispatch/router/behavior.rb +566 -0
  37. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  38. data/lib/merb-core/dispatch/router/resources.rb +191 -0
  39. data/lib/merb-core/dispatch/router/route.rb +511 -0
  40. data/lib/merb-core/dispatch/session.rb +222 -0
  41. data/lib/merb-core/dispatch/session/container.rb +74 -0
  42. data/lib/merb-core/dispatch/session/cookie.rb +173 -0
  43. data/lib/merb-core/dispatch/session/memcached.rb +68 -0
  44. data/lib/merb-core/dispatch/session/memory.rb +99 -0
  45. data/lib/merb-core/dispatch/session/store_container.rb +150 -0
  46. data/lib/merb-core/dispatch/worker.rb +28 -0
  47. data/lib/merb-core/gem_ext/erubis.rb +77 -0
  48. data/lib/merb-core/logger.rb +203 -0
  49. data/lib/merb-core/plugins.rb +67 -0
  50. data/lib/merb-core/rack.rb +25 -0
  51. data/lib/merb-core/rack/adapter.rb +44 -0
  52. data/lib/merb-core/rack/adapter/ebb.rb +25 -0
  53. data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
  54. data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
  55. data/lib/merb-core/rack/adapter/irb.rb +118 -0
  56. data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
  57. data/lib/merb-core/rack/adapter/runner.rb +28 -0
  58. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
  59. data/lib/merb-core/rack/adapter/thin.rb +39 -0
  60. data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
  61. data/lib/merb-core/rack/adapter/webrick.rb +36 -0
  62. data/lib/merb-core/rack/application.rb +32 -0
  63. data/lib/merb-core/rack/handler/mongrel.rb +97 -0
  64. data/lib/merb-core/rack/middleware.rb +20 -0
  65. data/lib/merb-core/rack/middleware/conditional_get.rb +29 -0
  66. data/lib/merb-core/rack/middleware/content_length.rb +18 -0
  67. data/lib/merb-core/rack/middleware/csrf.rb +73 -0
  68. data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
  69. data/lib/merb-core/rack/middleware/profiler.rb +19 -0
  70. data/lib/merb-core/rack/middleware/static.rb +45 -0
  71. data/lib/merb-core/rack/middleware/tracer.rb +20 -0
  72. data/lib/merb-core/server.rb +284 -0
  73. data/lib/merb-core/tasks/audit.rake +68 -0
  74. data/lib/merb-core/tasks/gem_management.rb +229 -0
  75. data/lib/merb-core/tasks/merb.rb +1 -0
  76. data/lib/merb-core/tasks/merb_rake_helper.rb +80 -0
  77. data/lib/merb-core/tasks/stats.rake +71 -0
  78. data/lib/merb-core/test.rb +11 -0
  79. data/lib/merb-core/test/helpers.rb +9 -0
  80. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  81. data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
  82. data/lib/merb-core/test/helpers/request_helper.rb +393 -0
  83. data/lib/merb-core/test/helpers/route_helper.rb +39 -0
  84. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  85. data/lib/merb-core/test/matchers.rb +9 -0
  86. data/lib/merb-core/test/matchers/controller_matchers.rb +351 -0
  87. data/lib/merb-core/test/matchers/route_matchers.rb +137 -0
  88. data/lib/merb-core/test/matchers/view_matchers.rb +375 -0
  89. data/lib/merb-core/test/run_specs.rb +49 -0
  90. data/lib/merb-core/test/tasks/spectasks.rb +68 -0
  91. data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
  92. data/lib/merb-core/test/test_ext/object.rb +14 -0
  93. data/lib/merb-core/test/test_ext/string.rb +14 -0
  94. data/lib/merb-core/vendor/facets.rb +2 -0
  95. data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
  96. data/lib/merb-core/vendor/facets/inflect.rb +342 -0
  97. data/lib/merb-core/version.rb +3 -0
  98. metadata +253 -0
@@ -0,0 +1,67 @@
1
+ module Merb
2
+
3
+ module Plugins
4
+
5
+ # ==== Returns
6
+ # Hash::
7
+ # The configuration loaded from Merb.root / "config/plugins.yml" or, if
8
+ # the load fails, an empty hash whose default value is another Hash.
9
+ def self.config
10
+ @config ||= begin
11
+ # this is so you can do Merb.plugins.config[:helpers][:awesome] = "bar"
12
+ config_hash = Hash.new {|h,k| h[k] = {}}
13
+ file = Merb.root / "config" / "plugins.yml"
14
+
15
+ if File.exists?(file)
16
+ require 'yaml'
17
+ to_merge = YAML.load_file(file)
18
+ else
19
+ to_merge = {}
20
+ end
21
+
22
+ config_hash.merge(to_merge)
23
+ end
24
+ end
25
+
26
+ # ==== Returns
27
+ # Array(String):: All Rakefile load paths Merb uses for plugins.
28
+ def self.rakefiles
29
+ Merb.rakefiles
30
+ end
31
+
32
+ # ==== Returns
33
+ # Array(String):: All Generator load paths Merb uses for plugins.
34
+ def self.generators
35
+ Merb.generators
36
+ end
37
+
38
+ # ==== Parameters
39
+ # *rakefiles:: Rakefiles to add to the list of plugin Rakefiles.
40
+ #
41
+ # ==== Notes
42
+ #
43
+ # This is a recommended way to register your plugin's Raketasks
44
+ # in Merb.
45
+ #
46
+ # ==== Examples
47
+ # From merb_sequel plugin:
48
+ #
49
+ # if defined(Merb::Plugins)
50
+ # Merb::Plugins.add_rakefiles "merb_sequel" / "merbtasks"
51
+ # end
52
+ def self.add_rakefiles(*rakefiles)
53
+ Merb.add_rakefiles(*rakefiles)
54
+ end
55
+
56
+ # ==== Parameters
57
+ # *generators:: Generator paths to add to the list of plugin generators.
58
+ #
59
+ # ==== Notes
60
+ #
61
+ # This is the recommended way to register your plugin's generators
62
+ # in Merb.
63
+ def self.add_generators(*generators)
64
+ Merb.add_generators(*generators)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ require 'rack'
2
+ module Merb
3
+ module Rack
4
+ autoload :Application, 'merb-core/rack/application'
5
+ autoload :Adapter, 'merb-core/rack/adapter'
6
+ autoload :Ebb, 'merb-core/rack/adapter/ebb'
7
+ autoload :EventedMongrel, 'merb-core/rack/adapter/evented_mongrel'
8
+ autoload :FastCGI, 'merb-core/rack/adapter/fcgi'
9
+ autoload :Irb, 'merb-core/rack/adapter/irb'
10
+ autoload :Middleware, 'merb-core/rack/middleware'
11
+ autoload :Mongrel, 'merb-core/rack/adapter/mongrel'
12
+ autoload :Runner, 'merb-core/rack/adapter/runner'
13
+ autoload :SwiftipliedMongrel, 'merb-core/rack/adapter/swiftiplied_mongrel'
14
+ autoload :Thin, 'merb-core/rack/adapter/thin'
15
+ autoload :ThinTurbo, 'merb-core/rack/adapter/thin_turbo'
16
+ autoload :WEBrick, 'merb-core/rack/adapter/webrick'
17
+ autoload :PathPrefix, 'merb-core/rack/middleware/path_prefix'
18
+ autoload :Static, 'merb-core/rack/middleware/static'
19
+ autoload :Profiler, 'merb-core/rack/middleware/profiler'
20
+ autoload :Tracer, 'merb-core/rack/middleware/tracer'
21
+ autoload :ContentLength, 'merb-core/rack/middleware/content_length'
22
+ autoload :ConditionalGet, 'merb-core/rack/middleware/conditional_get'
23
+ autoload :Csrf, 'merb-core/rack/middleware/csrf'
24
+ end # Rack
25
+ end # Merb
@@ -0,0 +1,44 @@
1
+ module Merb
2
+
3
+ module Rack
4
+
5
+ class Adapter
6
+
7
+ class << self
8
+ # ==== Parameters
9
+ # id<String>:: The identifier of the Rack adapter class to retrieve.
10
+ #
11
+ # ==== Returns.
12
+ # Class:: The adapter class.
13
+ def get(id)
14
+ Object.full_const_get(@adapters[id])
15
+ end
16
+
17
+ # Registers a new Rack adapter.
18
+ #
19
+ # ==== Parameters
20
+ # ids<Array>:: Identifiers by which this adapter is recognized by.
21
+ # adapter_class<Class>:: The Rack adapter class.
22
+ def register(ids, adapter_class)
23
+ @adapters ||= Hash.new
24
+ ids.each { |id| @adapters[id] = "Merb::Rack::#{adapter_class}" }
25
+ end
26
+ end # class << self
27
+
28
+ end # Adapter
29
+
30
+ # Register some Rack adapters
31
+ Adapter.register %w{ebb}, :Ebb
32
+ Adapter.register %w{emongrel}, :EventedMongrel
33
+ Adapter.register %w{fastcgi fcgi}, :FastCGI
34
+ Adapter.register %w{irb}, :Irb
35
+ Adapter.register %w{mongrel}, :Mongrel
36
+ Adapter.register %w{runner}, :Runner
37
+ Adapter.register %w{smongrel swift}, :SwiftipliedMongrel
38
+ Adapter.register %w{thin}, :Thin
39
+ Adapter.register %w{thin-turbo}, :ThinTurbo
40
+ Adapter.register %w{webrick}, :WEBrick
41
+
42
+ end # Rack
43
+ end # Merb
44
+
@@ -0,0 +1,25 @@
1
+ require 'ebb'
2
+ module Merb
3
+
4
+ module Rack
5
+
6
+ class Ebb
7
+ # start an Ebb server on given host and port.
8
+
9
+ # ==== Parameters
10
+ # opts<Hash>:: Options for Ebb (see below).
11
+ #
12
+ # ==== Options (opts)
13
+ # :host<String>:: The hostname that Ebb should serve.
14
+ # :port<Fixnum>:: The port Ebb should bind to.
15
+ # :app:: The application
16
+ def self.start(opts={})
17
+ Merb.logger.warn!("Using Ebb adapter")
18
+ Merb::Dispatcher.use_mutex = false
19
+ th = Thread.new { ::Ebb.start_server(opts[:app], opts) }
20
+ Merb::Server.change_privilege
21
+ th.join
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ require 'swiftcore/evented_mongrel'
2
+ require 'merb-core/rack/handler/mongrel'
3
+ module Merb
4
+ module Rack
5
+
6
+ class EventedMongrel < Mongrel
7
+ # Starts Mongrel as evented.
8
+ #
9
+ # ==== Parameters
10
+ # opts<Hash>:: Options for Mongrel (see below).
11
+ #
12
+ # ==== Options (opts)
13
+ # :host<String>:: The hostname that Mongrel should serve.
14
+ # :port<Fixnum>:: The port Mongrel should bind to.
15
+ # :app<String>>:: The application name.
16
+ def self.start(opts={})
17
+ Merb.logger.warn!("Using EventedMongrel adapter")
18
+ Merb::Dispatcher.use_mutex = false
19
+ server = ::Mongrel::HttpServer.new(opts[:host], opts[:port].to_i)
20
+ Merb::Server.change_privilege
21
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(opts[:app]))
22
+ server.run.join
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Merb
2
+ module Rack
3
+
4
+ class FastCGI
5
+ # ==== Parameters
6
+ # opts<Hash>:: Options for FastCGI (see below).
7
+ #
8
+ # ==== Options (opts)
9
+ # :app<String>>:: The application name.
10
+ def self.start(opts={})
11
+ Merb.logger.warn!("Using FastCGI adapter")
12
+ Merb::Server.change_privilege
13
+ ::Rack::Handler::FastCGI.run(opts[:app], opts)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,118 @@
1
+ module Merb
2
+ module Rack
3
+ class Console
4
+ # ==== Parameters
5
+ # name<~to_sym, Hash>:: The name of the route to generate.
6
+ # params<Hash>:: The params to use in the route generation.
7
+ #
8
+ # ==== Returns
9
+ # String:: The generated URL.
10
+ #
11
+ # ==== Alternatives
12
+ # If name is a hash, it will be merged with params.
13
+ def url(name, params={})
14
+ Merb::Router.generate(name, params)
15
+ end
16
+
17
+ # Reloads classes using Merb::BootLoader::ReloadClasses.
18
+ def reload!
19
+ Merb::BootLoader::ReloadClasses.reload
20
+ end
21
+
22
+ # Prints all routes for the application.
23
+ def show_routes
24
+ seen = []
25
+ unless Merb::Router.named_routes.empty?
26
+ puts "==== Named routes"
27
+ Merb::Router.named_routes.each do |name,route|
28
+ # something weird happens when you combine sprintf and irb
29
+ puts "Helper : #{name}"
30
+ meth = $1.upcase if route.conditions[:method].to_s =~ /(get|post|put|delete)/
31
+ puts "HTTP method: #{meth || 'GET'}"
32
+ puts "Route : #{route}"
33
+ puts "Params : #{route.params.inspect}"
34
+ puts
35
+ seen << route
36
+ end
37
+ end
38
+ puts "==== Anonymous routes"
39
+ (Merb::Router.routes - seen).each do |route|
40
+ meth = $1.upcase if route.conditions[:method].to_s =~ /(get|post|put|delete)/
41
+ puts "HTTP method: #{meth || 'GET'}"
42
+ puts "Route : #{route}"
43
+ puts "Params : #{route.params.inspect}"
44
+ puts
45
+ end
46
+ nil
47
+ end
48
+
49
+ # Starts a sandboxed session (delegates to any Merb::Orms::* modules).
50
+ #
51
+ # An ORM should implement Merb::Orms::MyOrm#open_sandbox! to support this.
52
+ # Usually this involves starting a transaction.
53
+ def open_sandbox!
54
+ puts "Loading #{Merb.environment} environment in sandbox (Merb #{Merb::VERSION})"
55
+ puts "Any modifications you make will be rolled back on exit"
56
+ orm_modules.each { |orm| orm.open_sandbox! if orm.respond_to?(:open_sandbox!) }
57
+ end
58
+
59
+ # Ends a sandboxed session (delegates to any Merb::Orms::* modules).
60
+ #
61
+ # An ORM should implement Merb::Orms::MyOrm#close_sandbox! to support this.
62
+ # Usually this involves rolling back a transaction.
63
+ def close_sandbox!
64
+ orm_modules.each { |orm| orm.close_sandbox! if orm.respond_to?(:close_sandbox!) }
65
+ puts "Modifications have been rolled back"
66
+ end
67
+
68
+ # Explictly show logger output during IRB session
69
+ def trace_log!
70
+ Merb.logger.auto_flush = true
71
+ end
72
+
73
+ private
74
+
75
+ # ==== Returns
76
+ # Array:: All Merb::Orms::* modules.
77
+ def orm_modules
78
+ if Merb.const_defined?('Orms')
79
+ Merb::Orms.constants.map { |c| Merb::Orms::const_get(c) }
80
+ else
81
+ []
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ class Irb
88
+ # ==== Parameters
89
+ # opts<Hash>:
90
+ # Options for IRB. Currently this is not used by the IRB adapter.
91
+ #
92
+ # ==== Notes
93
+ # If the +.irbrc+ file exists, it will be loaded into the IRBRC
94
+ # environment variable.
95
+ def self.start(opts={})
96
+ m = Merb::Rack::Console.new
97
+ m.extend Merb::Test::RequestHelper
98
+ Object.send(:define_method, :merb) { m }
99
+ ARGV.clear # Avoid passing args to IRB
100
+ m.open_sandbox! if sandboxed?
101
+ require 'irb'
102
+ require 'irb/completion'
103
+ if File.exists? ".irbrc"
104
+ ENV['IRBRC'] = ".irbrc"
105
+ end
106
+ IRB.start
107
+ at_exit do merb.close_sandbox! if sandboxed? end
108
+ exit
109
+ end
110
+
111
+ private
112
+
113
+ def self.sandboxed?
114
+ Merb::Config[:sandbox]
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,26 @@
1
+ require 'mongrel'
2
+ require 'merb-core/rack/handler/mongrel'
3
+ module Merb
4
+
5
+ module Rack
6
+
7
+ class Mongrel
8
+ # start server on given host and port.
9
+
10
+ # ==== Parameters
11
+ # opts<Hash>:: Options for Mongrel (see below).
12
+ #
13
+ # ==== Options (opts)
14
+ # :host<String>:: The hostname that Mongrel should serve.
15
+ # :port<Fixnum>:: The port Mongrel should bind to.
16
+ # :app<String>>:: The application name.
17
+ def self.start(opts={})
18
+ Merb.logger.warn!("Using Mongrel adapter")
19
+ server = ::Mongrel::HttpServer.new(opts[:host], opts[:port].to_i)
20
+ Merb::Server.change_privilege
21
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(opts[:app]))
22
+ server.run.join
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ module Merb
2
+
3
+ module Rack
4
+
5
+ class Runner
6
+ # ==== Parameters
7
+ # opts<Hash>:: Options for the runner (see below).
8
+ #
9
+ # ==== Options (opts)
10
+ # :runner_code<String>:: The code to run.
11
+ #
12
+ # ==== Notes
13
+ # If opts[:runner_code] matches a filename, that file will be read and
14
+ # the contents executed. Otherwise the code will be executed directly.
15
+ def self.start(opts={})
16
+ Merb::Server.change_privilege
17
+ if opts[:runner_code]
18
+ if File.exists?(opts[:runner_code])
19
+ eval(File.read(opts[:runner_code]), TOPLEVEL_BINDING, __FILE__, __LINE__)
20
+ else
21
+ eval(opts[:runner_code], TOPLEVEL_BINDING, __FILE__, __LINE__)
22
+ end
23
+ exit
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ require 'swiftcore/swiftiplied_mongrel'
2
+ require 'merb-core/rack/handler/mongrel'
3
+ module Merb
4
+ module Rack
5
+
6
+ class SwiftipliedMongrel < Mongrel
7
+ # Starts Mongrel as swift.
8
+ #
9
+ # ==== Parameters
10
+ # opts<Hash>:: Options for Mongrel (see below).
11
+ #
12
+ # ==== Options (opts)
13
+ # :host<String>:: The hostname that Mongrel should serve.
14
+ # :port<Fixnum>:: The port Mongrel should bind to.
15
+ # :app<String>>:: The application name.
16
+ def self.start(opts={})
17
+ Merb.logger.warn!("Using SwiftipliedMongrel adapter")
18
+ Merb::Dispatcher.use_mutex = false
19
+ server = ::Mongrel::HttpServer.new(opts[:host], opts[:port].to_i)
20
+ Merb::Server.change_privilege
21
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(opts[:app]))
22
+ server.run.join
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require "thin"
2
+
3
+ module Merb
4
+
5
+ module Rack
6
+
7
+ class Thin
8
+ # start a Thin server on given host and port.
9
+
10
+ # ==== Parameters
11
+ # opts<Hash>:: Options for Thin (see below).
12
+ #
13
+ # ==== Options (opts)
14
+ # :host<String>:: The hostname that Thin should serve.
15
+ # :port<Fixnum>:: The port Thin should bind to.
16
+ # :socket<Fixnum>>:: The socket number that thin should bind to.
17
+ # :socket_file<String>>:: The socket file that thin should attach to.
18
+ # :app<String>>:: The application name.
19
+ def self.start(opts={})
20
+ Merb::Dispatcher.use_mutex = false
21
+ if opts[:socket] || opts[:socket_file]
22
+ socket = opts[:socket] || "0"
23
+ socket_file = opts[:socket_file] || "#{Merb.root}/log/merb.#{socket}.sock"
24
+ Merb.logger.warn!("Using Thin adapter with socket file #{socket_file}.")
25
+ server = ::Thin::Server.new(socket_file, opts[:app], opts)
26
+ else
27
+ Merb.logger.warn!("Using Thin adapter on host #{opts[:host]} and port #{opts[:port]}.")
28
+ if opts[:host].include?('/')
29
+ opts[:host] = "#{opts[:host]}-#{opts[:port]}"
30
+ end
31
+ server = ::Thin::Server.new(opts[:host], opts[:port].to_i, opts[:app], opts)
32
+ end
33
+ Merb::Server.change_privilege
34
+ ::Thin::Logging.silent = true
35
+ server.start
36
+ end
37
+ end
38
+ end
39
+ end