Skip to content

Commit

Permalink
Add --core-ext option
Browse files Browse the repository at this point in the history
The `--core-ext` option can be used to indicate files that define core
extensions.  It accepts a regular expression pattern.  If a module is
defined exclusively in files that match the pattern, the module will be
designated as a core extension and will be listed separately in the main
page nav.

The default value for `--core-ext` is `/core_ext/` which matches Rails'
core extension files in `activesupport/lib/active_support/core_ext/`.
  • Loading branch information
jonathanhefner committed Oct 5, 2023
1 parent 369f964 commit 6f29801
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
23 changes: 17 additions & 6 deletions lib/rdoc/generator/template/rails/_index_nav.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@
<%= outline(@context) %>
</div>

<div class="nav__heading">Modules</div>
<ul class="nav__list">
<% top_modules(@context.store).each do |rdoc_module| %>
<li><%= link_to rdoc_module %></li>
<% end %>
</ul>
<% unless (modules = top_modules(@context.store)).empty? %>
<div class="nav__heading">Modules</div>
<ul class="nav__list">
<% modules.each do |rdoc_module| %>
<li><%= link_to rdoc_module %></li>
<% end %>
</ul>
<% end %>

<% unless (extensions = core_extensions(@context.store)).empty? %>
<div class="nav__heading">Core Extensions</div>
<ul class="nav__list">
<% extensions.each do |rdoc_module| %>
<li><%= link_to rdoc_module %></li>
<% end %>
</ul>
<% end %>
12 changes: 12 additions & 0 deletions lib/sdoc/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
require "sdoc/version"

class RDoc::Options
attr_writer :core_ext_pattern

def core_ext_pattern
@core_ext_pattern ||= /core_ext/
end

attr_accessor :github
attr_accessor :search_index
end
Expand Down Expand Up @@ -38,6 +44,12 @@ def self.setup_options(options)
opt.separator nil
opt.separator "SDoc generator options:"

opt.separator nil
opt.on("--core-ext=PATTERN", Regexp, "Regexp pattern indicating files that define core extensions. " \
"Defaults to 'core_ext'.") do |pattern|
options.core_ext_pattern = pattern
end

opt.separator nil
opt.on("--github", "-g",
"Generate links to github.") do |value|
Expand Down
19 changes: 19 additions & 0 deletions lib/sdoc/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,30 @@ def more_less_ul(items, limit)
end

def top_modules(rdoc_store)
_top_modules(rdoc_store).reject { |rdoc_module| _core_ext?(rdoc_module) }
end

def core_extensions(rdoc_store)
_top_modules(rdoc_store).select { |rdoc_module| _core_ext?(rdoc_module) }
end

def _top_modules(rdoc_store)
rdoc_store.all_classes_and_modules.select do |rdoc_module|
!rdoc_module.full_name.include?("::")
end.sort
end

def _core_ext?(rdoc_module)
# HACK There is currently a bug in RDoc v6.5.0 that causes the value of
# RDoc::ClassModule#in_files for `Object` to become polluted. The cause is
# unclear, but it might be related to setting global constants (for example,
# setting `APP_PATH = "..."` outside of a class or module). To work around
# this bug, we always treat `Object` as a core extension.
rdoc_module.full_name == "Object" ||

rdoc_module.in_files.all? { |rdoc_file| @options.core_ext_pattern.match?(rdoc_file.full_name) }
end

def module_breadcrumbs(rdoc_module)
parent_names = rdoc_module.full_name.split("::")[0...-1]

Expand Down
26 changes: 26 additions & 0 deletions spec/helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,32 @@ module Bar::Fuga; end
_(@helpers.top_modules(top_level.store)).
must_equal [top_level.find_module_named("Bar"), top_level.find_module_named("Foo")]
end

it "excludes core extensions (based on options.core_ext_pattern)" do
top_level = rdoc_top_level_for <<~RUBY
module Foo; end
RUBY

@helpers.options.core_ext_pattern = /#{Regexp.escape top_level.name}/

_(@helpers.top_modules(top_level.store)).must_be_empty
end
end

describe "#core_extensions" do
it "returns top-level core extensions in sorted order (based on options.core_ext_pattern)" do
top_level = rdoc_top_level_for <<~RUBY
class Foo; module Hoge; end; end
module Bar; class Fuga; end; end
RUBY

_(@helpers.core_extensions(top_level.store)).must_be_empty

@helpers.options.core_ext_pattern = /#{Regexp.escape top_level.name}/

_(@helpers.core_extensions(top_level.store)).
must_equal [top_level.find_module_named("Bar"), top_level.find_module_named("Foo")]
end
end

describe "#module_breadcrumbs" do
Expand Down
10 changes: 10 additions & 0 deletions spec/rdoc_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ def parse_options(*options)
end
end

describe "options.core_ext_pattern" do
it "is /core_ext/ by default" do
_(parse_options().core_ext_pattern).must_equal %r"core_ext"
end

it "can be set via --core-ext" do
_(parse_options("--core-ext", "foo.*bar").core_ext_pattern).must_equal %r"foo.*bar"
end
end

describe "options.github" do
it "is disabled by default" do
_(parse_options().github).must_be_nil
Expand Down

0 comments on commit 6f29801

Please sign in to comment.