mack 0.0.3
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 +43 -0
- data/bin/mack +60 -0
- data/bin/templates/Rakefile.template +6 -0
- data/bin/templates/app/controllers/default_controller.rb.template +7 -0
- data/bin/templates/app/helpers/application_helper.rb.template +2 -0
- data/bin/templates/app/views/default/index.html.erb.template +3 -0
- data/bin/templates/app/views/layouts/application.html.erb.template +15 -0
- data/bin/templates/config/app_config/default.yml.template +7 -0
- data/bin/templates/config/app_config/development.yml.template +0 -0
- data/bin/templates/config/app_config/production.yml.template +0 -0
- data/bin/templates/config/app_config/test.yml.template +0 -0
- data/bin/templates/config/boot.rb.template +6 -0
- data/bin/templates/config/database.yml.template +20 -0
- data/bin/templates/config/routes.rb.template +7 -0
- data/bin/templates/config/thin.ru.template +1 -0
- data/bin/templates/config/thin.yml.template +8 -0
- data/bin/templates/public/favicon.ico +0 -0
- data/bin/templates/public/stylesheets/scaffold.css.template +74 -0
- data/core_extensions/hash.rb +9 -0
- data/core_extensions/module.rb +29 -0
- data/core_extensions/nil.rb +8 -0
- data/core_extensions/object.rb +9 -0
- data/core_extensions/string.rb +28 -0
- data/errors/errors.rb +79 -0
- data/initialize/configuration.rb +99 -0
- data/initialize/configure_logging.rb +24 -0
- data/initialize/configure_orm_support.rb +23 -0
- data/initialize/console.rb +13 -0
- data/initialize/initializer.rb +88 -0
- data/initialize/server/simple_server.rb +21 -0
- data/lib/utils/html.rb +88 -0
- data/lib/utils/server.rb +27 -0
- data/mack.rb +124 -0
- data/mack_tasks.rb +16 -0
- data/routing/route_map.rb +268 -0
- data/routing/urls.rb +54 -0
- data/sea_level/controller_base.rb +293 -0
- data/sea_level/cookie_jar.rb +67 -0
- data/sea_level/filter.rb +63 -0
- data/sea_level/helpers/view_helpers/html_helpers.rb +33 -0
- data/sea_level/helpers/view_helpers/orm_helpers.rb +72 -0
- data/sea_level/request.rb +83 -0
- data/sea_level/response.rb +6 -0
- data/sea_level/session.rb +33 -0
- data/sea_level/view_binder.rb +101 -0
- data/tasks/cachetastic_tasks.rake +69 -0
- data/tasks/log_tasks.rake +9 -0
- data/tasks/mack_tasks.rake +15 -0
- data/tasks/rake_helpers.rb +24 -0
- data/tasks/rake_rules.rake +19 -0
- data/tasks/script_tasks.rake +44 -0
- data/tasks/test_tasks.rake +7 -0
- data/test_extensions/test_assertions.rb +47 -0
- data/test_extensions/test_helpers.rb +84 -0
- metadata +173 -0
data/README
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
=Hello, and welcome to Mack!
|
2
|
+
|
3
|
+
Mack is a Ruby web application framework. It takes the best ideas from several frameworks, including Rails, Merb, and Ramaze, and tries to improve upon those ideas. Mack uses Rack[http://rack.rubyforge.org] as an abstraction layer to separate itself from it's deployment.
|
4
|
+
|
5
|
+
Mack is also about performance. Because Mack uses technologies like Thin[http://code.macournoyer.com/thin] and Rack[http://rack.rubyforge.org], Mack is a multithreaded and fast framework. Current tests show Mack/Thin[http://code.macournoyer.com/thin] is twice as fast as Rails/Mongrel. Mack tries to strip out a lot of the cruft from other frameworks, like Rails, and delivers you a fast, efficient framework designed for actual real world development.
|
6
|
+
|
7
|
+
===Required gems:
|
8
|
+
rack
|
9
|
+
ruby_extensions
|
10
|
+
application_configuration
|
11
|
+
cachetastic
|
12
|
+
log4r
|
13
|
+
|
14
|
+
===Optional gems:
|
15
|
+
mongrel
|
16
|
+
thin
|
17
|
+
activerecord
|
18
|
+
datamapper
|
19
|
+
|
20
|
+
To run a Mack application:
|
21
|
+
$ rake script:server
|
22
|
+
|
23
|
+
It will try and run the app using the following servers in this order:
|
24
|
+
* Thin
|
25
|
+
* Mongrel
|
26
|
+
* WEBrick
|
27
|
+
|
28
|
+
rake script:server takes the following options:
|
29
|
+
$ rake script:server PORT=<port> MACK_ENV=<environment> HANDLER=<rack_handler>
|
30
|
+
|
31
|
+
The port and rack_handler flags don't apply if you're using Thin[http://code.macournoyer.com/thin] to run the app, which is the default if it is installed. Use the thin.yml file in your application's config directory to configure Thin. The rack_handler one will allow you to switch which server is used to run the app. See Rack for more Rack::Handlers.
|
32
|
+
|
33
|
+
The environment can also be changed like this:
|
34
|
+
$ rake script:server#<environment>
|
35
|
+
|
36
|
+
You can also run:
|
37
|
+
$ rake console
|
38
|
+
This will give you console level access to your application.
|
39
|
+
|
40
|
+
|
41
|
+
===Other documentation:
|
42
|
+
Thin[http://code.macournoyer.com/thin]
|
43
|
+
Rack[http://rack.rubyforge.org]
|
data/bin/mack
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'optparse'
|
3
|
+
require 'optparse/time'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'pp'
|
6
|
+
require 'erb'
|
7
|
+
|
8
|
+
app = ARGV[0]
|
9
|
+
raise "You must specify a name for this application!" if app.nil?
|
10
|
+
|
11
|
+
options = OpenStruct.new
|
12
|
+
options.orm = false
|
13
|
+
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
|
16
|
+
opts.on("-o [ORM]") do |v|
|
17
|
+
options.orm = v
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.parse!(ARGV)
|
23
|
+
|
24
|
+
include FileUtils
|
25
|
+
|
26
|
+
def create_dir(dir)
|
27
|
+
mkdir_p(dir)
|
28
|
+
puts "Created: #{dir}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create directories:
|
32
|
+
create_dir(File.join(app, "app", "controllers"))
|
33
|
+
create_dir(File.join(app, "app", "helpers"))
|
34
|
+
create_dir(File.join(app, "app", "models"))
|
35
|
+
create_dir(File.join(app, "app", "views", "default"))
|
36
|
+
create_dir(File.join(app, "app", "views", "layouts"))
|
37
|
+
create_dir(File.join(app, "config", "app_config"))
|
38
|
+
create_dir(File.join(app, "lib", "tasks"))
|
39
|
+
create_dir(File.join(app, "log"))
|
40
|
+
create_dir(File.join(app, "public", "images"))
|
41
|
+
create_dir(File.join(app, "public", "stylesheets"))
|
42
|
+
create_dir(File.join(app, "public", "javascripts"))
|
43
|
+
create_dir(File.join(app, "test", "unit"))
|
44
|
+
create_dir(File.join(app, "test", "functional"))
|
45
|
+
create_dir(File.join(app, "vendor", "plugins"))
|
46
|
+
|
47
|
+
# Copy over templates:
|
48
|
+
erb_files = Dir.glob(File.join(File.dirname(__FILE__), "templates", "**/*.template"))
|
49
|
+
|
50
|
+
erb_files.each do |fl|
|
51
|
+
if fl.match("database.yml") && !options.orm
|
52
|
+
else
|
53
|
+
res = ERB.new(File.open(fl).read).result(binding)
|
54
|
+
n = fl.gsub(File.join(File.dirname(__FILE__), "templates"), app).gsub(".template", "")
|
55
|
+
File.open(n, "w") {|f| f.puts res}
|
56
|
+
puts "Created: #{n}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
cp(File.join(File.dirname(__FILE__), "templates", "public", "favicon.ico"), File.join(app, "public", "favicon.ico"))
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
+
<title><%%= controller.controller_name %>: <%%= controller.action_name %></title>
|
8
|
+
<link href="/stylesheets/scaffold.css" media="screen" rel="stylesheet" type="text/css" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
|
12
|
+
<%%= @content_for_layout %>
|
13
|
+
|
14
|
+
</body>
|
15
|
+
</html>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
development:
|
2
|
+
adapter: mysql
|
3
|
+
database: <%= app.downcase %>_development
|
4
|
+
host: localhost
|
5
|
+
username: root
|
6
|
+
password:
|
7
|
+
|
8
|
+
test:
|
9
|
+
adapter: mysql
|
10
|
+
database: <%= app.downcase %>_test
|
11
|
+
host: localhost
|
12
|
+
username: root
|
13
|
+
password:
|
14
|
+
|
15
|
+
production:
|
16
|
+
adapter: mysql
|
17
|
+
database: <%= app.downcase %>_development
|
18
|
+
host: localhost
|
19
|
+
username: root
|
20
|
+
password:
|
@@ -0,0 +1 @@
|
|
1
|
+
run Mack::Utils::Server.build_app
|
Binary file
|
@@ -0,0 +1,74 @@
|
|
1
|
+
body { background-color: #fff; color: #333; }
|
2
|
+
|
3
|
+
body, p, ol, ul, td {
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
+
font-size: 13px;
|
6
|
+
line-height: 18px;
|
7
|
+
}
|
8
|
+
|
9
|
+
pre {
|
10
|
+
background-color: #eee;
|
11
|
+
padding: 10px;
|
12
|
+
font-size: 11px;
|
13
|
+
}
|
14
|
+
|
15
|
+
a { color: #000; }
|
16
|
+
a:visited { color: #666; }
|
17
|
+
a:hover { color: #fff; background-color:#000; }
|
18
|
+
|
19
|
+
.fieldWithErrors {
|
20
|
+
padding: 2px;
|
21
|
+
background-color: red;
|
22
|
+
display: table;
|
23
|
+
}
|
24
|
+
|
25
|
+
#errorExplanation {
|
26
|
+
width: 400px;
|
27
|
+
border: 2px solid red;
|
28
|
+
padding: 7px;
|
29
|
+
padding-bottom: 12px;
|
30
|
+
margin-bottom: 20px;
|
31
|
+
background-color: #f0f0f0;
|
32
|
+
}
|
33
|
+
|
34
|
+
#errorExplanation h2 {
|
35
|
+
text-align: left;
|
36
|
+
font-weight: bold;
|
37
|
+
padding: 5px 5px 5px 15px;
|
38
|
+
font-size: 12px;
|
39
|
+
margin: -7px;
|
40
|
+
background-color: #c00;
|
41
|
+
color: #fff;
|
42
|
+
}
|
43
|
+
|
44
|
+
#errorExplanation p {
|
45
|
+
color: #333;
|
46
|
+
margin-bottom: 0;
|
47
|
+
padding: 5px;
|
48
|
+
}
|
49
|
+
|
50
|
+
#errorExplanation ul li {
|
51
|
+
font-size: 12px;
|
52
|
+
list-style: square;
|
53
|
+
}
|
54
|
+
|
55
|
+
div.uploadStatus {
|
56
|
+
margin: 5px;
|
57
|
+
}
|
58
|
+
|
59
|
+
div.progressBar {
|
60
|
+
margin: 5px;
|
61
|
+
}
|
62
|
+
|
63
|
+
div.progressBar div.border {
|
64
|
+
background-color: #fff;
|
65
|
+
border: 1px solid gray;
|
66
|
+
width: 100%;
|
67
|
+
}
|
68
|
+
|
69
|
+
div.progressBar div.background {
|
70
|
+
background-color: #333;
|
71
|
+
height: 18px;
|
72
|
+
width: 0%;
|
73
|
+
}
|
74
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Module
|
2
|
+
|
3
|
+
# Bulk converts the security level of methods in this Module from one level to another.
|
4
|
+
def convert_security_of_methods(old_level = :public, new_level = :protected)
|
5
|
+
eval("#{old_level}_instance_methods").each{ |meth| self.send(:protected, meth) }
|
6
|
+
self
|
7
|
+
end
|
8
|
+
|
9
|
+
# Includes this module into an Object, and changes all public methods to protected.
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
# module MyCoolUtils
|
13
|
+
# def some_meth
|
14
|
+
# "hi"
|
15
|
+
# end
|
16
|
+
# self.include_safely_into(FooController)
|
17
|
+
# end
|
18
|
+
# or:
|
19
|
+
# MyCoolUtils.include_safely_into(FooController, SomeOtherClass)
|
20
|
+
def include_safely_into(*args)
|
21
|
+
[args].flatten.each do |a|
|
22
|
+
if a.is_a?(String) || a.is_a?(Symbol)
|
23
|
+
a = a.to_s.constantize
|
24
|
+
end
|
25
|
+
a.send(:include, self.convert_security_of_methods)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# Camel cases the string.
|
4
|
+
#
|
5
|
+
# Examples:
|
6
|
+
# "user".camelcase # => User
|
7
|
+
# "my_blog".camelcase # => MyBlog
|
8
|
+
# "my/blog".camelcase # => My::Blog
|
9
|
+
def camelcase
|
10
|
+
self.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns a constant of the string.
|
14
|
+
#
|
15
|
+
# Examples:
|
16
|
+
# "User".constantize # => User
|
17
|
+
# "HomeController".constantize # => HomeController
|
18
|
+
# "Mack::Configuration" # => Mack::Configuration
|
19
|
+
def constantize
|
20
|
+
Module.instance_eval("::#{self}")
|
21
|
+
end
|
22
|
+
|
23
|
+
# If the string is empty, this will return true.
|
24
|
+
def blank?
|
25
|
+
self == ""
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/errors/errors.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Mack
|
2
|
+
module Errors # :nodoc:
|
3
|
+
|
4
|
+
# Raised when someone calls render twice in one action
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# class FooController < Mack::Controller::Base
|
8
|
+
# def index
|
9
|
+
# render(:text => "Hello World")
|
10
|
+
# render(:action => "edit")
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
class DoubleRender < StandardError
|
14
|
+
end # DoubleRender
|
15
|
+
|
16
|
+
# Raised when an action returns something other then a string.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# class FooController < Mack::Controller::Base
|
20
|
+
# def index
|
21
|
+
# [1,2,3,4]
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
class InvalidRenderType < StandardError
|
25
|
+
# Takes the Class you are trying to render.
|
26
|
+
def initialize(klass)
|
27
|
+
super("You can not render a #{klass}! It must be a String.")
|
28
|
+
end
|
29
|
+
end # InvalidRenderType
|
30
|
+
|
31
|
+
# Raised when an action tries to render a resource that can't be found.
|
32
|
+
#
|
33
|
+
# Example:
|
34
|
+
# http://www.mackframework.com/my_missing_file.jpg
|
35
|
+
class ResourceNotFound < StandardError
|
36
|
+
# Takes the resource that can't be found.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# http://www.mackframework.com/my_missing_file.jpg # => my_missing_file.jpg would be the resource
|
40
|
+
def initialize(resource)
|
41
|
+
super(resource)
|
42
|
+
end
|
43
|
+
end # ResourceNotFound
|
44
|
+
|
45
|
+
# Raised when a route that matches the pattern of the incoming route AND the method of the request can't be found.
|
46
|
+
# It's important to note that BOTH the PATTERN and the HTTP METHOD HAVE to match for a route to be found!
|
47
|
+
class UndefinedRoute < StandardError
|
48
|
+
# Takes a request object.
|
49
|
+
def initialize(req)
|
50
|
+
super("#{req.path_info}; #{req.request_method}")
|
51
|
+
end
|
52
|
+
end # UndefinedRoute
|
53
|
+
|
54
|
+
# Raised when a layout is specified that doesn't exist.
|
55
|
+
class UnknownLayout < StandardError
|
56
|
+
# Takes a layout name.
|
57
|
+
def initialize(layout)
|
58
|
+
super("Could not find layout in: #{File.join(MACK_ROOT, "app", "views", layout.to_s + ".html.erb")}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Raised if an unsupported render option is supplied.
|
63
|
+
class UnknownRenderOption < StandardError
|
64
|
+
# Takes a render option.
|
65
|
+
def initialize(opt)
|
66
|
+
super("You did not specify a valid render option! '#{opt.inspect}'")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Raised if a Mack::Controller::Filter returns false.
|
71
|
+
class FilterChainHalted < StandardError
|
72
|
+
# Takes the name of the filter that returned false.
|
73
|
+
def initialize(filter)
|
74
|
+
super("The fitler chain was halted because of filter: '#{filter}'")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end # Errors
|
79
|
+
end # Mack
|