vintage 0.0.1 → 0.0.5
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/History.txt +9 -0
- data/app_generators/vintage_application/templates/index.erb +2 -2
- data/bin/vintage +14 -1
- data/config/hoe.rb +2 -3
- data/lib/vintage/errors.rb +26 -46
- data/lib/vintage/handler.rb +36 -53
- data/lib/vintage/request_context.rb +43 -28
- data/lib/vintage/server.rb +35 -6
- data/lib/vintage/version.rb +1 -1
- metadata +14 -6
data/History.txt
CHANGED
@@ -16,8 +16,8 @@
|
|
16
16
|
<ul>
|
17
17
|
<li>Remote IP: <%= request.remote_ip %></li>
|
18
18
|
<li>Referer: <%= request.referer %></li>
|
19
|
-
<li>Requested URI: <%= request.
|
20
|
-
<li>Request method: <%= request.
|
19
|
+
<li>Requested URI: <%= request.url %></li>
|
20
|
+
<li>Request method: <%= request.request_method %></li>
|
21
21
|
<li>User agent: <%= request.user_agent %></li>
|
22
22
|
<li>Query string: <%= request.query_string %></li>
|
23
23
|
<li>Parameters: <%= request.params == {} ? "None" : request.params.to_a.map{|k,v| "#{k} = #{v}"}.join(", ") %></li>
|
data/bin/vintage
CHANGED
@@ -19,7 +19,8 @@ OPTIONS = {
|
|
19
19
|
:config => 'configuration.yml',
|
20
20
|
:templates => 'erb',
|
21
21
|
:mount => '/',
|
22
|
-
:root => 'index'
|
22
|
+
:root => 'index',
|
23
|
+
:server => 'mongrel'
|
23
24
|
}
|
24
25
|
MANDATORY_OPTIONS = %w( )
|
25
26
|
|
@@ -33,7 +34,12 @@ a new project is generated. Otherwise, Vintage will start serving
|
|
33
34
|
given the defaults and/or any provided options.
|
34
35
|
|
35
36
|
Usage: #{File.basename($0)} [options]
|
37
|
+
|
38
|
+
To generate an application:
|
36
39
|
#{File.basename($0)} [project name]
|
40
|
+
|
41
|
+
To start your application:
|
42
|
+
#{File.basename($0)} start
|
37
43
|
|
38
44
|
Options are:
|
39
45
|
BANNER
|
@@ -56,6 +62,9 @@ BANNER
|
|
56
62
|
opts.on("-r", "--root=template", String,
|
57
63
|
"The template to render at the root URL",
|
58
64
|
"Default: index") { |OPTIONS[:root]| }
|
65
|
+
opts.on("-s", "--server=server", String,
|
66
|
+
"The server daemon to use (can be mongrel, webrick, cgi, or fastcgi)",
|
67
|
+
"Default: mongrel") { |OPTIONS[:server]| }
|
59
68
|
opts.on("-h", "--help",
|
60
69
|
"Show this help message.") { puts opts; exit }
|
61
70
|
opts.parse!(ARGV)
|
@@ -65,6 +74,10 @@ if ARGV.empty?
|
|
65
74
|
puts parser
|
66
75
|
puts
|
67
76
|
elsif ARGV[0] == "start"
|
77
|
+
if OPTIONS[:server] == 'swift'
|
78
|
+
require 'swiftcore/swiftiplied_mongrel'
|
79
|
+
end
|
80
|
+
|
68
81
|
OPTIONS.merge!(YAML::load_file(OPTIONS[:config])) if File.exists?(OPTIONS[:config])
|
69
82
|
Vintage::Server.run(OPTIONS)
|
70
83
|
else
|
data/config/hoe.rb
CHANGED
@@ -2,7 +2,7 @@ require 'vintage/version'
|
|
2
2
|
|
3
3
|
AUTHOR = 'Jeremy McAnally' # can also be an array of Authors
|
4
4
|
EMAIL = "jeremymcanally@gmail.com"
|
5
|
-
DESCRIPTION = "
|
5
|
+
DESCRIPTION = "The super slim web framework"
|
6
6
|
GEM_NAME = 'vintage' # what ppl will type to install your gem
|
7
7
|
RUBYFORGE_PROJECT = 'vintage' # The unix name for your project
|
8
8
|
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
@@ -32,7 +32,6 @@ REV = nil
|
|
32
32
|
# UNCOMMENT IF REQUIRED:
|
33
33
|
# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
|
34
34
|
VERS = Vintage::VERSION::STRING + (REV ? ".#{REV}" : "")
|
35
|
-
VERSION = VERS
|
36
35
|
RDOC_OPTS = ['--quiet', '--title', 'vintage documentation',
|
37
36
|
"--opname", "index.html",
|
38
37
|
"--line-numbers",
|
@@ -60,7 +59,7 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
60
59
|
|
61
60
|
# == Optional
|
62
61
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
63
|
-
|
62
|
+
p.extra_deps = [['rubigen', '>= 0.0.0']] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
64
63
|
|
65
64
|
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
66
65
|
|
data/lib/vintage/errors.rb
CHANGED
@@ -2,74 +2,54 @@ module Vintage
|
|
2
2
|
# A class to render the default error pages. These will
|
3
3
|
# not render if error pages are specified in the configuration.
|
4
4
|
class ErrorReporter
|
5
|
+
# CSS shared among error templates
|
6
|
+
CSS = """
|
7
|
+
body { margin: 0px; padding: 0px; font-family: sans-serif; }
|
8
|
+
h1 { background: #3E2B09; padding: 45px 10px 10px 10px; color: #6F5E3C; border: 0px; border-bottom: 2px solid #1C0907; margin: 0px; }
|
9
|
+
h1 span.error { text-shadow: 0.1em 0.1em #333; color: white; }
|
10
|
+
h2 { margin: 0px; padding: 5px 5px 10px 10px; font-size: 14pt !important; }
|
11
|
+
h2 span.where { color: #999; }
|
12
|
+
h3 { margin: 0px; padding: 10px 10px; color: #999;}
|
13
|
+
ul { margin: 0px; }
|
14
|
+
li { margin: 0px; padding: 0px 30px; }
|
15
|
+
pre { padding: 0 30px; margin: 0px; }
|
16
|
+
"""
|
17
|
+
|
5
18
|
# Standard template to render for a <tt>500 Internal Server Error</tt>
|
6
19
|
def self.internal_error(error, params)
|
7
|
-
"""
|
8
|
-
<html>
|
9
|
-
<head>
|
10
|
-
<title>Vintage Error: 500 Internal Server Error</title>
|
11
|
-
<style>
|
12
|
-
body { margin: 0px; padding: 0px; font-family: sans-serif; }
|
13
|
-
h1 { background: #3E2B09; padding: 45px 10px 10px 10px; color: #6F5E3C; border: 0px; border-bottom: 2px solid #1C0907; margin: 0px; }
|
14
|
-
h1 span.error { text-shadow: 0.1em 0.1em #333; color: white; }
|
15
|
-
h2 { margin: 0px; padding: 5px 5px 10px 10px; font-size: 14pt !important; }
|
16
|
-
h2 span.where { color: #999; }
|
17
|
-
h3 { margin: 0px; padding: 10px 10px; color: #999;}
|
18
|
-
ul { margin: 0px; }
|
19
|
-
li { margin: 0px; padding: 0px 30px; }
|
20
|
-
pre { padding: 0 30px; margin: 0px; }
|
21
|
-
</style>
|
22
|
-
</head>
|
23
|
-
|
24
|
-
<body>
|
25
|
-
<h1><span class='error'>#{error.class}</span> 500 Internal Server Error</h1>
|
26
|
-
<h2>#{error.message} <span class='where'>at #{error.backtrace[0]}</span></h2>
|
27
|
-
<div>
|
28
|
-
<h3>Parameters</h3>
|
29
|
-
<ul>
|
30
|
-
#{params == {} ? "None" : params.to_a.map{|key, val| "<li><b>" + key.to_s + "<b> = " + val.to_s + "</li>"}.join("\n") }
|
31
|
-
</ul>
|
32
|
-
<br />
|
33
|
-
<h3>Backtrace</h3>
|
34
|
-
<pre>#{error.backtrace.join("\n")}</pre>
|
35
|
-
</div>
|
36
|
-
</body>
|
37
|
-
</html>
|
38
|
-
|
39
|
-
"""
|
20
|
+
error_page("500 Internal Server Error", error.class.to_s, "500 Internal Server Error", error.message.to_s, "at #{error.backtrace[0]}", "<h3>Backtrace</h3>\n\t<pre>#{error.backtrace.join('\n')}</pre>", params)
|
40
21
|
end
|
41
22
|
|
42
23
|
# Standard template to render for a <tt>404 Page Not Found</tt> error
|
43
24
|
def self.not_found(url, remote_ip, params)
|
25
|
+
error_page("404 Not Found", "Page Not Found", "404 Not Found", "Request for #{url}", "from #{remote_ip}", params)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
# Standard template to render for a <tt>404 Page Not Found</tt> error
|
30
|
+
def self.error_page(title, h1_primary, h1_secondary, h2_primary, h2_secondary, extra_content = "", params = {})
|
44
31
|
"""
|
45
32
|
<html>
|
46
33
|
<head>
|
47
|
-
<title>Vintage Error:
|
34
|
+
<title>Vintage Error: #{title}</title>
|
48
35
|
<style>
|
49
|
-
|
50
|
-
h1 { background: #3E2B09; padding: 45px 10px 10px 10px; color: #6F5E3C; border: 0px; border-bottom: 2px solid #1C0907; margin: 0px; }
|
51
|
-
h1 span.error { text-shadow: 0.1em 0.1em #333; color: white; }
|
52
|
-
h2 { margin: 0px; padding: 5px 5px 10px 10px; font-size: 14pt !important; }
|
53
|
-
h2 span.where { color: #999; }
|
54
|
-
h3 { margin: 0px; padding: 10px 10px; color: #999;}
|
55
|
-
ul { margin: 0px; }
|
56
|
-
li { margin: 0px; padding: 0px 30px; }
|
57
|
-
pre { padding: 0 30px; margin: 0px; }
|
36
|
+
#{CSS}
|
58
37
|
</style>
|
59
38
|
</head>
|
60
39
|
|
61
40
|
<body>
|
62
|
-
<h1><span class='error'
|
63
|
-
<h2
|
41
|
+
<h1><span class='error'>#{h1_primary}</span> #{h1_secondary}</h1>
|
42
|
+
<h2>#{h2_primary} <span class='where'>#{h2_secondary}</span></h2>
|
64
43
|
<div>
|
65
44
|
<h3>Parameters</h3>
|
66
45
|
<ul>
|
67
46
|
#{params == {} ? "None" : params.to_a.map{|key, val| "<li><b>" + key.to_s + "<b> = " + val.to_s + "</li>"}.join("\n") }
|
68
47
|
</ul>
|
48
|
+
<br />
|
49
|
+
#{extra_content}
|
69
50
|
</div>
|
70
51
|
</body>
|
71
52
|
</html>
|
72
|
-
|
73
53
|
"""
|
74
54
|
end
|
75
55
|
end
|
data/lib/vintage/handler.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'mongrel'
|
3
3
|
require 'erubis'
|
4
4
|
require 'erb'
|
5
|
+
|
5
6
|
require 'mime/types'
|
6
7
|
|
7
8
|
require 'vintage/renderer'
|
@@ -10,13 +11,13 @@ require 'vintage/errors'
|
|
10
11
|
|
11
12
|
module Vintage
|
12
13
|
# The Mongrel HTTP Handler. Handles all operations with requests.
|
13
|
-
class Handler
|
14
|
+
class Handler
|
14
15
|
def initialize(options)
|
15
16
|
# Make our configuration options avialable to the handler
|
16
17
|
@options = options
|
17
18
|
|
18
19
|
# Setup a DirHandler for sending static files securely
|
19
|
-
@static_handler =
|
20
|
+
@static_handler = Rack::File.new(@options[:static_path])
|
20
21
|
|
21
22
|
# Inject our helpers in the RequestContext class to make them
|
22
23
|
# available on each request.
|
@@ -24,19 +25,17 @@ module Vintage
|
|
24
25
|
end
|
25
26
|
|
26
27
|
# Main request handler for Mongrel.
|
27
|
-
def
|
28
|
-
# Parse params into a nice Hash
|
29
|
-
handle_params(request.params["QUERY_STRING"])
|
30
|
-
|
31
|
-
# Setup our request's path
|
32
|
-
@request_path = request.params["PATH_INFO"]
|
33
|
-
|
28
|
+
def call(env)
|
34
29
|
# Setup up the request's context (response and request information)
|
35
|
-
|
36
|
-
|
30
|
+
request = Rack::Request.new(env)
|
31
|
+
context = RequestContext.new(request)
|
32
|
+
|
33
|
+
# Setup our request's path
|
34
|
+
@request_path = request.path_info
|
35
|
+
|
37
36
|
# Initialize the buffered log entry
|
38
37
|
log_entry = ""
|
39
|
-
log_entry << "*** request for [#{request.
|
38
|
+
log_entry << "*** request for [#{request.url}] from [#{env['REMOTE_ADDR']}]\n"
|
40
39
|
|
41
40
|
# If it's a root request, we want to render the template we configured
|
42
41
|
@request_path = @options[:root] if @request_path == '/'
|
@@ -53,64 +52,48 @@ module Vintage
|
|
53
52
|
# Is it a static file?
|
54
53
|
if (@request_path =~ /\.(.*)$/)
|
55
54
|
# Yes? Let our static handler take it away!
|
56
|
-
@static_handler.
|
55
|
+
@static_handler.call(env)
|
57
56
|
else
|
58
57
|
# No! Render a template...
|
59
58
|
content = Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@request_path}.#{@options[:templates]}", "r").read, context)
|
60
|
-
end
|
61
59
|
|
62
|
-
# Render (if response is 200) or redirect
|
63
|
-
response.start(context.response.code) do |head, out|
|
64
|
-
# Add any custom headers (e.g., from redirect_to)
|
65
|
-
context.response.headers.each do |k,v|
|
66
|
-
head[k] = v
|
67
|
-
end
|
68
|
-
|
69
60
|
# Set the content type if we're responding with a render
|
70
|
-
|
61
|
+
context.response.headers["Content-Type"] = "text/html" if context.response.code == 200
|
62
|
+
response = Rack::Response.new(content, context.response.code, {}.merge!(context.response.headers))
|
63
|
+
|
64
|
+
# Render (if response is 200) or redirect
|
65
|
+
# Set cookies
|
66
|
+
if context.response.cookies != {}
|
67
|
+
context.response.cookies.each do |key, value|
|
68
|
+
response.set_cookie(key, value)
|
69
|
+
end
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
out.write content
|
72
|
+
response.finish
|
74
73
|
end
|
75
74
|
else
|
76
75
|
# Page not found
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
out.write @options[:errors] && @options[:errors][:not_found] ? Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@options[:errors][:not_found]}.#{@options[:templates]}", "r").read, context) : ErrorReporter.not_found(@request_path, request.params['REMOTE_ADDR'], @params)
|
85
|
-
end
|
76
|
+
# Log the 404
|
77
|
+
log_entry << " response: [404]\n"
|
78
|
+
log_entry << " rendering 'page not found'\n"
|
79
|
+
|
80
|
+
# Send back the default or a custom template
|
81
|
+
content = @options[:errors] && @options[:errors][:not_found] ? Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@options[:errors][:not_found]}.#{@options[:templates]}", "r").read, context) : ErrorReporter.not_found(@request_path, request.params['REMOTE_ADDR'], @params)
|
82
|
+
[context.response.code, {}.merge!(context.response.headers), content]
|
86
83
|
end
|
87
84
|
rescue StandardError => err
|
88
85
|
# OOPS! Something broke.
|
89
|
-
response.
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
context.response.code = 500
|
87
|
+
|
88
|
+
# Log it and send an error page...
|
89
|
+
log_entry << "\t!!! [500] #{err}\n"
|
90
|
+
content = @options[:errors] && @options[:errors][:internal_error] ? Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@options[:errors][:internal_error]}.#{@options[:templates]}", "r").read, context) : ErrorReporter.internal_error(err, @params)
|
91
|
+
[context.response.code, {}.merge!(context.response.headers), content]
|
95
92
|
ensure
|
96
93
|
# After every request push the buffered log entry out to the logger
|
97
94
|
Log.enter log_entry.to_s + "\n"
|
98
95
|
end
|
99
96
|
|
100
|
-
# Parse HTTP params into a +Hash+.
|
101
|
-
def handle_params(params)
|
102
|
-
@params = {}
|
103
|
-
|
104
|
-
unless params == nil || params == ''
|
105
|
-
# Split the query string and hack it up
|
106
|
-
params.split('&').each do |param|
|
107
|
-
key, val = param.split('=')
|
108
|
-
|
109
|
-
@params[key.to_sym] = val
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
97
|
# Inject the default helpers and helpers from the
|
115
98
|
# +helpers/+ directory (if available) into the
|
116
99
|
# RequestContext class.
|
@@ -1,37 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'rack'
|
2
|
+
require 'rack/file'
|
3
|
+
|
4
|
+
module Vintage
|
5
|
+
# Class that encapsulates the response's headers and
|
6
|
+
# response code.
|
7
|
+
class Response
|
8
|
+
attr_accessor :headers, :code, :cookies
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
self.user_agent = request.params['HTTP_USER_AGENT']
|
11
|
-
self.query_string = request.params['QUERY_STRING']
|
12
|
-
self.params = param_hash
|
10
|
+
def initialize
|
11
|
+
self.headers = {}
|
12
|
+
self.code = 200
|
13
|
+
self.cookies = {}
|
14
|
+
end
|
13
15
|
end
|
14
|
-
end
|
15
16
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
|
19
|
-
|
17
|
+
# A class that creates a context for template
|
18
|
+
# rendering. Helpers are mixed in here to give
|
19
|
+
# templates access to them.
|
20
|
+
class RequestContext
|
21
|
+
attr_accessor :request, :response
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
def initialize(incoming_request)
|
24
|
+
self.request = incoming_request
|
25
|
+
self.response = Vintage::Response.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def cookies
|
29
|
+
self.request.cookies
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_cookie(key, val)
|
33
|
+
self.response.cookies[key] = val
|
34
|
+
end
|
35
|
+
|
36
|
+
# def session
|
37
|
+
# @env["rack.session"]
|
38
|
+
# end
|
24
39
|
end
|
25
40
|
end
|
26
41
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
42
|
+
module Rack
|
43
|
+
class Request
|
44
|
+
def remote_ip
|
45
|
+
@env['REMOTE_ADDR']
|
46
|
+
end
|
47
|
+
|
48
|
+
def user_agent
|
49
|
+
@env['HTTP_USER_AGENT']
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
data/lib/vintage/server.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'mongrel'
|
3
2
|
|
4
3
|
require 'erubis'
|
5
4
|
|
@@ -7,6 +6,15 @@ require 'vintage/version'
|
|
7
6
|
require 'vintage/log'
|
8
7
|
require 'vintage/helpers'
|
9
8
|
|
9
|
+
begin
|
10
|
+
require 'swiftcore/evented_mongrel'
|
11
|
+
rescue
|
12
|
+
# Don't have it? No problem!
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'rack'
|
16
|
+
require 'rack/file'
|
17
|
+
|
10
18
|
begin
|
11
19
|
Dir.entries("helpers/").select{|entry| entry =~ /(.*).rb$/}.each do |helper_file|
|
12
20
|
Vintage::Helpers.module_eval(File.open(helper_file).read)
|
@@ -22,11 +30,32 @@ module Vintage
|
|
22
30
|
Log.enter "- vintage version #{VERSION::STRING}"
|
23
31
|
Log.enter "\t starting server on port #{options[:port]}"
|
24
32
|
Log.enter
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
33
|
+
|
34
|
+
application = Handler.new(options)
|
35
|
+
|
36
|
+
server = Rack::Handler::Mongrel
|
37
|
+
|
38
|
+
case options[:server]
|
39
|
+
when "mongrel"
|
40
|
+
server = Rack::Handler::Mongrel
|
41
|
+
when "thin"
|
42
|
+
begin
|
43
|
+
require 'thin'
|
44
|
+
server = Rack::Handler::Thin
|
45
|
+
rescue LoadError
|
46
|
+
puts "You don't have Thin installed!"
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
when "webrick"
|
50
|
+
server = Rack::Handler::WEBrick
|
51
|
+
when "cgi"
|
52
|
+
server = Rack::Handler::CGI
|
53
|
+
when "fastcgi"
|
54
|
+
server = Rack::Handler::FastCGI
|
55
|
+
end
|
56
|
+
|
57
|
+
server.run application, {:Port => options[:port], :Host => "0.0.0.0", :AccessLog => []}
|
58
|
+
rescue Interrupt, Mongrel::StopServer
|
30
59
|
Log.enter
|
31
60
|
Log.enter "- interrupt signal caught"
|
32
61
|
Log.enter "\tshutting server down"
|
data/lib/vintage/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vintage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy McAnally
|
@@ -9,11 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-01-
|
12
|
+
date: 2008-01-11 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rubigen
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.0.0
|
23
|
+
version:
|
24
|
+
description: The super slim web framework
|
17
25
|
email: jeremymcanally@gmail.com
|
18
26
|
executables:
|
19
27
|
- vintage
|
@@ -84,7 +92,7 @@ rubyforge_project: vintage
|
|
84
92
|
rubygems_version: 1.0.1
|
85
93
|
signing_key:
|
86
94
|
specification_version: 2
|
87
|
-
summary:
|
95
|
+
summary: The super slim web framework
|
88
96
|
test_files:
|
89
97
|
- test/test_generator_helper.rb
|
90
98
|
- test/test_helper.rb
|