Class: Jekyll::Commands::Serve

Inherits:
Jekyll::Command show all
Defined in:
lib/jekyll/commands/serve.rb

Class Method Summary collapse

Methods inherited from Jekyll::Command

add_build_options, configuration_from_options, inherited, process_site, subclasses

Class Method Details

.custom_file_handlerObject

Custom WEBrick FileHandler servlet for serving “/file.html” at “/file” when no exact match is found. This mirrors the behavior of GitHub Pages and many static web server configs.


105
106
107
108
109
110
111
112
113
114
115
# File 'lib/jekyll/commands/serve.rb', line 105

def custom_file_handler
  Class.new WEBrick::HTTPServlet::FileHandler do
    def search_file(req, res, basename)
      if file = super
        file
      else
        super(req, res, "#{basename}.html")
      end
    end
  end
end

.file_handler_optionsObject

recreate NondisclosureName under utf-8 circumstance


140
141
142
143
144
145
# File 'lib/jekyll/commands/serve.rb', line 140

def file_handler_options
  WEBrick::Config::FileHandler.merge({
    :FancyIndexing     => true,
    :NondisclosureName => ['.ht*','~*']
  })
end

.init_with_program(prog) ⇒ Object


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/jekyll/commands/serve.rb', line 8

def init_with_program(prog)
  prog.command(:serve) do |c|
    c.syntax 'serve [options]'
    c.description 'Serve your site locally'
    c.alias :server
    c.alias :s

    add_build_options(c)

    c.option 'detach', '-B', '--detach', 'Run the server in the background (detach)'
    c.option 'port', '-P', '--port [PORT]', 'Port to listen on'
    c.option 'host', '-H', '--host [HOST]', 'Host to bind to'
    c.option 'baseurl', '-b', '--baseurl [URL]', 'Base URL'
    c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'

    c.action do |args, options|
      options["serving"] = true
      options["watch"] = true unless options.key?("watch")
      Jekyll::Commands::Build.process(options)
      Jekyll::Commands::Serve.process(options)
    end
  end
end

.mime_typesObject


123
124
125
126
# File 'lib/jekyll/commands/serve.rb', line 123

def mime_types
  mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
  WEBrick::HTTPUtils::load_mime_types(mime_types_file)
end

.process(options) ⇒ Object

Boot up a WEBrick server which points to the compiled site's root.


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jekyll/commands/serve.rb', line 33

def process(options)
  options = configuration_from_options(options)
  destination = options['destination']
  setup(destination)

  s = WEBrick::HTTPServer.new(webrick_options(options))
  s.unmount("")

  s.mount(
    options['baseurl'],
    custom_file_handler,
    destination,
    file_handler_options
  )

  Jekyll.logger.info "Server address:", server_address(s, options)

  if options['detach'] # detach the server
    pid = Process.fork { s.start }
    Process.detach(pid)
    Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
  else # create a new server thread, then join it with current terminal
    t = Thread.new { s.start }
    trap("INT") { s.shutdown }
    t.join
  end
end

.server_address(server, options) ⇒ Object


128
129
130
131
132
133
134
135
136
137
# File 'lib/jekyll/commands/serve.rb', line 128

def server_address(server, options)
  baseurl = "#{options['baseurl']}/" if options['baseurl']
  [
    "http://",
    server.config[:BindAddress],
    ":",
    server.config[:Port],
    baseurl || ""
  ].map(&:to_s).join("")
end

.setup(destination) ⇒ Object


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/jekyll/commands/serve.rb', line 61

def setup(destination)
  require 'webrick'

  FileUtils.mkdir_p(destination)

  # monkey patch WEBrick using custom 404 page (/404.html)
  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) ⇒ Object


117
118
119
120
121
# File 'lib/jekyll/commands/serve.rb', line 117

def start_callback(detached)
  unless detached
    Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
  end
end

.webrick_options(config) ⇒ Object


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/jekyll/commands/serve.rb', line 77

def webrick_options(config)
  opts = {
    :BindAddress        => config['host'],
    :DirectoryIndex     => %w(index.html index.htm index.cgi index.rhtml index.xml),
    :DocumentRoot       => config['destination'],
    :DoNotReverseLookup => true,
    :MimeTypes          => mime_types,
    :Port               => config['port'],
    :StartCallback      => start_callback(config['detach'])
  }

  if config['verbose']
    opts.merge!({
      :Logger => WEBrick::Log.new($stdout, WEBrick::Log::DEBUG)
    })
  else
    opts.merge!({
      :AccessLog => [],
      :Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
    })
  end

  opts
end