Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic server mode support #1151

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ group :development do
gem 'rubocop', '>= 1.31.0'
gem 'gettext'
gem 'prism', '>= 0.30.0'
gem 'webrick'
end
2 changes: 1 addition & 1 deletion lib/rdoc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,12 @@ def self.home
autoload :Generator, "#{__dir__}/rdoc/generator"
autoload :Options, "#{__dir__}/rdoc/options"
autoload :Parser, "#{__dir__}/rdoc/parser"
autoload :Servlet, "#{__dir__}/rdoc/servlet"
autoload :RI, "#{__dir__}/rdoc/ri"
autoload :Stats, "#{__dir__}/rdoc/stats"
autoload :Store, "#{__dir__}/rdoc/store"
autoload :Task, "#{__dir__}/rdoc/task"
autoload :Text, "#{__dir__}/rdoc/text"
autoload :Server, "#{__dir__}/rdoc/server"

autoload :Markdown, "#{__dir__}/rdoc/markdown"
autoload :Markup, "#{__dir__}/rdoc/markup"
Expand Down
23 changes: 18 additions & 5 deletions lib/rdoc/generator/darkfish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,19 +238,21 @@ def write_style_sheet
# Build the initial indices and output objects based on an array of TopLevel
# objects containing the extracted information.

def generate
def generate(server_mode: false)
setup

write_style_sheet
generate_index
generate_class_files
generate_file_files
generate_table_of_contents
@json_index.generate
@json_index.generate_gzipped

copy_static

unless server_mode
# For the server, we only generate the JSON index if requested
@json_index.generate
@json_index.generate_gzipped
copy_static
end
rescue => e
debug_msg "%s: %s\n %s" % [
e.class.name, e.message, e.backtrace.join("\n ")
Expand Down Expand Up @@ -608,12 +610,23 @@ def setup

return unless @store

update_data_from_store
end

def update_data_from_store
@classes = @store.all_classes_and_modules.sort
@files = @store.all_files.sort
@methods = @classes.flat_map { |m| m.method_list }.sort
@modsort = get_sorted_module_list @classes
end

def clear_data
@classes.clear if @classes
@files.clear if @files
@methods.clear if @methods
@modsort.clear if @modsort
end

##
# Return a string describing the amount of time in the given number of
# seconds in terms a human can understand easily.
Expand Down
15 changes: 15 additions & 0 deletions lib/rdoc/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ class RDoc::Options

attr_reader :visibility

##
# The server's port to listen on. `nil` or `false` means the server is disabled.

attr_reader :server_port

##
# Indicates if files of test suites should be skipped
attr_accessor :skip_tests
Expand Down Expand Up @@ -392,6 +397,7 @@ def init_ivars # :nodoc:
@encoding = Encoding::UTF_8
@charset = @encoding.name
@skip_tests = true
@server_port = false
end

def init_with map # :nodoc:
Expand Down Expand Up @@ -1116,6 +1122,15 @@ def parse argv

opt.separator nil

opt.on(
"--server[=PORT]",
Integer,
"[Experimental] Run WEBrick server with generated documentation.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel we can remove the [Experiment] flag, we're not shipping something we're not expecting will work or introduce any breaking changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My interpretation of "experimental" is: the feature works but may not live up to expectation at the moment and has a slight chance to be removed if it's proven problematic.

In this case, I don't expect it to be removed later but it doesn't have the maturity to work like yard server or some static site generators' server mode.

"Uses port 4000 by default. Will use ./tmp for file output."
) do |port|
@server_port = port || 4000
end

opt.on("--help", "-h", "Display this help") do
RDoc::RDoc::GENERATORS.each_key do |generator|
setup_generator generator
Expand Down
36 changes: 34 additions & 2 deletions lib/rdoc/rdoc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

require 'find'
require 'fileutils'
require 'tmpdir'
require 'pathname'
require 'time'

Expand Down Expand Up @@ -463,7 +464,7 @@ def document options
exit
end

unless @options.coverage_report then
unless @options.coverage_report || @options.server_port
@last_modified = setup_output_dir @options.op_dir, @options.force_update
end

Expand Down Expand Up @@ -496,9 +497,16 @@ def document options

@generator = gen_klass.new @store, @options

generate
if @options.server_port
start_server
else
generate
end
end

# Don't need to run stats for server mode
return if @options.server_port

if @stats and (@options.coverage_report or not @options.quiet) then
puts
puts @stats.summary.accept RDoc::Markup::ToRdoc.new
Expand All @@ -507,6 +515,30 @@ def document options
exit @stats.fully_documented? if @options.coverage_report
end

def start_server
begin
require 'webrick'
rescue LoadError
abort "webrick is not found. You may need to `gem install webrick` to install webrick."
end

tmp_dir = Dir.mktmpdir

# Change the output directory to tmp so it doesn't overwrite the current documentation
Dir.chdir tmp_dir do
server = WEBrick::HTTPServer.new Port: @options.server_port

server.mount '/', RDoc::Server, self

trap 'INT' do server.shutdown end
trap 'TERM' do server.shutdown end

server.start
end
ensure
FileUtils.remove_entry tmp_dir
end

##
# Generates documentation for +file_info+ (from #parse_files) into the
# output dir using the generator selected
Expand Down
7 changes: 4 additions & 3 deletions lib/rdoc/ri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ module RDoc::RI

class Error < RDoc::Error; end

autoload :Driver, "#{__dir__}/ri/driver"
autoload :Paths, "#{__dir__}/ri/paths"
autoload :Store, "#{__dir__}/ri/store"
autoload :Driver, "#{__dir__}/ri/driver"
autoload :Paths, "#{__dir__}/ri/paths"
autoload :Store, "#{__dir__}/ri/store"
autoload :Servlet, "#{__dir__}/ri/servlet"

end
2 changes: 1 addition & 1 deletion lib/rdoc/ri/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,7 @@ def start_server

extra_doc_dirs = @stores.map {|s| s.type == :extra ? s.path : nil}.compact

server.mount '/', RDoc::Servlet, nil, extra_doc_dirs
server.mount '/', RDoc::RI::Servlet, nil, extra_doc_dirs

trap 'INT' do server.shutdown end
trap 'TERM' do server.shutdown end
Expand Down
10 changes: 5 additions & 5 deletions lib/rdoc/servlet.rb → lib/rdoc/ri/servlet.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true
require_relative '../rdoc'
require_relative '../../rdoc'
require 'erb'
require 'time'
require 'json'
Expand All @@ -24,14 +24,14 @@
#
# server = WEBrick::HTTPServer.new Port: 8000
#
# server.mount '/', RDoc::Servlet
# server.mount '/', RDoc::RI::Servlet
#
# If you want to mount the servlet some other place than the root, provide the
# base path when mounting:
#
# server.mount '/rdoc', RDoc::Servlet, '/rdoc'
# server.mount '/rdoc', RDoc::RI::Servlet, '/rdoc'

class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet
class RDoc::RI::Servlet < WEBrick::HTTPServlet::AbstractServlet

@server_stores = Hash.new { |hash, server| hash[server] = {} }
@cache = Hash.new { |hash, store| hash[store] = {} }
Expand Down Expand Up @@ -146,7 +146,7 @@ def do_GET req, res
# Fills in +res+ with the class, module or page for +req+ from +store+.
#
# +path+ is relative to the mount_path and is used to determine the class,
# module or page name (/RDoc/Servlet.html becomes RDoc::Servlet).
# module or page name (/RDoc/RI.html becomes RDoc::RI).
# +generator+ is used to create the page.

def documentation_page store, generator, path, req, res
Expand Down
Loading