serve 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -1,15 +1,17 @@
1
1
  History.txt
2
2
  License.txt
3
3
  Manifest.txt
4
+ Quickstart.textile
4
5
  README.txt
5
6
  Rakefile
6
7
  bin/serve
7
8
  config/hoe.rb
8
9
  config/requirements.rb
9
10
  lib/serve.rb
11
+ lib/serve/application.rb
12
+ lib/serve/handlers/dynamic_handler.rb
10
13
  lib/serve/handlers/email_handler.rb
11
14
  lib/serve/handlers/file_type_handler.rb
12
- lib/serve/handlers/haml_handler.rb
13
15
  lib/serve/handlers/markdown_handler.rb
14
16
  lib/serve/handlers/redirect_handler.rb
15
17
  lib/serve/handlers/sass_handler.rb
@@ -21,6 +23,7 @@ script/destroy
21
23
  script/generate
22
24
  script/txt2html
23
25
  setup.rb
26
+ spec/serve_application_spec.rb
24
27
  spec/serve_spec.rb
25
28
  spec/spec.opts
26
29
  spec/spec_helper.rb
@@ -0,0 +1,148 @@
1
+ h1. Getting Started with Serve
2
+
3
+
4
+ Serve is a rapid prototyping framework for Rails applications. It is designed to compliment Rails development and enforce a strict separation of concerns between designer and developer. Using Serve with Rails allows the designer to happily work in his own space creating an HTML prototype of the application, while the developer works on the Rails application and copies over HTML from the prototype as needed. This allows the designer to focus on presentation and flow while the developer can focus on the implementation.
5
+
6
+ Let's have a look at how it all works.
7
+
8
+
9
+ h3. Installation
10
+
11
+ To get started we need to download and install the Ruby gem for Serve:
12
+
13
+ <pre>
14
+ % sudo gem install serve
15
+ </pre>
16
+
17
+ After we've done that it's probably a good idea to install a couple of additional gems so that Serve will play nicely with HAML, Markdown, and Textile:
18
+
19
+ <pre>
20
+ % sudo gem install haml Bluecloth Redcloth
21
+ </pre>
22
+
23
+
24
+ h3. Project Directory Structure
25
+
26
+ Once we have everything installed the next thing to do is setup the project directory. I like to setup my projects with the following directory structure:
27
+
28
+ <pre>
29
+ artwork # Logos and other identity design files go here
30
+ mockups # Fireworks or Photoshop web app mockups go here
31
+ prototype # The HTML prototype for the web app goes here
32
+ application # The actual Rails application is here
33
+ </pre>
34
+
35
+ Let's go ahead and create the directory for the prototype:
36
+
37
+ % mkdir prototype
38
+
39
+ Rails apps generally store images, javascripts, and stylesheets in the top level directories by the same name. Let's go ahead and mirror those directories for our prototype:
40
+
41
+ <pre>
42
+ % cd prototype
43
+ % mkdir images
44
+ % mkdir javascripts
45
+ % mkdir stylesheets
46
+ </pre>
47
+
48
+
49
+ h3. Creating Our First Screen
50
+
51
+ Now that we have the prototype directory set up, let's create our first page so that you can get a feel for how Serve works. This will be a simple HTML login page for our application.
52
+
53
+ Insert the following HTML into an file named "login.html":
54
+
55
+ <pre><code>
56
+ <form action="/dashboard/" method="put">
57
+ <p>
58
+ <label for="username">Username</label>
59
+ <input type="text" name="username" id="username" />
60
+ </p>
61
+ <p>
62
+ <label for="password">Password</label>
63
+ <input type="password" name="password" id="password" />
64
+ </p>
65
+ <p>
66
+ <input type="submit" value="Login" />
67
+ </p>
68
+ </form>
69
+ </code></pre>
70
+
71
+
72
+ h3. Starting Serve
73
+
74
+ To view our login page in a Web browser, we need to start up Serve in the directory where we are building the prototype:
75
+
76
+ <pre>
77
+ % cd prototype
78
+ % serve
79
+ [2008-02-23 15:19:05] INFO WEBrick 1.3.1
80
+ [2008-02-23 15:19:05] INFO ruby 1.8.6 (2007-09-24) [universal-darwin9.0]
81
+ [2008-02-23 15:19:05] INFO Serve::Server#start: pid=5087 port=4000
82
+ ...
83
+ </pre>
84
+
85
+ Once you execute the `serve` command it will launch a mini Web server for the prototype and will output a noisy log of any activity. (To stop the command at any point simply switch back to the command line and press Ctrl+C.)
86
+
87
+ By default the `serve` command automatically serves files from the directory that it is started in over port 4000 on your local machine. To access the the prototype in your Web browser go to:
88
+
89
+ http://localhost:4000
90
+
91
+ You should see a simple directory listing. It will look similar to this:
92
+
93
+ <pre>
94
+ Name Last modified Size
95
+ ----------------------------------------------------------
96
+ Parent Directory 2008/02/23 15:35 -
97
+ images/ 2008/02/23 15:35 -
98
+ javascripts/ 2008/02/23 15:35 -
99
+ login.html 2008/02/23 15:36 346
100
+ stylesheets/ 2008/02/23 15:35 -
101
+ </pre>
102
+
103
+ Now navigate to the following URL:
104
+
105
+ http://localhost:4000/login/
106
+
107
+ You should see the contents of the login page. Note that Serve allows you to refer to pages without their extension. This allows you to use URLs in your documents that correspond well to the URLs that Rails uses by default.
108
+
109
+
110
+ h3. Layouts
111
+
112
+ One thing to note about the source that I gave you for the login page. I intentionally left out the <html>, <head>, and <body> tags because they belong a layout---not the source file. Let's go ahead and create that layout now.
113
+
114
+ Insert the following HTML into a file named "_layout.html" in the root directory of your prototype:
115
+
116
+ <pre><code>
117
+ <html>
118
+ <head>
119
+ <title><%= @title %></title>
120
+ </head>
121
+ <body>
122
+ <h1><%= @title %>/h1>
123
+ <%= yield %>
124
+ </body>
125
+ </html>
126
+ </code></pre>
127
+
128
+ This layout includes a small amount of ERB(Embedded Ruby) to indicate the title of the web page and to insert the content of the page at the appropriate point.
129
+
130
+ Embedded Ruby is delineated with the opening and closing sequence <% and %> respectively. Sequences that begin with an addition equals sign insert their output directly into the HTML. In this case we want to render the @title variable as the title in the head and as the first heading in the document body. The yield keyword is used to insert the content of the page at that point.
131
+
132
+ We need to make one small change to our login page before continuing. Insert the following line at the top of login.html file:
133
+
134
+ <pre>
135
+ <% @title = "Login" %>
136
+ </pre>
137
+
138
+ This will set the @title variable for the login page. Now, switch back to your Web browser and navigate to:
139
+
140
+ <pre>
141
+ http://localhost:4000/login/
142
+ </pre>
143
+
144
+ The page should now have a title and heading that both read "Login".
145
+
146
+ h3. Content For
147
+
148
+ h3. Partials
data/README.txt CHANGED
@@ -70,11 +70,11 @@ It is recommended that you install serve via RubyGems:
70
70
  For more information, be sure to look through the documentation over at
