merb 0.3.7 → 0.4.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.
- data/README +25 -26
- data/Rakefile +48 -36
- data/app_generators/merb/USAGE +5 -0
- data/app_generators/merb/merb_generator.rb +107 -0
- data/app_generators/merb/templates/Rakefile +99 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/controllers/application.rb +1 -1
- data/app_generators/merb/templates/app/controllers/exceptions.rb +13 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/helpers/global_helper.rb +0 -0
- data/{examples/skeleton/dist/app/mailers → app_generators/merb/templates/app/mailers/views}/layout/application.erb +0 -0
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +207 -0
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +38 -0
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +40 -0
- data/app_generators/merb/templates/app/views/layout/application.html.erb +11 -0
- data/app_generators/merb/templates/config/boot.rb +11 -0
- data/app_generators/merb/templates/config/dependencies.rb +41 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/development.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/production.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/test.rb +0 -0
- data/app_generators/merb/templates/config/merb.yml +64 -0
- data/app_generators/merb/templates/config/merb_init.rb +16 -0
- data/app_generators/merb/templates/config/plugins.yml +1 -0
- data/app_generators/merb/templates/config/router.rb +32 -0
- data/{lib/merb/core_ext/merb_array.rb → app_generators/merb/templates/config/upload.conf} +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +6 -0
- data/app_generators/merb/templates/public/stylesheets/master.css +119 -0
- data/app_generators/merb/templates/script/destroy +28 -0
- data/app_generators/merb/templates/script/generate +28 -0
- data/{examples/skeleton → app_generators/merb/templates}/script/stop_merb +0 -0
- data/app_generators/merb/templates/script/win_script.cmd +1 -0
- data/app_generators/merb/templates/spec/spec.opts +6 -0
- data/app_generators/merb/templates/spec/spec_helper.rb +10 -0
- data/app_generators/merb/templates/test/test_helper.rb +13 -0
- data/app_generators/merb_plugin/USAGE +5 -0
- data/app_generators/merb_plugin/merb_plugin_generator.rb +64 -0
- data/app_generators/merb_plugin/templates/LICENSE +20 -0
- data/app_generators/merb_plugin/templates/README +4 -0
- data/app_generators/merb_plugin/templates/Rakefile +35 -0
- data/app_generators/merb_plugin/templates/TODO +5 -0
- data/app_generators/merb_plugin/templates/merbtasks.rb +6 -0
- data/app_generators/merb_plugin/templates/sampleplugin.rb +10 -0
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +7 -0
- data/app_generators/merb_plugin/templates/spec_helper.rb +2 -0
- data/bin/merb +1 -1
- data/lib/autotest/discover.rb +3 -0
- data/lib/autotest/merb_rspec.rb +79 -0
- data/lib/merb.rb +72 -93
- data/lib/merb/{merb_abstract_controller.rb → abstract_controller.rb} +28 -5
- data/lib/merb/caching/action_cache.rb +65 -29
- data/lib/merb/caching/fragment_cache.rb +9 -4
- data/lib/merb/caching/store/file_cache.rb +22 -14
- data/lib/merb/caching/store/memory_cache.rb +26 -8
- data/lib/merb/{merb_constants.rb → constants.rb} +9 -7
- data/lib/merb/controller.rb +178 -0
- data/lib/merb/core_ext.rb +13 -11
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/{merb_class.rb → class.rb} +0 -0
- data/lib/merb/core_ext/{merb_enumerable.rb → enumerable.rb} +0 -0
- data/lib/merb/core_ext/get_args.rb +52 -0
- data/lib/merb/core_ext/{merb_hash.rb → hash.rb} +40 -11
- data/lib/merb/core_ext/{merb_inflections.rb → inflections.rb} +0 -0
- data/lib/merb/core_ext/{merb_inflector.rb → inflector.rb} +1 -1
- data/lib/merb/core_ext/{merb_kernel.rb → kernel.rb} +56 -3
- data/lib/merb/core_ext/mash.rb +88 -0
- data/lib/merb/core_ext/{merb_module.rb → module.rb} +0 -0
- data/lib/merb/core_ext/{merb_numeric.rb → numeric.rb} +0 -0
- data/lib/merb/core_ext/{merb_object.rb → object.rb} +10 -47
- data/lib/merb/core_ext/string.rb +56 -0
- data/lib/merb/core_ext/{merb_symbol.rb → symbol.rb} +0 -0
- data/lib/merb/dispatcher.rb +109 -0
- data/lib/merb/{merb_drb_server.rb → drb_server.rb} +0 -0
- data/lib/merb/erubis_ext.rb +10 -0
- data/lib/merb/exceptions.rb +173 -0
- data/lib/merb/generators/merb_app/merb_app.rb +5 -25
- data/lib/merb/generators/merb_generator_helpers.rb +317 -0
- data/lib/merb/generators/merb_plugin.rb +19 -0
- data/lib/merb/logger.rb +65 -0
- data/lib/merb/{merb_mail_controller.rb → mail_controller.rb} +102 -49
- data/lib/merb/{merb_mailer.rb → mailer.rb} +31 -27
- data/lib/merb/mixins/{basic_authentication_mixin.rb → basic_authentication.rb} +3 -3
- data/lib/merb/mixins/{controller_mixin.rb → controller.rb} +131 -112
- data/lib/merb/mixins/{erubis_capture_mixin.rb → erubis_capture.rb} +12 -21
- data/lib/merb/mixins/{form_control_mixin.rb → form_control.rb} +6 -12
- data/lib/merb/mixins/render.rb +401 -0
- data/lib/merb/mixins/responder.rb +378 -0
- data/lib/merb/mixins/{view_context_mixin.rb → view_context.rb} +65 -10
- data/lib/merb/mixins/web_controller.rb +29 -0
- data/lib/merb/{merb_handler.rb → mongrel_handler.rb} +59 -38
- data/lib/merb/part_controller.rb +19 -0
- data/lib/merb/plugins.rb +16 -0
- data/lib/merb/rack_adapter.rb +37 -0
- data/lib/merb/request.rb +421 -0
- data/lib/merb/router.rb +576 -0
- data/lib/merb/{merb_server.rb → server.rb} +275 -71
- data/lib/merb/session.rb +10 -10
- data/lib/merb/session/cookie_store.rb +125 -0
- data/lib/merb/session/{merb_mem_cache_session.rb → mem_cache_session.rb} +22 -9
- data/lib/merb/session/{merb_memory_session.rb → memory_session.rb} +15 -11
- data/lib/merb/template.rb +35 -8
- data/lib/merb/template/erubis.rb +16 -10
- data/lib/merb/template/haml.rb +33 -20
- data/lib/merb/template/markaby.rb +16 -14
- data/lib/merb/template/xml_builder.rb +8 -4
- data/lib/merb/test/{merb_fake_request.rb → fake_request.rb} +11 -5
- data/lib/merb/test/helper.rb +31 -0
- data/lib/merb/test/hpricot.rb +136 -0
- data/lib/merb/test/{merb_multipart.rb → multipart.rb} +1 -1
- data/lib/merb/test/rspec.rb +93 -0
- data/lib/merb/{merb_upload_handler.rb → upload_handler.rb} +5 -6
- data/lib/merb/{merb_upload_progress.rb → upload_progress.rb} +1 -1
- data/lib/merb/{merb_view_context.rb → view_context.rb} +27 -42
- data/lib/{merb_tasks.rb → tasks.rb} +0 -0
- data/lib/tasks/merb.rake +21 -11
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +16 -0
- data/merb_default_generators/model/templates/new_model_template.erb +5 -0
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +26 -0
- data/merb_default_generators/resource_controller/templates/controller.rb +30 -0
- data/merb_default_generators/resource_controller/templates/edit.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/helper.rb +5 -0
- data/merb_default_generators/resource_controller/templates/index.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/new.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/show.html.erb +1 -0
- data/merb_generators/controller/USAGE +5 -0
- data/merb_generators/controller/controller_generator.rb +16 -0
- data/merb_generators/controller/templates/controller.rb +8 -0
- data/merb_generators/controller/templates/helper.rb +5 -0
- data/merb_generators/controller/templates/index.html.erb +3 -0
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +60 -0
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +67 -0
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +8 -0
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +5 -0
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +5 -0
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +26 -0
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +7 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +53 -0
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +17 -0
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +9 -0
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +29 -0
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +9 -0
- metadata +172 -94
- data/examples/README_EXAMPLES +0 -10
- data/examples/skeleton/Rakefile +0 -68
- data/examples/skeleton/dist/app/views/layout/application.herb +0 -12
- data/examples/skeleton/dist/conf/database.yml +0 -23
- data/examples/skeleton/dist/conf/merb.yml +0 -57
- data/examples/skeleton/dist/conf/merb_init.rb +0 -24
- data/examples/skeleton/dist/conf/router.rb +0 -22
- data/examples/skeleton/dist/conf/upload.conf +0 -5
- data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +0 -14
- data/examples/skeleton/script/new_migration +0 -21
- data/lib/merb/core_ext/merb_string.rb +0 -18
- data/lib/merb/merb_controller.rb +0 -206
- data/lib/merb/merb_dispatcher.rb +0 -87
- data/lib/merb/merb_exceptions.rb +0 -319
- data/lib/merb/merb_part_controller.rb +0 -42
- data/lib/merb/merb_plugins.rb +0 -293
- data/lib/merb/merb_request.rb +0 -165
- data/lib/merb/merb_router.rb +0 -309
- data/lib/merb/merb_yaml_store.rb +0 -31
- data/lib/merb/mixins/render_mixin.rb +0 -283
- data/lib/merb/mixins/responder_mixin.rb +0 -159
- data/lib/merb/session/merb_ar_session.rb +0 -131
- data/lib/merb/vendor/paginator/README.txt +0 -84
- data/lib/merb/vendor/paginator/paginator.rb +0 -124
- data/lib/tasks/db.rake +0 -55
data/lib/merb/merb_dispatcher.rb
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
|
|
3
|
-
class Dispatcher
|
|
4
|
-
class << self
|
|
5
|
-
|
|
6
|
-
attr_accessor :path_prefix
|
|
7
|
-
|
|
8
|
-
def use_mutex=(val)
|
|
9
|
-
@@use_mutex = val
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
@@mutex = Mutex.new
|
|
13
|
-
@@use_mutex = ::Merb::Server.use_mutex
|
|
14
|
-
# This is where we grab the incoming request REQUEST_URI and use that in
|
|
15
|
-
# the merb RouteMatcher to determine which controller and method to run.
|
|
16
|
-
# Returns a 2 element tuple of: [controller, action]
|
|
17
|
-
def handle(request, response)
|
|
18
|
-
start = Time.now
|
|
19
|
-
|
|
20
|
-
request_uri = request.params[Merb::Const::REQUEST_URI]
|
|
21
|
-
request_uri.sub!(path_prefix, '') if path_prefix
|
|
22
|
-
route = route_path(request_uri)
|
|
23
|
-
|
|
24
|
-
allowed = route.delete(:allowed)
|
|
25
|
-
rest = route.delete(:rest)
|
|
26
|
-
namespace = route.delete(:namespace)
|
|
27
|
-
|
|
28
|
-
cont = namespace ? "#{namespace}/#{route[:controller]}" : route[:controller]
|
|
29
|
-
|
|
30
|
-
klass = resolve_controller(cont)
|
|
31
|
-
controller = klass.build(request.body, request.params, route, response)
|
|
32
|
-
|
|
33
|
-
if rest
|
|
34
|
-
method = controller.request.method
|
|
35
|
-
if allowed.keys.include?(method) && action = allowed[method]
|
|
36
|
-
controller.params[:action] = action
|
|
37
|
-
else
|
|
38
|
-
raise Merb::HTTPMethodNotAllowed.new(method, allowed)
|
|
39
|
-
end
|
|
40
|
-
else
|
|
41
|
-
action = route[:action]
|
|
42
|
-
end
|
|
43
|
-
controller._benchmarks[:setup_time] = Time.now - start
|
|
44
|
-
if @@use_mutex
|
|
45
|
-
@@mutex.synchronize {
|
|
46
|
-
controller.dispatch(action)
|
|
47
|
-
}
|
|
48
|
-
else
|
|
49
|
-
controller.dispatch(action)
|
|
50
|
-
end
|
|
51
|
-
[controller, action]
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def route_path(path)
|
|
55
|
-
path = path.sub(/\/+/, '/').sub(/\?.*$/, '')
|
|
56
|
-
path = path[0..-2] if (path[-1] == ?/) && path.size > 1
|
|
57
|
-
Merb::Router.match(path)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Take a controller class name string and reload or require the right
|
|
61
|
-
# controller file then CamelCase it and return the class object.
|
|
62
|
-
def resolve_controller(controller_name)
|
|
63
|
-
segments = controller_name.split('/').map{|s| s.snake_case}
|
|
64
|
-
path = "#{DIST_ROOT}/app/controllers/#{controller_name}.rb"
|
|
65
|
-
cnt = segments.map{|s| s.camel_case }.join('::')
|
|
66
|
-
|
|
67
|
-
if !File.exist?(path)
|
|
68
|
-
raise "Bad controller! #{cnt}"
|
|
69
|
-
end unless $TESTING
|
|
70
|
-
|
|
71
|
-
begin
|
|
72
|
-
if MERB_ENV == 'development'
|
|
73
|
-
Object.send(:remove_const, cnt) rescue nil
|
|
74
|
-
load(path)
|
|
75
|
-
end
|
|
76
|
-
return Object.full_const_get(cnt)
|
|
77
|
-
rescue RuntimeError
|
|
78
|
-
warn "Error getting instance of '#{controller_name.camel_case}': #{$!}"
|
|
79
|
-
raise $!
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
end # end class << self
|
|
84
|
-
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
end
|
data/lib/merb/merb_exceptions.rb
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
begin
|
|
2
|
-
require 'coderay'
|
|
3
|
-
rescue LoadError => ex
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
module Merb
|
|
7
|
-
|
|
8
|
-
module ControllerExceptions
|
|
9
|
-
# ControllerExceptions are a way of simplifying controller code by placing
|
|
10
|
-
# exceptional logic elsewhere. ControllerExceptions are like
|
|
11
|
-
# mini-controllers which have one action. The exception action is called
|
|
12
|
-
# to render a web page when the exception is raised. Additionally all
|
|
13
|
-
# ControllerExceptions have an HTTP status code associated with them
|
|
14
|
-
# which is given to the browser when it's action is rendered.
|
|
15
|
-
#
|
|
16
|
-
# ControllerExceptions::Base is an abstract base class, it cannot be
|
|
17
|
-
# raised. Derived from Base are many exceptions, one for each HTTP status
|
|
18
|
-
# code. EG Unauthorized (401), PaymentRequired (402), and Forbidden (403).
|
|
19
|
-
#
|
|
20
|
-
# These exceptions can be raised by your controller without any further
|
|
21
|
-
# work. For example
|
|
22
|
-
#
|
|
23
|
-
# def show
|
|
24
|
-
# product = Product.find(params[:id])
|
|
25
|
-
# raise NotFound if product.nil?
|
|
26
|
-
# [...]
|
|
27
|
-
# end
|
|
28
|
-
#
|
|
29
|
-
# By default the NotFound exception will look in for a template at
|
|
30
|
-
# app/views/exceptions/not_found.{rhtml, haml, whatevs}
|
|
31
|
-
# If the template is not found then a simple message will be sent.
|
|
32
|
-
#
|
|
33
|
-
# To extend the use of the ControllerExceptions one may derive a new
|
|
34
|
-
# exception from one of the already defined ones. Then one must add a
|
|
35
|
-
# special method called error_response which is like a controller action
|
|
36
|
-
# preparing the context for rendering a template at
|
|
37
|
-
# app/views/exceptions/my_exception_snake_cased.whatevs
|
|
38
|
-
#
|
|
39
|
-
# As an example we will create an exception called AdminAccessRequired.
|
|
40
|
-
# First we decide on what HTTP status code such an error might have.
|
|
41
|
-
# 401, Unauthorized seems to fit.
|
|
42
|
-
#
|
|
43
|
-
# class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized
|
|
44
|
-
# def error_response
|
|
45
|
-
# @tried_to_access request.uri
|
|
46
|
-
# render :layout => 'error_page'
|
|
47
|
-
# end
|
|
48
|
-
# end
|
|
49
|
-
#
|
|
50
|
-
# At app/views/exceptions/admin_access_required.rhtml we write
|
|
51
|
-
#
|
|
52
|
-
# <h1>You're not an administrator!</h1>
|
|
53
|
-
# <p>You tried to access <%= @tried_to_access %> but that URL is
|
|
54
|
-
# restricted to administrators.</p>
|
|
55
|
-
#
|
|
56
|
-
# The layout 'error_page' works like any other controller, it would be
|
|
57
|
-
# looked for at app/views/layouts
|
|
58
|
-
#
|
|
59
|
-
# TODO: if you need to pass data to your exception use a constructor.
|
|
60
|
-
class Base < StandardError
|
|
61
|
-
include Merb::RenderMixin
|
|
62
|
-
include Merb::ControllerMixin
|
|
63
|
-
include Merb::ResponderMixin
|
|
64
|
-
|
|
65
|
-
def _template_root
|
|
66
|
-
@controller._template_root
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# The filename of the exception template. usually something like
|
|
70
|
-
# views/exceptions/not_found.rhtml
|
|
71
|
-
def template_path
|
|
72
|
-
_template_root / 'exceptions' / self.class.name.snake_case.split('::').last
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def set_controller(controller)
|
|
76
|
-
@controller = controller
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def request; @controller.request; end
|
|
80
|
-
def params; @controller.params; end
|
|
81
|
-
def cookies; @controller.cookies; end
|
|
82
|
-
def headers; @controller.headers; end
|
|
83
|
-
def session; @controller.session; end
|
|
84
|
-
def response; @controller.response; end
|
|
85
|
-
|
|
86
|
-
def status
|
|
87
|
-
self.class.const_get(:STATUS)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def call_action
|
|
91
|
-
# TODO: this method is meaningless at the moment but it could call
|
|
92
|
-
# filters
|
|
93
|
-
# before filters?
|
|
94
|
-
error_response
|
|
95
|
-
# after filters?
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def error_response
|
|
99
|
-
if File.exists?(template_path)
|
|
100
|
-
render
|
|
101
|
-
else
|
|
102
|
-
"Error #{status} #{self.class.name.split('::').last}!"
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
module HTTPErrors
|
|
107
|
-
# created with:
|
|
108
|
-
# ruby -r rubygems -e "require 'mongrel'; puts Mongrel::HTTP_STATUS_CODES.keys.sort.map {|code| %Q{class #{Mongrel::HTTP_STATUS_CODES[code].gsub /[^\w]/,''} < Merb::ControllerExceptions::Base; STATUS = #{code}; end} }.join(%Q{\n})"
|
|
109
|
-
# we could do some magic here, but i think it's more instructive to just
|
|
110
|
-
# have these values copied
|
|
111
|
-
class Continue < Merb::ControllerExceptions::Base; STATUS = 100; end
|
|
112
|
-
class SwitchingProtocols < Merb::ControllerExceptions::Base; STATUS = 101; end
|
|
113
|
-
class OK < Merb::ControllerExceptions::Base; STATUS = 200; end
|
|
114
|
-
class Created < Merb::ControllerExceptions::Base; STATUS = 201; end
|
|
115
|
-
class Accepted < Merb::ControllerExceptions::Base; STATUS = 202; end
|
|
116
|
-
class NonAuthoritativeInformation < Merb::ControllerExceptions::Base; STATUS = 203; end
|
|
117
|
-
class NoContent < Merb::ControllerExceptions::Base; STATUS = 204; end
|
|
118
|
-
class ResetContent < Merb::ControllerExceptions::Base; STATUS = 205; end
|
|
119
|
-
class PartialContent < Merb::ControllerExceptions::Base; STATUS = 206; end
|
|
120
|
-
class MultipleChoices < Merb::ControllerExceptions::Base; STATUS = 300; end
|
|
121
|
-
class MovedPermanently < Merb::ControllerExceptions::Base; STATUS = 301; end
|
|
122
|
-
class MovedTemporarily < Merb::ControllerExceptions::Base; STATUS = 302; end
|
|
123
|
-
class SeeOther < Merb::ControllerExceptions::Base; STATUS = 303; end
|
|
124
|
-
class NotModified < Merb::ControllerExceptions::Base; STATUS = 304; end
|
|
125
|
-
class UseProxy < Merb::ControllerExceptions::Base; STATUS = 305; end
|
|
126
|
-
class BadRequest < Merb::ControllerExceptions::Base; STATUS = 400; end
|
|
127
|
-
class Unauthorized < Merb::ControllerExceptions::Base; STATUS = 401; end
|
|
128
|
-
class PaymentRequired < Merb::ControllerExceptions::Base; STATUS = 402; end
|
|
129
|
-
class Forbidden < Merb::ControllerExceptions::Base; STATUS = 403; end
|
|
130
|
-
class NotFound < Merb::ControllerExceptions::Base; STATUS = 404; end
|
|
131
|
-
class MethodNotAllowed < Merb::ControllerExceptions::Base; STATUS = 405; end
|
|
132
|
-
class NotAcceptable < Merb::ControllerExceptions::Base; STATUS = 406; end
|
|
133
|
-
class ProxyAuthenticationRequired < Merb::ControllerExceptions::Base; STATUS = 407; end
|
|
134
|
-
class RequestTimeout < Merb::ControllerExceptions::Base; STATUS = 408; end
|
|
135
|
-
class Conflict < Merb::ControllerExceptions::Base; STATUS = 409; end
|
|
136
|
-
class Gone < Merb::ControllerExceptions::Base; STATUS = 410; end
|
|
137
|
-
class LengthRequired < Merb::ControllerExceptions::Base; STATUS = 411; end
|
|
138
|
-
class PreconditionFailed < Merb::ControllerExceptions::Base; STATUS = 412; end
|
|
139
|
-
class RequestEntityTooLarge < Merb::ControllerExceptions::Base; STATUS = 413; end
|
|
140
|
-
class RequestURITooLarge < Merb::ControllerExceptions::Base; STATUS = 414; end
|
|
141
|
-
class UnsupportedMediaType < Merb::ControllerExceptions::Base; STATUS = 415; end
|
|
142
|
-
class InternalServerError < Merb::ControllerExceptions::Base; STATUS = 500; end
|
|
143
|
-
class NotImplemented < Merb::ControllerExceptions::Base; STATUS = 501; end
|
|
144
|
-
class BadGateway < Merb::ControllerExceptions::Base; STATUS = 502; end
|
|
145
|
-
class ServiceUnavailable < Merb::ControllerExceptions::Base; STATUS = 503; end
|
|
146
|
-
class GatewayTimeout < Merb::ControllerExceptions::Base; STATUS = 504; end
|
|
147
|
-
class HTTPVersionNotSupported < Merb::ControllerExceptions::Base; STATUS = 505; end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
include HTTPErrors
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
class MerbError < StandardError; end
|
|
154
|
-
class Noroutefound < MerbError; end
|
|
155
|
-
class MissingControllerFile < MerbError; end
|
|
156
|
-
class MerbControllerError < MerbError; end
|
|
157
|
-
class HTTPMethodNotAllowed < MerbError
|
|
158
|
-
def initialize(method, allowed)
|
|
159
|
-
super("HTTPMethodNotAllowed: #{method}\n"+ "Allowed: #{allowed.keys.join(' ')})")
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# Format exception message for browser display.
|
|
165
|
-
def self.html_exception(e)
|
|
166
|
-
if ::Merb::Server.show_error
|
|
167
|
-
ErrorResponse.new(e).out
|
|
168
|
-
else
|
|
169
|
-
IO.read(DIST_ROOT / 'public/500.html') rescue "500 Internal Server Error!"
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def self.exception(e)
|
|
174
|
-
"#{ e.message } - (#{ e.class })\n" <<
|
|
175
|
-
"#{(e.backtrace or []).join("\n")}"
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
class ErrorResponse
|
|
179
|
-
def initialize error
|
|
180
|
-
@error = error
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def out
|
|
184
|
-
error = @error
|
|
185
|
-
backtrace = @error.backtrace
|
|
186
|
-
|
|
187
|
-
colors = []
|
|
188
|
-
min = 200
|
|
189
|
-
max = 255
|
|
190
|
-
step = -((max - min) / backtrace.size).abs
|
|
191
|
-
max.step(min, step) do |color|
|
|
192
|
-
colors << color
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
backtrace.map! do |line|
|
|
196
|
-
file, lineno, meth = line.scan(/(.*?):(\d+)(?::in `(.*?)')?/).first
|
|
197
|
-
|
|
198
|
-
# When a backtrace entry doesn't have a filepath as the first field
|
|
199
|
-
# (e.g., "(haml):12" or "(eval):41:in `_haml_render'"), it'll cause
|
|
200
|
-
# a second exception to be raised, masking the first. This traps it.
|
|
201
|
-
lines = (__caller_lines__(file, lineno, 5) rescue [])
|
|
202
|
-
|
|
203
|
-
[ lines, lines.object_id.abs, file, lineno, meth ]
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
error_page(colors, error, *backtrace)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# This method offers highlighting for the sourcecode-chunks from the
|
|
210
|
-
# traceback. Just 'gem install coderay'.
|
|
211
|
-
def error_page(colors, title, *backtrace)
|
|
212
|
-
@backtrace = backtrace
|
|
213
|
-
@colors = colors
|
|
214
|
-
@title = title
|
|
215
|
-
@coderay = Object.constants.include?('CodeRay')
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
template =
|
|
219
|
-
<<-HEREDOC
|
|
220
|
-
<html>
|
|
221
|
-
<head>
|
|
222
|
-
<title><%= @title %></title>
|
|
223
|
-
<style type="text/css">
|
|
224
|
-
<!--
|
|
225
|
-
table {border:0px}
|
|
226
|
-
tr {line-height:1.3}
|
|
227
|
-
td {font-size:.8em; padding:4px}
|
|
228
|
-
h1 {font-size:2em}
|
|
229
|
-
h1, td {font-family:'courier new', 'courier', monospace}
|
|
230
|
-
td.line {color:#000; text-align:center}
|
|
231
|
-
td.method {font-weight:bold; text-align:right}
|
|
232
|
-
td.file a {color:#000}
|
|
233
|
-
td.file a:hover {color:#F00}
|
|
234
|
-
tr.clickable:hover {background:#FFA}
|
|
235
|
-
.clickable {cursor: help }
|
|
236
|
-
#title {float: left;}
|
|
237
|
-
.source
|
|
238
|
-
{
|
|
239
|
-
border:1px #000 solid;
|
|
240
|
-
margin:2px;
|
|
241
|
-
padding:8px;
|
|
242
|
-
background:#F0F0F0;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
-->
|
|
246
|
-
<% if @coderay %>
|
|
247
|
-
<%= CodeRay::Encoders[:html]::CSS.new.stylesheet %>
|
|
248
|
-
<% end %>
|
|
249
|
-
</style>
|
|
250
|
-
<script type="text/javascript">
|
|
251
|
-
$ = function(el){
|
|
252
|
-
if(el === null || el === undefined)
|
|
253
|
-
throw("Argument for $() must be a domRef/domId");
|
|
254
|
-
if( el.constructor === String )
|
|
255
|
-
el = document.getElementById(el);
|
|
256
|
-
if(el === null || !el.nodeType)
|
|
257
|
-
throw("Argument for $() not found in document tree.");
|
|
258
|
-
return el;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
var toggle = function(el){
|
|
262
|
-
el = $(el);
|
|
263
|
-
var visible = el.style.display != 'none'; // visible? boolean
|
|
264
|
-
if(visible){
|
|
265
|
-
el.style.display = 'none'; // hide
|
|
266
|
-
}else{
|
|
267
|
-
el.style.display = ''; // unhide
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
</script>
|
|
271
|
-
</head>
|
|
272
|
-
<body>
|
|
273
|
-
<div>
|
|
274
|
-
<h1><img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAJQAA/+4ADkFk\nb2JlAGTAAAAAAf/bAIQADQkJCQoJDQoKDRMMCwwTFhENDREWGhUVFhUVGhkU\nFhUVFhQZGR0fIB8dGScnKionJzk4ODg5QEBAQEBAQEBAQAEODAwOEA4RDw8R\nFA4RDhQVERISERUgFRUXFRUgKB0ZGRkZHSgjJiAgICYjLCwoKCwsNzc1NzdA\nQEBAQEBAQEBA/8AAEQgAJgAtAwEiAAIRAQMRAf/EAT8AAAEFAQEBAQEBAAAA\nAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoL\nEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVS\nwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePz\nRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAAIC\nAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLh\ncoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSF\ntJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMR\nAD8A9OVDK6xRQYa02axuEBvnB7x8Fm/W36x19HqoxmAvyswkMraHFwY2N7va\nCe/5Vy/Seu29RvdXaI2CW6EBw4OhGnZAk9Einrbuvn03Oaw1lvmCCP8ANXPW\n9Zz7shlrM9zKBLnN3Fmg1gnj8An61m14eCbAN9j4ZVWJJc5x2gQPivO3ZnUM\nXLtfY8by73sDmuHw9pPCZRPVNgdH13F+teJU51WbZpX9O4xpPEho4juug9Wr\n0vW3t9Lbv9SRt2xO7dxEL5+blW5I2W2FrdsSJJgdj4r0P1W/+Nf6Un1p9PZJ\nnf8AaPU2+P0fwThdVaLF3TlfXZvUsr63ZIpZY4Y9VDKTWwuIY5vqEe3uXFx+\nSn0XBupy9t+loqDXy1zTJLST7tefJbVDLsjLycwO9Sy/09ANQafUJP8A4IrG\nQGufXltEAjZYPA900kkeCRoXA+sHSeoTXn41xJxnB9bY3e4HRcTbVsfB2h7j\ntDWkkAT7jrPjC9FzCMfpJZU5wDGgN7wNI4HZcJdiNrvP2t+62SNg9vedxnRO\nj2WyQfZy2oOA5kbfGedF0jb8w/Uq2ra/25NcGD9F1dk6/BqrYNODY5rrve4+\n2rGpBcR3Mr0j9iVf83vscD1J3bZMep/NelM+Hsn5oqa3RG0uuf6b9j9dsCRI\n+lx4haGT9g1FgZ6nc0n/AKrSEkko/Kg7vO9XtsxzV+y6a8xjtxu+hWWwPY0f\npBMnv2XN52ZmbyLunYocCZNl1bpdENmS0wOdUkkPsT9rL6rfbf8AnJiPzvT+\nzfpPVrZ6ezb6Ttv0e26OTzC9U3uk+z88ACRu+hz8YSSR6q6P/9k=\n"/>
|
|
275
|
-
<%= @title %></h1>
|
|
276
|
-
</div>
|
|
277
|
-
|
|
278
|
-
<table class="main">
|
|
279
|
-
<thead>
|
|
280
|
-
<tr>
|
|
281
|
-
<td class="method">Method</td>
|
|
282
|
-
<td class="line">Line</td>
|
|
283
|
-
<td class="file">File</td>
|
|
284
|
-
</tr>
|
|
285
|
-
</thead>
|
|
286
|
-
<% @backtrace.each do |lines, hash, file, lineno, meth| %>
|
|
287
|
-
<tr id="line_<%= hash %>" onclick="toggle('source_<%= hash %>'); return false"; class="clickable" style="background:rgb(250,250,<%= @colors.shift %>);">
|
|
288
|
-
<td class="method"><%= meth %></td>
|
|
289
|
-
<td class="line"><%= lineno %></td>
|
|
290
|
-
<td class="file"><%= file %></td>
|
|
291
|
-
</tr>
|
|
292
|
-
<tr id="source_<%= hash %>" <%= @coderay? " class='CodeRay' " : ''%> style="display:none;">
|
|
293
|
-
<td colspan="3">
|
|
294
|
-
<div class="source">
|
|
295
|
-
<table>
|
|
296
|
-
<tr><td colspan='2'><a href='txmt://open?url=file://<%=file%>&line=<%=lineno%>'>Open in TextMate</a></td></tr>
|
|
297
|
-
<% lines.each do |llineno, lcode, lcurrent| %>
|
|
298
|
-
<tr class="source"<%= 'style="background:#faa;"' if lcurrent %>>
|
|
299
|
-
<td><%= llineno %></td>
|
|
300
|
-
<td>
|
|
301
|
-
<%= @coderay ? CodeRay.scan(lcode, :ruby).html : "<pre>\#{lcode}</pre>" %>
|
|
302
|
-
</td>
|
|
303
|
-
</tr>
|
|
304
|
-
<% end %>
|
|
305
|
-
</table>
|
|
306
|
-
</div>
|
|
307
|
-
</td>
|
|
308
|
-
</tr>
|
|
309
|
-
<% end %>
|
|
310
|
-
</table>
|
|
311
|
-
</body>
|
|
312
|
-
</html>
|
|
313
|
-
HEREDOC
|
|
314
|
-
tmpl = Erubis::MEruby.new template
|
|
315
|
-
tmpl.result(binding)
|
|
316
|
-
end
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
class PartController < AbstractController
|
|
3
|
-
self._template_root = File.expand_path(DIST_ROOT / "app/parts/views")
|
|
4
|
-
|
|
5
|
-
def initialize(web_controller)
|
|
6
|
-
@_benchmarks = {}
|
|
7
|
-
@web_controller = web_controller
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def dispatch(action=:to_s)
|
|
11
|
-
old_action = params[:action]
|
|
12
|
-
params[:action] = action
|
|
13
|
-
super(action)
|
|
14
|
-
params[:action] = old_action
|
|
15
|
-
@_body
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def request
|
|
19
|
-
@web_controller.request
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def params
|
|
23
|
-
@web_controller.params
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def cookies
|
|
27
|
-
@web_controller.cookies
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def headers
|
|
31
|
-
@web_controller.headers
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def session
|
|
35
|
-
@web_controller.session
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def response
|
|
39
|
-
@web_controller.response
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
data/lib/merb/merb_plugins.rb
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
# TODO: Find Merb app root so we aren't wantonly copying Rakefiles
|
|
2
|
-
# TODO: Figure out a good way to handle the lack of install/uninstall script
|
|
3
|
-
# TODO: Minimum versions for local gems in install
|
|
4
|
-
|
|
5
|
-
require 'yaml'
|
|
6
|
-
require 'rubygems'
|
|
7
|
-
|
|
8
|
-
module Merb
|
|
9
|
-
class PluginManager
|
|
10
|
-
|
|
11
|
-
def self.gem_name
|
|
12
|
-
@@gem_name
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.gem_spec
|
|
16
|
-
@@gem_spec
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def self.options
|
|
20
|
-
@@options
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def self.gem_name=(val)
|
|
24
|
-
@@gem_name = val
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def self.gem_spec=(val)
|
|
28
|
-
@@gem_spec = val
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.options=(val)
|
|
32
|
-
@@options = val
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# Run a particular plugin action
|
|
37
|
-
def self.action(action, gem_name = nil, opts = [])
|
|
38
|
-
@@gem_name = gem_name
|
|
39
|
-
@@options = opts.flatten
|
|
40
|
-
|
|
41
|
-
case action
|
|
42
|
-
when 'install':
|
|
43
|
-
install
|
|
44
|
-
when 'uninstall':
|
|
45
|
-
uninstall
|
|
46
|
-
when 'remove':
|
|
47
|
-
remove_from_manifest
|
|
48
|
-
when 'list':
|
|
49
|
-
list
|
|
50
|
-
when 'help'
|
|
51
|
-
help
|
|
52
|
-
when 'migrate'
|
|
53
|
-
migrate
|
|
54
|
-
when 'update'
|
|
55
|
-
raise "This hasn't been implemented yet!"
|
|
56
|
-
when 'upgrade'
|
|
57
|
-
raise "This hasn't been implemented yet!"
|
|
58
|
-
else
|
|
59
|
-
raise "Invalid action: #{action}"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Install a new plugin named +gem_name+.
|
|
64
|
-
def self.install
|
|
65
|
-
raise "Plugin already installed!" if plugin_installed?
|
|
66
|
-
|
|
67
|
-
self.gem_spec = find_locally or install_gem
|
|
68
|
-
|
|
69
|
-
run_install_script
|
|
70
|
-
copy_rakefile
|
|
71
|
-
add_to_manifest
|
|
72
|
-
rescue Exception => e
|
|
73
|
-
puts "\n!!! Plugin installation FAILED: #{e.message}\n\n"
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Check the manifest to see if the plugin is already installed in this application.
|
|
77
|
-
def self.plugin_installed?
|
|
78
|
-
with_manifest do |manifest|
|
|
79
|
-
return manifest.has_key?(gem_name)
|
|
80
|
-
end
|
|
81
|
-
rescue
|
|
82
|
-
false
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Search the local Rubygems installation for the gem.
|
|
86
|
-
def self.find_locally
|
|
87
|
-
all_installed_gems = Gem::SourceIndex.from_installed_gems
|
|
88
|
-
latest_gem_version = all_installed_gems.search(gem_name).sort_by {|x| x.version.version }.last
|
|
89
|
-
require 'pp'
|
|
90
|
-
|
|
91
|
-
if latest_gem_version
|
|
92
|
-
puts "Local gem found."
|
|
93
|
-
return latest_gem_version
|
|
94
|
-
else
|
|
95
|
-
puts "Can't find gem...installing."
|
|
96
|
-
return false
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Run the installation code in the gem.
|
|
101
|
-
def self.run_install_script
|
|
102
|
-
require "#{gem_name}/install"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Copy the Rakefile from the gem to a directory in our application.
|
|
106
|
-
def self.copy_rakefile
|
|
107
|
-
path = gem_spec.loaded_from.split(/specifications/)[0] + "gems/#{gem_name}-#{gem_spec.version.version}/"
|
|
108
|
-
|
|
109
|
-
merb_rake_file = path + "Rakefile.merb"
|
|
110
|
-
|
|
111
|
-
require 'fileutils'
|
|
112
|
-
Dir.mkdir 'plugins' if !File.exists?('plugins/')
|
|
113
|
-
FileUtils.cp merb_rake_file, "plugins/#{gem_name}.rake"
|
|
114
|
-
|
|
115
|
-
File.open('Rakefile', 'a') do |rakefile|
|
|
116
|
-
rakefile.write("\nrequire 'plugins/#{gem_name}.rake\n")
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def self.remove_rakefile
|
|
121
|
-
FileUtils.rm "plugins/#{gem_name}.rake"
|
|
122
|
-
|
|
123
|
-
File.open('Rakefile', 'r+') do |rakefile|
|
|
124
|
-
contents = rakefile.read
|
|
125
|
-
contents.gsub!("\nrequire 'plugins/#{gem_name}.rake\n", "")
|
|
126
|
-
|
|
127
|
-
rakefile.pos = 0
|
|
128
|
-
rakefile.write contents
|
|
129
|
-
rakefile.truncate rakefile.pos
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Do a gem installation since it wasn't found in the locally installed gems.
|
|
134
|
-
def self.install_gem
|
|
135
|
-
require 'rubygems/installer'
|
|
136
|
-
|
|
137
|
-
options = {
|
|
138
|
-
:domain => :both,
|
|
139
|
-
:generate_rdoc => true,
|
|
140
|
-
:generate_ri => true,
|
|
141
|
-
:force => false,
|
|
142
|
-
:test => false,
|
|
143
|
-
:wrappers => true,
|
|
144
|
-
:version => "> 0",
|
|
145
|
-
:install_dir => Gem.dir,
|
|
146
|
-
:security_policy => nil }
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
puts "Attempting local install..."
|
|
151
|
-
local_install = Gem::Installer.new(gem_name, options).install(options[:force], options[:install_dir]) rescue false
|
|
152
|
-
|
|
153
|
-
if !local_install
|
|
154
|
-
# Do remote installation
|
|
155
|
-
require 'rubygems/remote_installer'
|
|
156
|
-
|
|
157
|
-
Gem.configuration = ConfigStub.new
|
|
158
|
-
|
|
159
|
-
puts "Attempting remote installation..."
|
|
160
|
-
installer = Gem::RemoteInstaller.new(options)
|
|
161
|
-
|
|
162
|
-
@@options.each do |opt|
|
|
163
|
-
installer.sources << opt.gsub(/source=/, '') if opt.scan(/^source=/) != []
|
|
164
|
-
options[:version] = "> #{opt.gsub(/version=/, '')}" if opt.scan(/^version=/) != []
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
remote_install = installer.install(gem_name, options[:version], options[:force], options[:install_dir]) rescue false
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
if !remote_install && !local_install
|
|
171
|
-
raise "That plugin can't be found in locally or in a remote repository."
|
|
172
|
-
else
|
|
173
|
-
find_locally
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Method to open and load our manifest; yields the manifest data to whatever method calls it.
|
|
178
|
-
def self.with_manifest
|
|
179
|
-
File.open('plugins.manifest', 'r+') do |manifest_file|
|
|
180
|
-
manifest_data = YAML::load(manifest_file.read)
|
|
181
|
-
manifest_data = {} if !manifest_data.is_a?(Hash)
|
|
182
|
-
|
|
183
|
-
yield manifest_data
|
|
184
|
-
|
|
185
|
-
manifest_file.pos = 0
|
|
186
|
-
manifest_file.write manifest_data.to_yaml
|
|
187
|
-
manifest_file.truncate manifest_file.pos
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# Write our newly installed plugin to the application's manifest.
|
|
192
|
-
def self.add_to_manifest
|
|
193
|
-
with_manifest do |manifest_data|
|
|
194
|
-
manifest_data[gem_name] = {'version' => gem_spec.version.version}
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def self.uninstall
|
|
199
|
-
raise "That plugin isn't installed!" if !plugin_installed?
|
|
200
|
-
|
|
201
|
-
require "#{gem_name}/uninstall" rescue nil
|
|
202
|
-
|
|
203
|
-
remove_rakefile
|
|
204
|
-
remove_from_manifest
|
|
205
|
-
uninstall_gem
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def self.remove_from_manifest
|
|
209
|
-
with_manifest do |manifest|
|
|
210
|
-
manifest.delete(gem_name)
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def self.uninstall_gem
|
|
215
|
-
require 'rubygems/installer'
|
|
216
|
-
require 'rubygems/doc_manager'
|
|
217
|
-
|
|
218
|
-
options = {
|
|
219
|
-
:domain => :both,
|
|
220
|
-
:generate_rdoc => true,
|
|
221
|
-
:generate_ri => true,
|
|
222
|
-
:force => false,
|
|
223
|
-
:test => false,
|
|
224
|
-
:wrappers => true,
|
|
225
|
-
:version => "> 0",
|
|
226
|
-
:install_dir => Gem.dir,
|
|
227
|
-
:security_policy => nil }
|
|
228
|
-
|
|
229
|
-
Gem::Uninstaller.new(gem_name, options).uninstall
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
def self.list
|
|
233
|
-
with_manifest do |manifest_data|
|
|
234
|
-
manifest_data.each do |key, value|
|
|
235
|
-
gem_name = key
|
|
236
|
-
gem_spec = find_locally
|
|
237
|
-
puts "#{key} (#{gem_spec.version.version})"
|
|
238
|
-
puts "\t#{gem_spec.description}\n"
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def self.migrate
|
|
244
|
-
raise "This hasn't been implemented yet!"
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def self.help
|
|
248
|
-
puts """
|
|
249
|
-
Merb Plugins
|
|
250
|
-
The -P (--plugin) option fed to Merb allows you to manage plugins.
|
|
251
|
-
|
|
252
|
-
Commands
|
|
253
|
-
--------
|
|
254
|
-
install Installs a new plugin.
|
|
255
|
-
uninstall Uninstalls a plugin, removing its entry from the manifest and uninstalling the gem.
|
|
256
|
-
remove Uninstalls a plugin, removing its entry from the manifest but leaving the gem installed.
|
|
257
|
-
list Lists all installed plugins for this Merb application.
|
|
258
|
-
upgrade Upgrades a plugin to the specified version.
|
|
259
|
-
update Updates a plugin to the latest available version.
|
|
260
|
-
migrate Reads the manifest for this application, installing and updating gems as needed.
|
|
261
|
-
help Shows this help message.
|
|
262
|
-
|
|
263
|
-
"""
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
# Class to stub out the verbose flag in Rubygems user interaction lib
|
|
268
|
-
class ConfigStub
|
|
269
|
-
attr_accessor :verbose
|
|
270
|
-
|
|
271
|
-
def initialize
|
|
272
|
-
@verbose = false
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
module Gem
|
|
278
|
-
# Fixes a bug in RubyGems where the SilentProgressReporter class is
|
|
279
|
-
# inaccurately named SilentReporter. Maybe one day we'll monkeypatch this for
|
|
280
|
-
# our own purposes.
|
|
281
|
-
class SilentProgressReporter
|
|
282
|
-
attr_reader :count
|
|
283
|
-
|
|
284
|
-
def initialize(out_stream, size, initial_message)
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def updated(message)
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def done
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
end
|