From 3b4feb41f0a2e767b18d26f01d1a3d3a0fc28713 Mon Sep 17 00:00:00 2001 From: Tom Bell Date: Tue, 18 Dec 2012 21:00:24 +0000 Subject: [PATCH] Add initial serve command The `ServeCommand` will let you serve your site locally for development. You can specify `--port`, `--host` and `--baseurl` options if you wish to change the defaults. Additionally the `BuildCommand` will be called before the processing of the serve command, this makes sure that the site is actually built. This means you are able to pass the `--watch` option to auto-regenerate your site, even while serving it locally. --- bin/jekyll2 | 29 +++++++++++++++++++++++++++++ lib/jekyll/commands/build.rb | 31 ++++++++++++++++++------------- lib/jekyll/commands/serve.rb | 28 ++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 lib/jekyll/commands/serve.rb diff --git a/bin/jekyll2 b/bin/jekyll2 index ce85f13b..d99ba866 100755 --- a/bin/jekyll2 +++ b/bin/jekyll2 @@ -29,3 +29,32 @@ command :build do |c| Jekyll::BuildCommand.process(options) end end + +# Serve command +# +# Args: +# --source +# --destination +# --watch +# +# --port +# --host +# --baseurl +command :serve do |c| + c.syntax = 'jekyll serve [options]' + c.description = 'Serve...' + c.option '-w', '--watch', 'Watch for changes and rebuild' + c.option '-p', '--port [PORT]', 'Port to listen on' + c.option '-h', '--host [HOST]', 'Host to bind to' + c.option '-b', '--baseurl [URL]', 'Base URL' + c.action do |args, options| + options.default :watch => false, + :port => '4000', + :host => '0.0.0.0', + :baseurl => '/', + :serving => true + + Jekyll::BuildCommand.process(options) + Jekyll::ServeCommand.process(options) + end +end diff --git a/lib/jekyll/commands/build.rb b/lib/jekyll/commands/build.rb index 074f5d49..2ff8aa80 100644 --- a/lib/jekyll/commands/build.rb +++ b/lib/jekyll/commands/build.rb @@ -14,20 +14,21 @@ module Jekyll destination = opts['destination'] if opts['watch'] - self.watch(site, source, destination) + self.watch(site, opts) else - self.build(site, source, destination) + self.build(site, opts) end end # Private: Build the site from source into destination. # # site - A Jekyll::Site instance - # source - A String of the source path - # destination - A String of the destination path + # options - A Hash of options passed to the command # # Returns nothing. - def self.build(site, source, destination) + def self.build(site, options) + source = options['source'] + destination = options['destination'] puts "Building site: #{source} -> #{destination}" begin site.process @@ -44,13 +45,15 @@ module Jekyll # Private: Watch for file changes and rebuild the site. # # site - A Jekyll::Site instance - # source - A String of the source path - # destination - A String of the destination path + # options - A Hash of options passed to the command # # Returns nothing. - def self.watch(site, source, destination) + def self.watch(site, options) require 'directory_watcher' + source = options['source'] + destination = options['destination'] + puts "Auto-Regenerating enabled: #{source} -> #{destination}" dw = DirectoryWatcher.new(source) @@ -65,12 +68,14 @@ module Jekyll dw.start - trap("SIGINT") do - puts "Stopping auto-regeneration..." - exit 0 - end + unless options['serving'] + loop { sleep 1000 } - loop { sleep 1000 } + trap("INT") do + puts "Stopping auto-regeneration..." + exit 0 + end + end end end diff --git a/lib/jekyll/commands/serve.rb b/lib/jekyll/commands/serve.rb new file mode 100644 index 00000000..665a26cf --- /dev/null +++ b/lib/jekyll/commands/serve.rb @@ -0,0 +1,28 @@ +module Jekyll + + class ServeCommand < Command + def self.process(options) + require 'webrick' + include WEBrick + + destination = options.destination + + FileUtils.mkdir_p(destination) + + mime_types = WEBrick::HTTPUtils::DefaultMimeTypes + mime_types.store 'js', 'application/javascript' + + s = HTTPServer.new( + :Port => options.port, + :BindAddress => options.host, + :MimeTypes => mime_types + ) + + s.mount(options.baseurl, HTTPServlet::FileHandler, destination) + t = Thread.new { s.start } + trap("INT") { s.shutdown } + t.join() + end + end + +end