merb 0.3.7 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
module Erubis
|
3
|
+
class MEruby < Erubis::Eruby
|
4
|
+
include PercentLineEnhancer
|
5
|
+
include StringBufferEnhancer
|
6
|
+
end
|
7
|
+
def self.load_yaml_file(file, binding = binding)
|
8
|
+
YAML::load(Erubis::MEruby.new(IO.read(File.expand_path(file))).result(binding))
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
begin
|
2
|
+
require 'coderay'
|
3
|
+
rescue LoadError => ex
|
4
|
+
end
|
5
|
+
|
6
|
+
module Merb
|
7
|
+
# ControllerExceptions are a way of simplifying controller code by placing
|
8
|
+
# exceptional logic back into the MVC pattern.
|
9
|
+
#
|
10
|
+
# When a ControllerException is raised within your application merb will
|
11
|
+
# attempt to re-route the request to your Exceptions controller to render
|
12
|
+
# the error in a friendly mannor.
|
13
|
+
#
|
14
|
+
# For example you might have an action in your app that raises NotFound
|
15
|
+
# if a some resource was not available
|
16
|
+
#
|
17
|
+
# def show
|
18
|
+
# product = Product.find(params[:id])
|
19
|
+
# raise NotFound if product.nil?
|
20
|
+
# [...]
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# This would halt execution of your action and re-route it over to your
|
24
|
+
# Exceptions controller which might look something like
|
25
|
+
#
|
26
|
+
# class Exceptions < Application
|
27
|
+
# def not_found
|
28
|
+
# render :layout => :none
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# As usual the not_found action will look for a template in
|
33
|
+
# app/views/exceptions/not_found.html.erb
|
34
|
+
#
|
35
|
+
# Note: All standard ControllerExceptions have an HTTP status code associated
|
36
|
+
# with them which is sent to the browser when the action it is rendered.
|
37
|
+
#
|
38
|
+
# Note: If you do not specifiy how to handle raised ControllerExceptions
|
39
|
+
# or an unhandlable exception occurs within your customised exception action
|
40
|
+
# then they will be rendered using the built-in error template
|
41
|
+
# in development mode this "built in" template will show stack-traces for
|
42
|
+
# any of the ServerError family of exceptions (you can force the stack-trace
|
43
|
+
# to display in production mode using the :exception_details config option in
|
44
|
+
# merb.yml)
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# Internal Exceptions
|
48
|
+
#
|
49
|
+
# Any other rogue errors (not ControllerExceptions) that occur during the
|
50
|
+
# execution of you app will be converted into the ControllerException
|
51
|
+
# InternalServerError, and like all ControllerExceptions can be caught
|
52
|
+
# on your Exceptions controller.
|
53
|
+
#
|
54
|
+
# InternalServerErrors return status 500, a common use for cusomizing this
|
55
|
+
# action might be to send emails to the development team, warning that their
|
56
|
+
# application have exploded. Mock example:
|
57
|
+
#
|
58
|
+
# def internal_server_error
|
59
|
+
# MySpecialMailer.deliver(
|
60
|
+
# "team@cowboys.com",
|
61
|
+
# "Exception occured at #{Time.now}",
|
62
|
+
# params[:exception])
|
63
|
+
# render :inline => 'Something is wrong, but the team are on it!'
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Note: The special param[:exception] is available in all Exception actions
|
67
|
+
# and contains the ControllerException that was raised (this is handy if
|
68
|
+
# you want to display the associated message or display more detailed info)
|
69
|
+
#
|
70
|
+
#
|
71
|
+
# Extending ControllerExceptions
|
72
|
+
#
|
73
|
+
# To extend the use of the ControllerExceptions one may extend any of the
|
74
|
+
# HTTPError classes.
|
75
|
+
#
|
76
|
+
# As an example we can create an exception called AdminAccessRequired.
|
77
|
+
#
|
78
|
+
# class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized; end
|
79
|
+
#
|
80
|
+
# Add the required action to our Exceptions controller
|
81
|
+
#
|
82
|
+
# class Exceptions < Application
|
83
|
+
# def admin_access_required
|
84
|
+
# render
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# In app/views/exceptions/admin_access_required.rhtml
|
89
|
+
#
|
90
|
+
# <h1>You're not an administrator!</h1>
|
91
|
+
# <p>You tried to access <%= @tried_to_access %> but that URL is
|
92
|
+
# restricted to administrators.</p>
|
93
|
+
#
|
94
|
+
module ControllerExceptions
|
95
|
+
class Base < StandardError
|
96
|
+
def name
|
97
|
+
self.class.to_s.snake_case.split('::').last
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class Informational < Merb::ControllerExceptions::Base; end
|
102
|
+
class Continue < Merb::ControllerExceptions::Informational; STATUS = 100; end
|
103
|
+
class SwitchingProtocols < Merb::ControllerExceptions::Informational; STATUS = 101; end
|
104
|
+
class Successful < Merb::ControllerExceptions::Base; end
|
105
|
+
class OK < Merb::ControllerExceptions::Successful; STATUS = 200; end
|
106
|
+
class Created < Merb::ControllerExceptions::Successful; STATUS = 201; end
|
107
|
+
class Accepted < Merb::ControllerExceptions::Successful; STATUS = 202; end
|
108
|
+
class NonAuthoritativeInformation < Merb::ControllerExceptions::Successful; STATUS = 203; end
|
109
|
+
class NoContent < Merb::ControllerExceptions::Successful; STATUS = 204; end
|
110
|
+
class ResetContent < Merb::ControllerExceptions::Successful; STATUS = 205; end
|
111
|
+
class PartialContent < Merb::ControllerExceptions::Successful; STATUS = 206; end
|
112
|
+
class Redirection < Merb::ControllerExceptions::Base; end
|
113
|
+
class MultipleChoices < Merb::ControllerExceptions::Redirection; STATUS = 300; end
|
114
|
+
class MovedPermanently < Merb::ControllerExceptions::Redirection; STATUS = 301; end
|
115
|
+
class MovedTemporarily < Merb::ControllerExceptions::Redirection; STATUS = 302; end
|
116
|
+
class SeeOther < Merb::ControllerExceptions::Redirection; STATUS = 303; end
|
117
|
+
class NotModified < Merb::ControllerExceptions::Redirection; STATUS = 304; end
|
118
|
+
class UseProxy < Merb::ControllerExceptions::Redirection; STATUS = 305; end
|
119
|
+
class TemporaryRedirect < Merb::ControllerExceptions::Redirection; STATUS = 307; end
|
120
|
+
class ClientError < Merb::ControllerExceptions::Base; end
|
121
|
+
class BadRequest < Merb::ControllerExceptions::ClientError; STATUS = 400; end
|
122
|
+
class Unauthorized < Merb::ControllerExceptions::ClientError; STATUS = 401; end
|
123
|
+
class PaymentRequired < Merb::ControllerExceptions::ClientError; STATUS = 402; end
|
124
|
+
class Forbidden < Merb::ControllerExceptions::ClientError; STATUS = 403; end
|
125
|
+
class NotFound < Merb::ControllerExceptions::ClientError; STATUS = 404; end
|
126
|
+
class ActionNotFound < Merb::ControllerExceptions::NotFound; end
|
127
|
+
class TemplateNotFound < Merb::ControllerExceptions::NotFound; end
|
128
|
+
class LayoutNotFound < Merb::ControllerExceptions::NotFound; end
|
129
|
+
class MethodNotAllowed < Merb::ControllerExceptions::ClientError; STATUS = 405; end
|
130
|
+
class NotAcceptable < Merb::ControllerExceptions::ClientError; STATUS = 406; end
|
131
|
+
class ProxyAuthenticationRequired < Merb::ControllerExceptions::ClientError; STATUS = 407; end
|
132
|
+
class RequestTimeout < Merb::ControllerExceptions::ClientError; STATUS = 408; end
|
133
|
+
class Conflict < Merb::ControllerExceptions::ClientError; STATUS = 409; end
|
134
|
+
class Gone < Merb::ControllerExceptions::ClientError; STATUS = 410; end
|
135
|
+
class LengthRequired < Merb::ControllerExceptions::ClientError; STATUS = 411; end
|
136
|
+
class PreconditionFailed < Merb::ControllerExceptions::ClientError; STATUS = 412; end
|
137
|
+
class RequestEntityTooLarge < Merb::ControllerExceptions::ClientError; STATUS = 413; end
|
138
|
+
class RequestURITooLarge < Merb::ControllerExceptions::ClientError; STATUS = 414; end
|
139
|
+
class UnsupportedMediaType < Merb::ControllerExceptions::ClientError; STATUS = 415; end
|
140
|
+
class RequestRangeNotSatisfiable < Merb::ControllerExceptions::ClientError; STATUS = 416; end
|
141
|
+
class ExpectationFailed < Merb::ControllerExceptions::ClientError; STATUS = 417; end
|
142
|
+
class ServerError < Merb::ControllerExceptions::Base; end
|
143
|
+
class NotImplemented < Merb::ControllerExceptions::ServerError; STATUS = 501; end
|
144
|
+
class BadGateway < Merb::ControllerExceptions::ServerError; STATUS = 502; end
|
145
|
+
class ServiceUnavailable < Merb::ControllerExceptions::ServerError; STATUS = 503; end
|
146
|
+
class GatewayTimeout < Merb::ControllerExceptions::ServerError; STATUS = 504; end
|
147
|
+
class HTTPVersionNotSupported < Merb::ControllerExceptions::ServerError; STATUS = 505; end
|
148
|
+
class InternalServerError < Merb::ControllerExceptions::ServerError; STATUS = 500
|
149
|
+
DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
|
150
|
+
|
151
|
+
def initialize(exception = nil)
|
152
|
+
@exception = exception
|
153
|
+
@coderay = CodeRay rescue nil
|
154
|
+
end
|
155
|
+
|
156
|
+
def backtrace
|
157
|
+
@exception ? @exception.backtrace : backtrace
|
158
|
+
end
|
159
|
+
|
160
|
+
def message
|
161
|
+
@exception ? @exception.message : message
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# PLEASE STOP REMOVING THIS ONE GUYS! It's used to show exceptions in the log file
|
167
|
+
# this is the second time I've had to add it back.
|
168
|
+
def self.exception(e)
|
169
|
+
"#{ e.message } - (#{ e.class })\n" <<
|
170
|
+
"#{(e.backtrace or []).join("\n")}"
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -4,33 +4,13 @@ require 'find'
|
|
4
4
|
module Merb
|
5
5
|
|
6
6
|
class AppGenerator
|
7
|
-
SKELETON_DIR = File.expand_path File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'examples/skeleton')
|
8
|
-
|
9
7
|
def self.run(path)
|
10
|
-
|
11
|
-
|
12
|
-
if File.exists? @path
|
13
|
-
STDERR.puts "ERROR: Path #{@path} already exists! Aborting!"
|
14
|
-
exit 1
|
15
|
-
end
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rubigen'
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
Find.find(@path) do |f|
|
21
|
-
FileUtils.rm_rf(f) if /\.svn$/ =~ f
|
22
|
-
end
|
23
|
-
public_path = File.expand_path(File.join(@path, "dist", "public"))
|
24
|
-
mailer_path = File.expand_path(File.join(@path, "dist", "app", "mailers"))
|
25
|
-
app_path = File.expand_path(File.join(@path, "dist", "app"))
|
26
|
-
FileUtils.mkdir_p(["#{mailer_path}/helpers",
|
27
|
-
"#{mailer_path}/views",
|
28
|
-
"#{@path}/log",
|
29
|
-
"#{app_path}/models",
|
30
|
-
"#{public_path}/javascripts",
|
31
|
-
"#{public_path}/stylesheets",
|
32
|
-
"#{public_path}/images"])
|
33
|
-
puts 'Done'
|
11
|
+
require 'rubigen/scripts/generate'
|
12
|
+
RubiGen::Base.use_application_sources!
|
13
|
+
RubiGen::Scripts::Generate.new.run([path], :generator => 'merb', :backtrace => true)
|
34
14
|
end
|
35
15
|
|
36
16
|
end
|
@@ -0,0 +1,317 @@
|
|
1
|
+
# Provides some basic generator support that is generally required in various
|
2
|
+
# Generators
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module GeneratorHelpers
|
6
|
+
|
7
|
+
class ModelGeneratorBase < RubiGen::Base
|
8
|
+
|
9
|
+
default_options :author => nil
|
10
|
+
attr_reader :name, :model_attributes
|
11
|
+
attr_accessor :model_template_name, :model_test_generator_name, :migration_generator_name
|
12
|
+
|
13
|
+
def initialize(runtime_args, runtime_options = {})
|
14
|
+
super
|
15
|
+
usage if args.empty?
|
16
|
+
@class_name = args.shift.snake_case.to_const_string
|
17
|
+
extract_options
|
18
|
+
end
|
19
|
+
|
20
|
+
def manifest
|
21
|
+
unless @class_name
|
22
|
+
puts banner
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
record do |m|
|
26
|
+
|
27
|
+
# ensure there are no other definitions of this model already defined.
|
28
|
+
m.class_collisions(@class_name)
|
29
|
+
# Ensure appropriate folder(s) exists
|
30
|
+
m.directory 'app/models'
|
31
|
+
#
|
32
|
+
model_filename = @class_name.snake_case
|
33
|
+
spec_filename = @class_name.snake_case.pluralize
|
34
|
+
table_name = spec_filename
|
35
|
+
|
36
|
+
|
37
|
+
# Create stubs
|
38
|
+
m.template model_template_name,
|
39
|
+
"app/models/#{model_filename}.rb",
|
40
|
+
:assigns => { :class_name => @class_name,
|
41
|
+
:table_attributes => model_attributes}
|
42
|
+
|
43
|
+
# Check to see if a scope has been set for which test framework to use.
|
44
|
+
# If we try to run the dependency without an :rspec or :test_unit scope an
|
45
|
+
# error will be raised.
|
46
|
+
scopes = RubiGen::Base.sources.select{ |s| s.is_a?( RubiGen::PathFilteredSource )}.first.filters
|
47
|
+
if scopes.include?(:rspec) || scopes.include?(:test_unit)
|
48
|
+
unless options[:skip_testing]
|
49
|
+
m.dependency model_test_generator_name, [@class_name]
|
50
|
+
end
|
51
|
+
else
|
52
|
+
puts "\nSelect a scope for :rspec or :test_unit in script/generate if you want to generate test stubs\n\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
unless options[:skip_migration]
|
56
|
+
m.dependency migration_generator_name,["add_model_#{spec_filename}"], :table_name => table_name, :table_attributes => model_attributes
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
def banner
|
64
|
+
<<-EOS
|
65
|
+
Creates a new model for merb
|
66
|
+
|
67
|
+
USAGE: #{$0} #{spec.name} NameOfModel [field:type field:type]
|
68
|
+
|
69
|
+
Example:
|
70
|
+
#{$0} #{spec.name} person
|
71
|
+
|
72
|
+
If you already have 3 migrations, this will create the AddModelPeople migration in
|
73
|
+
schema/migration/004_add_model_people.rb
|
74
|
+
|
75
|
+
Options:
|
76
|
+
--skip-migration will not create a migration file
|
77
|
+
|
78
|
+
EOS
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_options!(opts)
|
82
|
+
opts.separator ''
|
83
|
+
opts.separator 'Options:'
|
84
|
+
# For each option below, place the default
|
85
|
+
# at the top of the file next to "default_options"
|
86
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
87
|
+
# "Some comment about this option",
|
88
|
+
# "Default: none") { |options[:author]| }
|
89
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
90
|
+
opts.on( "--skip-migration", "Don't generate a migration for this model") { |options[:skip_migration]| }
|
91
|
+
opts.on( "--skip-testing", "Don't generate a test or spec file for this model") { |options[:skip_testing]| }
|
92
|
+
end
|
93
|
+
|
94
|
+
def extract_options
|
95
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
96
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
97
|
+
# raw instance variable value.
|
98
|
+
# @author = options[:author]
|
99
|
+
# get the attributes into a format that can be used.
|
100
|
+
attribute = Struct.new(:name, :type)
|
101
|
+
@model_attributes = args.map{ |b| b.split(":").size > 1 ? attribute.new(*b.split(":")) : nil }.compact
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class MigrationGeneratorBase < RubiGen::Base
|
106
|
+
|
107
|
+
default_options :author => nil
|
108
|
+
|
109
|
+
attr_reader :name
|
110
|
+
attr_accessor :migration_template_name
|
111
|
+
|
112
|
+
def initialize(runtime_args, runtime_options = {})
|
113
|
+
super
|
114
|
+
usage if args.empty?
|
115
|
+
@class_name = args.shift
|
116
|
+
options[:table_name] ||= runtime_options[:table_name]
|
117
|
+
extract_options
|
118
|
+
end
|
119
|
+
|
120
|
+
def manifest
|
121
|
+
unless @class_name
|
122
|
+
puts banner
|
123
|
+
exit 1
|
124
|
+
end
|
125
|
+
record do |m|
|
126
|
+
# Ensure appropriate folder(s) exists
|
127
|
+
m.directory 'schema/migrations'
|
128
|
+
|
129
|
+
# Create stubs
|
130
|
+
highest_migration = Dir[Dir.pwd+'/schema/migrations/*'].map{|f| File.basename(f) =~ /^(\d+)/; $1}.max
|
131
|
+
filename = format("%03d_%s", (highest_migration.to_i+1), @class_name.snake_case)
|
132
|
+
m.template "new_migration.erb", "schema/migrations/#{filename}.rb",
|
133
|
+
:assigns => { :class_name => @class_name,
|
134
|
+
:table_name => options[:table_name],
|
135
|
+
:table_attributes => options[:table_attributes] }
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
protected
|
141
|
+
def banner
|
142
|
+
<<-EOS
|
143
|
+
Creates a new migration for merb
|
144
|
+
|
145
|
+
USAGE: #{$0} #{spec.name} NameOfMigration [field:type field:type]
|
146
|
+
|
147
|
+
Example:
|
148
|
+
#{$0} #{spec.name} AddPeople
|
149
|
+
|
150
|
+
If you already have 3 migrations, this will create the AddPeople migration in
|
151
|
+
schema/migration/004_add_people.rb
|
152
|
+
|
153
|
+
#{$0} #{spec.name} project --table-name projects_table name:string created_at:timestamp
|
154
|
+
|
155
|
+
This will create a migration that creates a table call projects_table with these attributes:
|
156
|
+
string :name
|
157
|
+
timestamp :created_at
|
158
|
+
|
159
|
+
EOS
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_options!(opts)
|
163
|
+
opts.separator ''
|
164
|
+
opts.separator 'Options:'
|
165
|
+
# For each option below, place the default
|
166
|
+
# at the top of the file next to "default_options"
|
167
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
168
|
+
# "Some comment about this option",
|
169
|
+
# "Default: none") { |options[:author]| }
|
170
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
171
|
+
opts.on( "--table-name=\"table_name_for_migration\"",
|
172
|
+
String,
|
173
|
+
"Include a create table with the given table name"){ |options[:table_name]| }
|
174
|
+
end
|
175
|
+
|
176
|
+
def extract_options
|
177
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
178
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
179
|
+
# raw instance variable value.
|
180
|
+
# @author = options[:author]
|
181
|
+
if !options[:table_attributes]
|
182
|
+
attribute = Struct.new(:name, :type)
|
183
|
+
options[:table_attributes] = args.map{ |b| b.split(":").size == 2 ? attribute.new(*b.split(":")) : nil }.compact
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
class MerbModelTestGenerator < RubiGen::Base
|
189
|
+
|
190
|
+
default_options :author => nil
|
191
|
+
|
192
|
+
attr_reader :name, :model_test_template_name, :model_test_path_name, :model_test_file_suffix
|
193
|
+
|
194
|
+
def initialize(runtime_args, runtime_options = {})
|
195
|
+
super
|
196
|
+
usage if args.empty?
|
197
|
+
@class_name = args.shift.snake_case.to_const_string
|
198
|
+
extract_options
|
199
|
+
end
|
200
|
+
|
201
|
+
def manifest
|
202
|
+
unless @class_name
|
203
|
+
puts banner
|
204
|
+
exit 1
|
205
|
+
end
|
206
|
+
record do |m|
|
207
|
+
# ensure there are no other definitions of this model already defined.
|
208
|
+
# Ensure appropriate folder(s) exists
|
209
|
+
m.directory model_test_path_name
|
210
|
+
#
|
211
|
+
model_filename = @class_name.snake_case
|
212
|
+
|
213
|
+
# Create stubs
|
214
|
+
m.template model_test_template_name,
|
215
|
+
"#{model_test_path_name}/#{model_filename}_#{model_test_file_suffix}.rb",
|
216
|
+
:assigns => {:class_name => @class_name}
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
protected
|
221
|
+
|
222
|
+
|
223
|
+
def add_options!(opts)
|
224
|
+
# opts.separator ''
|
225
|
+
# opts.separator 'Options:'
|
226
|
+
# For each option below, place the default
|
227
|
+
# at the top of the file next to "default_options"
|
228
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
229
|
+
# "Some comment about this option",
|
230
|
+
# "Default: none") { |options[:author]| }
|
231
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
232
|
+
end
|
233
|
+
|
234
|
+
def extract_options
|
235
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
236
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
237
|
+
# raw instance variable value.
|
238
|
+
# @author = options[:author]
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Pass the following options are available to this generatrs
|
243
|
+
class ControllerGeneratorBase < RubiGen::Base
|
244
|
+
|
245
|
+
default_options :author => nil
|
246
|
+
|
247
|
+
attr_reader :name, :class_name, :file_name
|
248
|
+
|
249
|
+
def initialize(runtime_args, runtime_options = {})
|
250
|
+
super
|
251
|
+
usage if args.empty?
|
252
|
+
@name = args.shift
|
253
|
+
@class_name = @name.camel_case #.pluralize
|
254
|
+
@file_name = @name.snake_case #.pluralize
|
255
|
+
@engine = runtime_options[:engine] || "erb" # set by subclasses only
|
256
|
+
@template_actions = runtime_options[:actions] || %w[index] # Used by subclasses only
|
257
|
+
@test_generator = runtime_options[:test_stub_generator] || "merb_controller_test"
|
258
|
+
extract_options
|
259
|
+
end
|
260
|
+
|
261
|
+
def manifest
|
262
|
+
record do |m|
|
263
|
+
|
264
|
+
# ensure there are no other definitions of this model already defined.
|
265
|
+
m.class_collisions(@class_name)
|
266
|
+
|
267
|
+
m.directory "app/controllers"
|
268
|
+
m.template "controller.rb", "app/controllers/#{file_name}.rb", :assigns => {:actions => @template_actions}
|
269
|
+
|
270
|
+
m.directory "app/views/#{file_name}"
|
271
|
+
|
272
|
+
# Include templates if they exist
|
273
|
+
@template_actions.each do |the_action|
|
274
|
+
template_name = "#{the_action}.html.#{@engine}"
|
275
|
+
template_path = "/" + source_path(spec.name).split("/")[0..-2].join("/")
|
276
|
+
|
277
|
+
if File.exists?(File.join(template_path,template_name))
|
278
|
+
m.template template_name, "app/views/#{file_name}/#{template_name}"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
m.directory "app/helpers/"
|
283
|
+
m.template "helper.rb", "app/helpers/#{file_name}_helper.rb"
|
284
|
+
m.dependency @test_generator, [name], :destination => destination_root, :template_actions => @template_actions
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
protected
|
289
|
+
def banner
|
290
|
+
<<-EOS
|
291
|
+
Creates a Merb controller
|
292
|
+
|
293
|
+
USAGE: #{$0} #{spec.name} name"
|
294
|
+
EOS
|
295
|
+
end
|
296
|
+
|
297
|
+
def add_options!(opts)
|
298
|
+
# opts.separator ''
|
299
|
+
# opts.separator 'Options:'
|
300
|
+
# For each option below, place the default
|
301
|
+
# at the top of the file next to "default_options"
|
302
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
303
|
+
# "Some comment about this option",
|
304
|
+
# "Default: none") { |options[:author]| }
|
305
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
306
|
+
end
|
307
|
+
|
308
|
+
def extract_options
|
309
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
310
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
311
|
+
# raw instance variable value.
|
312
|
+
# @author = options[:author]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|
317
|
+
end
|