class Jekyll::Commands::Serve

Constants

COMMAND_OPTIONS

Public Class Methods

init_with_program(prog) click to toggle source
# File lib/jekyll/commands/serve.rb, line 19
def init_with_program(prog)
  prog.command(:serve) do |cmd|
    cmd.description "Serve your site locally"
    cmd.syntax "serve [options]"
    cmd.alias :server
    cmd.alias :s

    add_build_options(cmd)
    COMMAND_OPTIONS.each do |key, val|
      cmd.option key, *val
    end

    cmd.action do |_, opts|
      opts["serving"] = true
      opts["watch"  ] = true unless opts.key?("watch")
      Build.process(opts)
      Serve.process(opts)
    end
  end
end
process(opts) click to toggle source
# File lib/jekyll/commands/serve.rb, line 42
def process(opts)
  opts = configuration_from_options(opts)
  destination = opts["destination"]
  setup(destination)

  server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
  server.mount(opts["baseurl"], Servlet, destination, file_handler_opts)
  Jekyll.logger.info "Server address:", server_address(server, opts)
  launch_browser server, opts if opts["open_url"]
  boot_or_detach server, opts
end

Private Class Methods

boot_or_detach(server, opts) click to toggle source

Keep in our area with a thread or detach the server as requested by the user. This method determines what we do based on what you ask us to do.

# File lib/jekyll/commands/serve.rb, line 143
def boot_or_detach(server, opts)
  if opts["detach"]
    pid = Process.fork do
      server.start
    end

    Process.detach(pid)
    Jekyll.logger.info "Server detached with pid '#{pid}'.",                "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
  else
    t = Thread.new { server.start }
    trap("INT") { server.shutdown }
    t.join
  end
end
create_error_page() click to toggle source
# File lib/jekyll/commands/serve.rb, line 65
def create_error_page
  @header["Content-Type"] = "text/html; charset=UTF-8"
  @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
end
enable_logging(opts) click to toggle source

Make the stack verbose if the user requests it.

# File lib/jekyll/commands/serve.rb, line 162
def enable_logging(opts)
  opts[:AccessLog] = []
  level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
  opts[:Logger] = WEBrick::Log.new($stdout, level)
end
enable_ssl(opts) click to toggle source

Add SSL to the stack if the user triggers –enable-ssl and they provide both types of certificates commonly needed. Raise if they forget to add one of the certificates.

# File lib/jekyll/commands/serve.rb, line 173
def enable_ssl(opts)
  return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
  if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
    raise RuntimeError, "--ssl-cert or --ssl-key missing."
  end

  require "openssl"
  require "webrick/https"
  source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_key" ])
  source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_cert"])
  opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(source_certificate))
  opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
  opts[:SSLEnable] = true
end
file_handler_opts() click to toggle source

Recreate NondisclosureName under utf-8 circumstance

# File lib/jekyll/commands/serve.rb, line 102
def file_handler_opts
  WEBrick::Config::FileHandler.merge({
    :FancyIndexing     => true,
    :NondisclosureName => [
      '.ht*', '~*'
    ]
  })
end
launch_browser(server, opts) click to toggle source
# File lib/jekyll/commands/serve.rb, line 126
def launch_browser(server, opts)
  command =
    if Utils::Platforms.windows?
      "start"
    elsif Utils::Platforms.osx?
      "open"
    else
      "xdg-open"
    end
  system command, server_address(server, opts)
end
mime_types() click to toggle source
# File lib/jekyll/commands/serve.rb, line 198
def mime_types
  file = File.expand_path('../mime.types', File.dirname(__FILE__))
  WEBrick::HTTPUtils.load_mime_types(file)
end
server_address(server, opts) click to toggle source
# File lib/jekyll/commands/serve.rb, line 114
def server_address(server, opts)
  "%{prefix}://%{address}:%{port}%{baseurl}" % {
    :prefix => server.config[:SSLEnable] ? "https" : "http",
    :baseurl => opts["baseurl"] ? "#{opts["baseurl"]}/" : "",
    :address => server.config[:BindAddress],
    :port => server.config[:Port]
  }
end
setup(destination) click to toggle source

Do a base pre-setup of WEBRick so that everything is in place when we get ready to party, checking for an setting up an error page and making sure our destination exists.

# File lib/jekyll/commands/serve.rb, line 59
def setup(destination)
  require_relative "serve/servlet"

  FileUtils.mkdir_p(destination)
  if File.exist?(File.join(destination, "404.html"))
    WEBrick::HTTPResponse.class_eval do
      def create_error_page
        @header["Content-Type"] = "text/html; charset=UTF-8"
        @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
      end
    end
  end
end
start_callback(detached) click to toggle source
# File lib/jekyll/commands/serve.rb, line 189
def start_callback(detached)
  unless detached
    proc do
      Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
    end
  end
end
webrick_opts(opts) click to toggle source
# File lib/jekyll/commands/serve.rb, line 76
def webrick_opts(opts)
  opts = {
    :JekyllOptions      => opts,
    :DoNotReverseLookup => true,
    :MimeTypes          => mime_types,
    :DocumentRoot       => opts["destination"],
    :StartCallback      => start_callback(opts["detach"]),
    :BindAddress        => opts["host"],
    :Port               => opts["port"],
    :DirectoryIndex     => %W(
      index.htm
      index.html
      index.rhtml
      index.cgi
      index.xml
    )
  }

  enable_ssl(opts)
  enable_logging(opts)
  opts
end