71
71
  RubyForge:
72
72
 
73
- http://serve.rubyforge.org/
73
+ * http://serve.rubyforge.org
74
74
 
75
75
  Or visit the project page here:
76
76
 
77
- http://rubyforge.org/projects/serve/
77
+ * http://rubyforge.org/projects/serve
78
78
 
79
79
 
80
80
  === License
data/bin/serve CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
2
  lib = File.dirname(__FILE__) + '/../lib'
4
3
  require 'rubygems'
5
4
  if File.file?(lib + '/serve/version.rb')
@@ -8,69 +7,4 @@ else
8
7
  gem 'serve'
9
8
  end
10
9
  require 'serve'
11
-
12
- args = ARGV.join(' ')
13
- args.gsub!(%r{http://}, '')
14
- args = args.split(/[ :]/).compact
15
-
16
- help = args.delete('--help') || args.delete('-h') || false
17
- version = args.delete('--version') || args.delete('-v') || false
18
- environment = args.delete('production') || args.delete('test') || args.delete('test') || 'development'
19
- port = args.pop
20
- address = args.pop || '0.0.0.0'
21
- script = Dir.pwd + '/script/server'
22
-
23
- if args.size > 0
24
- puts "invalid arguments"
25
- puts ""
26
- help = true
27
- end
28
-
29
- case
30
- when version
31
- puts "Serve #{Serve.version}"
32
- when help
33
- program = File.basename($0)
34
- puts "Usage:"
35
- puts " #{program} [port] [environment]"
36
- puts " #{program} [address:port] [environment]"
37
- puts " #{program} [options]"
38
- puts " "
39
- puts "Description:"
40
- puts " Starts a WEBrick server on the specified address and port with its document "
41
- puts " root set to the current working directory. By default the command uses "
42
- puts " 0.0.0.0 for the address and 4000 for the port. This means that once the "
43
- puts " command has been started you can access the documents in the current "
44
- puts " directory with any Web browser at:"
45
- puts " "
46
- puts " http://localhost:4000/"
47
- puts " "
48
- puts " If the haml, redcloth, or bluecloth gems are installed the command can serve "
49
- puts " Haml, Sass, Textile, and Markdown for documents with haml, sass, textile, "
50
- puts " and markdown file extensions."
51
- puts " "
52
- puts " If the Rails command script/server exists in the current directory the "
53
- puts " script will start that instead with the specified environment or the "
54
- puts " development environment if none is specified. Rails apps are started by "
55
- puts " default on port 3000."
56
- puts " "
57
- puts "Options:"
58
- puts " -h, --help Show this message and quit."
59
- puts " -v, --version Show the program version number and quit."
60
- else
61
- unless File.file?(script) and File.executable?(script)
62
- port ||= 4000
63
- server = Serve::Server.new(
64
- :Port => port,
65
- :BindAddress => address,
66
- :DocumentRoot => Dir.pwd,
67
- :DirectoryIndex => %w(index.html index.txt index.text index.haml index.textile index.markdown index.email index.redirect),
68
- :AppendExtensions => %w(html txt text haml textile markdown email redirect)
69
- )
70
- trap("INT") { server.shutdown }
71
- server.start
72
- else
73
- port ||= 3000
74
- system "#{script} -p #{port} -b #{address} -e #{environment}"
75
- end
76
- end
10
+ Serve::Application.run
@@ -0,0 +1,145 @@
1
+ module Serve
2
+ class Application
3
+ class InvalidArgumentsError < StandardError; end
4
+
5
+ attr_accessor :options
6
+
7
+ def self.run(args = ARGV)
8
+ Application.new.run(args)
9
+ end
10
+
11
+ def initialize
12
+ self.options = {}
13
+ end
14
+
15
+ def run(args = ARGV)
16
+ @options = parse(args)
17
+ case
18
+ when options[:version]
19
+ puts version
20
+ when options[:help]
21
+ puts help
22
+ else
23
+ Dir.chdir(options[:root])
24
+ if rails_app?
25
+ run_rails_app
26
+ else
27
+ run_server
28
+ end
29
+ end
30
+ rescue InvalidArgumentsError
31
+ puts "invalid arguments"
32
+ puts
33
+ puts help
34
+ end
35
+
36
+ def parse(args)
37
+ args = normalize_args(args)
38
+ options[:help] = extract_boolean(args, '-h', '--help')
39
+ options[:version] = extract_boolean(args, '-v', '--version')
40
+ options[:environment] = extract_environment(args)
41
+ options[:root] = extract_root(args)
42
+ options[:address] = extract_address(args)
43
+ options[:port] = extract_port(args)
44
+ raise InvalidArgumentsError if args.size > 0
45
+ options
46
+ end
47
+
48
+ def version
49
+ "Serve #{Serve.version}"
50
+ end
51
+
52
+ def help
53
+ program = File.basename($0)
54
+ [
55
+ "Usage:",
56
+ " #{program} [port] [environment] [port]",
57
+ " #{program} [address:port] [environment] [port]",
58
+ " #{program} [options]",
59
+ " ",
60
+ "Description:",
61
+ " Starts a WEBrick server on the specified address and port with its document ",
62
+ " root set to the current working directory. (Optionally, you can specify the ",
63
+ " directory as the last parameter.) By default the command uses 0.0.0.0 for ",
64
+ " the address and 4000 for the port. This means that once the command has ",
65
+ " been started you can access the documents in the current directory with any ",
66
+ " Web browser at:",
67
+ " ",
68
+ " http://localhost:4000/",
69
+ " ",
70
+ " If the haml, redcloth, or bluecloth gems are installed the command can serve ",
71
+ " Haml, Sass, Textile, and Markdown for documents with haml, sass, textile, ",
72
+ " and markdown file extensions.",
73
+ " ",
74
+ " If the Rails command script/server exists in the current directory the ",
75
+ " script will start that instead with the specified environment or the ",
76
+ " development environment if none is specified. Rails apps are started by ",
77
+ " default on port 3000.",
78
+ " ",
79
+ "Options:",
80
+ " -h, --help Show this message and quit.",
81
+ " -v, --version Show the program version number and quit."
82
+ ].join("\n")
83
+ end
84
+
85
+ private
86
+ def normalize_args(args)
87
+ args = args.join(' ')
88
+ args.gsub!(%r{http://}, '')
89
+ args.split(/[ :]/).compact
90
+ end
91
+
92
+ def extract_boolean(args, *opts)
93
+ opts.each do |opt|
94
+ return true if args.delete(opt)
95
+ end
96
+ false
97
+ end
98
+
99
+ def extract_environment(args)
100
+ args.delete('production') || args.delete('test') || args.delete('development') || 'development'
101
+ end
102
+
103
+ def extract_port(args)
104
+ args.delete(args.find {|a| /^\d\d\d+$/.match(a) }) || (rails_app? ? 3000 : 4000)
105
+ end
106
+
107
+ def extract_address(args)
108
+ args.delete(args.find {|a| /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(a) }) || '0.0.0.0'
109
+ end
110
+
111
+ def extract_root(args)
112
+ args.reverse.each do |dir|
113
+ if File.directory?(dir)
114
+ args.delete(dir)
115
+ return File.expand_path(dir)
116
+ end
117
+ end
118
+ Dir.pwd
119
+ end
120
+
121
+ def rails_script_server
122
+ @rails_server_script ||= options[:root] + '/script/server'
123
+ end
124
+
125
+ def rails_app?
126
+ File.file?(rails_script_server) and File.executable?(rails_script_server)
127
+ end
128
+
129
+ def run_rails_app
130
+ system "#{rails_script_server} -p #{options[:port]} -b #{options[:address]} -e #{options[:environment]}"
131
+ end
132
+
133
+ def run_server
134
+ server = Serve::Server.new(
135
+ :Port => options[:port],
136
+ :BindAddress => options[:address],
137
+ :DocumentRoot => options[:root],
138
+ :DirectoryIndex => %w(index.html index.erb index.html.erb index.rhtml index.haml index.html.haml index.txt index.text index.textile index.markdown index.email index.redirect),
139
+ :AppendExtensions => %w(html txt text haml erb rhtml html.erb html.haml textile markdown email redirect)
140
+ )
141
+ trap("INT") { server.shutdown }
142
+ server.start
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,167 @@
1
+ module Serve #:nodoc:
2
+ class Handler < FileTypeHandler #:nodoc:
3
+ extension 'erb', 'html.erb', 'rhtml', 'haml', 'html.haml'
4
+
5
+ def process(req, res)
6
+ class << req
7
+ alias headers header
8
+ end
9
+ res['content-type'] = content_type
10
+ res.body = parse(req, res)
11
+ end
12
+
13
+ def parse(req, res)
14
+ context = Context.new(req, res)
15
+ view_helpers_file_path = Dir.pwd + '/view_helpers.rb'
16
+ if File.file?(view_helpers_file_path)
17
+ (class << context; self end).module_eval(File.read(view_helpers_file_path))
18
+ class << context
19
+ include ViewHelpers
20
+ end
21
+ end
22
+ parser = Parser.new(context)
23
+ context.content << parser.parse_file(@script_filename)
24
+ layout = find_layout_for(@script_filename)
25
+ if layout
26
+ parser.parse_file(layout)
27
+ else
28
+ context.content
29
+ end
30
+ end
31
+
32
+ def find_layout_for(filename)
33
+ root = Dir.pwd
34
+ path = filename[root.size..-1]
35
+ layout = nil
36
+ begin
37
+ path = File.dirname(path)
38
+ l = File.join(root, path, '_layout.haml')
39
+ layout = l if File.file?(l)
40
+ end until layout or path == "/"
41
+ layout
42
+ end
43
+
44
+ module ERB #:nodoc:
45
+ class Engine #:nodoc:
46
+ def initialize(string, options = {})
47
+ @erb = ::ERB.new(string, nil, '-')
48
+ @erb.filename = options[:filename]
49
+ end
50
+
51
+ def render(context, &block)
52
+ @erb.result(context.instance_eval { binding })
53
+ end
54
+ end
55
+ end
56
+
57
+ class Parser #:nodoc:
58
+ attr_accessor :context, :script_filename
59
+
60
+ def initialize(context)
61
+ @context = context
62
+ @context.parser = self
63
+ end
64
+
65
+ def parse_file(filename)
66
+ old_script_filename = @script_filename
67
+ @script_filename = filename
68
+ lines = IO.read(filename)
69
+ engine = case File.extname(filename).sub(/^./, '').downcase
70
+ when 'haml'
71
+ require 'haml'
72
+ Haml::Engine.new(lines, :attr_wrapper => '"', :filename => filename)
73
+ when 'erb'
74
+ require 'erb'
75
+ ERB::Engine.new(lines, :filename => filename)
76
+ else
77
+ raise 'extension not supported'
78
+ end
79
+ result = engine.render(context) do |*args|
80
+ context.get_content_for(*args)
81
+ end
82
+ @script_filename = old_script_filename
83
+ result
84
+ end
85
+ end
86
+
87
+ class Context #:nodoc:
88
+ attr_accessor :content, :parser
89
+ attr_reader :request, :response
90
+
91
+ def initialize(req, res)
92
+ @request, @response = req, res
93
+ @content = ''
94
+ end
95
+
96
+ # Content_for methods
97
+
98
+ def content_for(symbol, &block)
99
+ set_content_for(symbol, capture_haml(&block))
100
+ end
101
+
102
+ def content_for?(symbol)
103
+ !(get_content_for(symbol)).nil?
104
+ end
105
+
106
+ def get_content_for(symbol = :content)
107
+ if symbol.to_s.intern == :content
108
+ @content
109
+ else
110
+ instance_variable_get("@content_for_#{symbol}")
111
+ end
112
+ end
113
+
114
+ def set_content_for(symbol, value)
115
+ instance_variable_set("@content_for_#{symbol}", value)
116
+ end
117
+
118
+ # Render methods
119
+
120
+ def render(options)
121
+ partial = options.delete(:partial)
122
+ template = options.delete(:template)
123
+ case
124
+ when partial
125
+ render_partial(partial)
126
+ when template
127
+ render_template(template)
128
+ else
129
+ raise "render options not supported #{options.inspect}"
130
+ end
131
+ end
132
+
133
+ def render_partial(partial)
134
+ render_template(partial, :partial => true)
135
+ end
136
+
137
+ def render_template(template, options={})
138
+ path = File.dirname(parser.script_filename)
139
+ if template =~ %r{^/}
140
+ template = template[1..-1]
141
+ path = Dir.pwd
142
+ end
143
+ filename = template_filename(File.join(path, template), :partial => options.delete(:partial))
144
+ if File.file?(filename)
145
+ parser.parse_file(filename)
146
+ else
147
+ raise "File does not exist #{filename.inspect}"
148
+ end
149
+ end
150
+
151
+ private
152
+
153
+ def template_filename(name, options)
154
+ path = File.dirname(name)
155
+ template = File.basename(name)
156
+ template = "_" + template if options.delete(:partial)
157
+ template += extname(parser.script_filename) unless name =~ /\.[a-z]{3,4}$/
158
+ File.join(path, template)
159
+ end
160
+
161
+ def extname(filename)
162
+ /(\.[a-z]{3,4}\.[a-z]{3,4})$/.match(filename)
163
+ $1 || File.extname(filename) || ''
164
+ end
165
+ end
166
+ end
167
+ end
@@ -1,21 +1,24 @@
1
1
  module Serve #:nodoc:
2
2
  class FileTypeHandler < ::WEBrick::HTTPServlet::AbstractServlet #:nodoc:
3
3
 
4
- def self.extension(extension)
5
- ::WEBrick::HTTPServlet::FileHandler.add_handler(extension, self)
4
+ def self.extension(*extensions)
5
+ extensions.each do |extensions|
6
+ ::WEBrick::HTTPServlet::FileHandler.add_handler(extensions, self)
7
+ end
6
8
  end
7
-
9
+
10
+
8
11
  def initialize(server, name)
9
12
  super
10
13
  @script_filename = name
11
14
  end
12
-
15
+
13
16
  def process(req, res)
14
17
  data = open(@script_filename){|io| io.read }
15
18
  res['content-type'] = content_type
16
19
  res.body = parse(data)
17
20
  end
18
-
21
+
19
22
  def do_GET(req, res)
20
23
  begin
21
24
  process(req, res)
@@ -26,15 +29,15 @@ module Serve #:nodoc:
26
29
  raise ::WEBrick::HTTPStatus::InternalServerError, ex.message
27
30
  end
28
31
  end
29
-
32
+
30
33
  alias do_POST do_GET
31
-
34
+
32
35
  protected
33
-
36
+
34
37
  def content_type
35
38
  'text/html'
36
39
  end
37
-
40
+
38
41
  def parse(string)
39
42
  string.dup
40
43
  end
data/lib/serve/version.rb CHANGED
@@ -2,8 +2,8 @@ module Serve #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 6
6
-
5
+ TINY = 7
6
+
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
9
9
 
data/lib/serve.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'webrick'
2
2
  require 'serve/version'
3
+ require 'serve/application'
3
4
  require 'serve/webrick/extensions'
4
5
  require 'serve/handlers/file_type_handler'
5
6
  require 'serve/handlers/textile_handler'
6
7
  require 'serve/handlers/markdown_handler'
7
- require 'serve/handlers/haml_handler'
8
+ require 'serve/handlers/dynamic_handler'
8
9
  require 'serve/handlers/sass_handler'
9
10
  require 'serve/handlers/email_handler'
10
11
  require 'serve/handlers/redirect_handler'
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Serve::Application do
4
+
5
+ before :each do
6
+ @app = Serve::Application.new
7
+ @defopts = {
8
+ :help => false,
9
+ :help => false,
10
+ :version => false,
11
+ :environment => 'development',
12
+ :port => 4000,
13
+ :address => '0.0.0.0',
14
+ :root => Dir.pwd
15
+ }
16
+ end
17
+
18
+ describe "parsing" do
19
+ it "should parse no arguments" do
20
+ @app.parse([]).should == @defopts
21
+ end
22
+
23
+ it "should parse with only the port" do
24
+ @app.parse(["2000"])[:port].should == "2000"
25
+ end
26
+
27
+ it "should parse with the port and address" do
28
+ @app.parse(["1.1.1.1", "2000"]).should ==
29
+ @defopts.update(:address => "1.1.1.1", :port=>"2000")
30
+ @app.parse(["1.1.1.1:2000"]).should ==
31
+ @defopts.update(:address => "1.1.1.1", :port=>"2000")
32
+ end
33
+
34
+ it "should parse with the port, address, and protocol" do
35
+ @app.parse(["http://1.1.1.1:2000"]).should ==
36
+ @defopts.update(:address => "1.1.1.1", :port=>"2000")
37
+ end
38
+
39
+ it "should parse help" do
40
+ @app.parse([])[:help].should be_false
41
+ @app.parse(["-h"])[:help].should be_true
42
+ @app.parse(["--help"])[:help].should be_true
43
+ end
44
+
45
+ it "should parse version" do
46
+ @app.parse([])[:version].should be_false
47
+ @app.parse(["-v"])[:version].should be_true
48
+ @app.parse(["--version"])[:version].should be_true
49
+ end
50
+
51
+ it "should parse environment" do
52
+ @app.parse([])[:environment].should == "development"
53
+ @app.parse(["production"])[:environment].should == "production"
54
+ @app.parse(["test"])[:environment].should == "test"
55
+ @app.parse(["development"])[:environment].should == "development"
56
+ end
57
+
58
+ it "should parse working directory" do
59
+ @app.parse([])[:root].should == Dir.pwd
60
+ dir = File.dirname(__FILE__)
61
+ @app.parse([dir])[:root].should == File.expand_path(dir)
62
+ end
63
+
64
+ it "should detect invalid arguments" do
65
+ lambda { @app.parse(["--invalid"]) }.should raise_error(Serve::Application::InvalidArgumentsError)
66
+ lambda { @app.parse(["invalid"]) }.should raise_error(Serve::Application::InvalidArgumentsError)
67
+ end
68
+ end
69
+
70
+ describe "running" do
71
+
72
+ end
73
+
74
+ end
data/spec/serve_spec.rb CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
3
3
  describe "Serve" do
4
4
 
5
5
  it "should register all of the file type handlers" do
6
- handlers = ["cgi", "email", "haml", "markdown", "redirect", "rhtml", "sass", "textile"]
6
+ handlers = ["cgi", "email", "erb", "haml", "html.erb", "html.haml", "markdown", "redirect", "rhtml", "sass", "textile"]
7
7
  table = WEBrick::HTTPServlet::FileHandler::HandlerTable
8
8
  table.keys.sort.should == handlers
9
9
  end
data.tar.gz.sig CHANGED
@@ -1 +1 @@
1
- 8�\���:L20[6N����g�~Yad5 �V����t#h$dpQ/�����n��L�
1
+ B4RqPylWCF��)U��79M����+p�1��;%����+u�@
metadata CHANGED
@@ -1,29 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: serve
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.9.6
7
- date: 2008-02-20 00:00:00 -05:00
8
- summary: Serve is a small Ruby script that makes it easy to start up a WEBrick server in any directory. Serve is ideal for HTML prototyping and simple file sharing. If the haml, redcloth, and bluecloth gems are installed serve can handle Haml, Sass, Textile, and Markdown (in addition to HTML).
9
- require_paths:
10
- - lib
11
- email: me@johnwlong.com
12
- homepage: http://serve.rubyforge.org
13
- rubyforge_project: serve
14
- description: Serve is a small Ruby script that makes it easy to start up a WEBrick server in any directory. Serve is ideal for HTML prototyping and simple file sharing. If the haml, redcloth, and bluecloth gems are installed serve can handle Haml, Sass, Textile, and Markdown (in addition to HTML).
4
+ version: 0.9.7
5
+ platform: ruby
6
+ authors:
7
+ - John W. Long
15
8
  autorequire:
16
- default_executable:
17
9
  bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
25
- platform: ruby
26
- signing_key:
27
10
  cert_chain:
28
11
  - |
29
12
  -----BEGIN CERTIFICATE-----
@@ -47,22 +30,36 @@ cert_chain:
47
30
  qXI=
48
31
  -----END CERTIFICATE-----
49
32
 
50
- post_install_message:
51
- authors:
52
- - John W. Long
33
+ date: 2008-07-17 00:00:00 -04:00
34
+ default_executable:
35
+ dependencies: []
36
+
37
+ description: Serve is a small Ruby script that makes it easy to start up a WEBrick server in any directory. Serve is ideal for HTML prototyping and simple file sharing. If the haml, redcloth, and bluecloth gems are installed serve can handle Haml, Sass, Textile, and Markdown (in addition to HTML).
38
+ email: me@johnwlong.com
39
+ executables:
40
+ - serve
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - History.txt
45
+ - License.txt
46
+ - Manifest.txt
47
+ - README.txt
53
48
  files:
54
49
  - History.txt
55
50
  - License.txt
56
51
  - Manifest.txt
52
+ - Quickstart.textile
57
53
  - README.txt
58
54
  - Rakefile
59
55
  - bin/serve
60
56
  - config/hoe.rb
61
57
  - config/requirements.rb
62
58
  - lib/serve.rb
59
+ - lib/serve/application.rb
60
+ - lib/serve/handlers/dynamic_handler.rb
63
61
  - lib/serve/handlers/email_handler.rb
64
62
  - lib/serve/handlers/file_type_handler.rb
65
- - lib/serve/handlers/haml_handler.rb
66
63
  - lib/serve/handlers/markdown_handler.rb
67
64
  - lib/serve/handlers/redirect_handler.rb
68
65
  - lib/serve/handlers/sass_handler.rb
@@ -74,6 +71,7 @@ files:
74
71
  - script/generate
75
72
  - script/txt2html
76
73
  - setup.rb
74
+ - spec/serve_application_spec.rb
77
75
  - spec/serve_spec.rb
78
76
  - spec/spec.opts
79
77
  - spec/spec_helper.rb
@@ -82,21 +80,32 @@ files:
82
80
  - tasks/rspec.rake
83
81
  - tasks/undefine.rake
84
82
  - tasks/website.rake
85
- test_files: []
86
-
83
+ has_rdoc: true
84
+ homepage: http://serve.rubyforge.org
85
+ post_install_message:
87
86
  rdoc_options:
88
87
  - --main
89
88
  - README.txt
90
- extra_rdoc_files:
91
- - History.txt
92
- - License.txt
93
- - Manifest.txt
94
- - README.txt
95
- executables:
96
- - serve
97
- extensions: []
98
-
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ version:
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ version:
99
103
  requirements: []
100
104
 
101
- dependencies: []
105
+ rubyforge_project: serve
106
+ rubygems_version: 1.0.1
107
+ signing_key:
108
+ specification_version: 2
109
+ summary: Serve is a small Ruby script that makes it easy to start up a WEBrick server in any directory. Serve is ideal for HTML prototyping and simple file sharing. If the haml, redcloth, and bluecloth gems are installed serve can handle Haml, Sass, Textile, and Markdown (in addition to HTML).
110
+ test_files: []
102
111
 
metadata.gz.sig CHANGED
Binary file
@@ -1,114 +0,0 @@
1
- module Serve #:nodoc:
2
- class HamlHandler < FileTypeHandler #:nodoc:
3
- extension 'haml'
4
-
5
- def parse(string)
6
- require 'haml'
7
- engine = Haml::Engine.new(string,
8
- :attr_wrapper => '"',
9
- :filename => @script_filename
10
- )
11
- layout = find_layout(@script_filename)
12
- if layout
13
- lines = IO.read(layout)
14
- context = Context.new(Dir.pwd, @script_filename, engine.options.dup)
15
- context.content = engine.render(context) do |*args|
16
- context.get_content_for(*args)
17
- end
18
- layout_engine = Haml::Engine.new(lines, engine.options.dup)
19
- layout_engine.render(context) do |*args|
20
- context.get_content_for(*args)
21
- end
22
- else
23
- engine.render
24
- end
25
- end
26
-
27
- def find_layout(filename)
28
- root = Dir.pwd
29
- path = filename[root.size..-1]
30
- layout = nil
31
- begin
32
- path = File.dirname(path)
33
- l = File.join(root, path, '_layout.haml')
34
- layout = l if File.file?(l)
35
- end until layout or path == "/"
36
- layout
37
- end
38
-
39
- class Context #:nodoc:
40
- attr_accessor :content
41
-
42
- def initialize(root, script_filename, engine_options)
43
- @root, @script_filename, @engine_options = root, script_filename, engine_options
44
- end
45
-
46
- # Content_for methods
47
-
48
- def content_for(symbol, &block)
49
- set_content_for(symbol, capture_haml(&block))
50
- end
51
-
52
- def content_for?(symbol)
53
- !(get_content_for(symbol)).nil?
54
- end
55
-
56
- def get_content_for(symbol = :content)
57
- if symbol.to_s.intern == :content
58
- @content
59
- else
60
- instance_variable_get("@content_for_#{symbol}") || instance_variable_get("@#{symbol}")
61
- end
62
- end
63
-
64
- def set_content_for(symbol, value)
65
- instance_variable_set("@content_for_#{symbol}", value)
66
- end
67
-
68
- # Render methods
69
-
70
- def render(options)
71
- partial = options.delete(:partial)
72
- template = options.delete(:template)
73
- case
74
- when partial
75
- render_partial(partial)
76
- when template
77
- render_template(template)
78
- else
79
- raise "render options not supported #{options.inspect}"
80
- end
81
- end
82
-
83
- def render_partial(partial)
84
- render_template(partial, :partial => true)
85
- end
86
-
87
- def render_template(template, options={})
88
- path = File.dirname(@script_filename)
89
- if template =~ %r{^/}
90
- template = template[1..-1]
91
- path = @root
92
- end
93
- filename = template_filename(File.join(path, template), :partial => options.delete(:partial))
94
- if File.file?(filename)
95
- lines = IO.read(filename)
96
- engine = Haml::Engine.new(lines, @engine_options)
97
- engine.render(self) do |*args|
98
- get_content_for(*args)
99
- end
100
- else
101
- raise "File does not exist #{filename.inspect}"
102
- end
103
- end
104
-
105
- def template_filename(name, options)
106
- path = File.dirname(name)
107
- template = File.basename(name)
108
- template = "_" + template if options.delete(:partial)
109
- template += ".haml" unless name =~ /\.haml$/
110
- File.join(path, template)
111
- end
112
- end
113
- end
114
- end