mack 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|