Skip to content

Commit e3f122b

Browse files
committed
feat(plugin): introduce simple event-based plugin system
1 parent 0e5a763 commit e3f122b

File tree

5 files changed

+82
-0
lines changed

5 files changed

+82
-0
lines changed

lib/rdoc.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,6 @@ def self.home
208208
autoload :Extend, "#{__dir__}/rdoc/code_object/extend"
209209
autoload :Require, "#{__dir__}/rdoc/code_object/require"
210210

211+
autoload :BasePlugin, "#{__dir__}/rdoc/base_plugin"
212+
autoload :EventRegistry, "#{__dir__}/rdoc/event_registry"
211213
end

lib/rdoc/base_plugin.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module RDoc
2+
class BasePlugin
3+
# Register a literner for the given event
4+
5+
def self.listens_to(event_name, &block)
6+
rdoc.event_registry.register(event_name, block)
7+
end
8+
9+
# Activate the plugin with the given RDoc instance
10+
# Without calling this, plugins won't work
11+
12+
def self.activate_with(rdoc = ::RDoc::RDoc.current)
13+
@@rdoc = rdoc
14+
end
15+
16+
def self.rdoc
17+
@@rdoc
18+
end
19+
end
20+
end

lib/rdoc/event_registry.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module RDoc
2+
class EventRegistry
3+
EVENT_TYPES = %i[
4+
rdoc_start
5+
sample
6+
rdoc_store_complete
7+
]
8+
9+
attr_reader :environment
10+
11+
def initialize
12+
@registry = EVENT_TYPES.map { |event_name| [event_name, []] }.to_h
13+
@environment = {}
14+
end
15+
16+
def register(event_name, handler)
17+
@registry[event_name] << handler
18+
end
19+
20+
def trigger(event_name, *args)
21+
@registry[event_name].each do |handler|
22+
handler.call(@environment, *args)
23+
end
24+
end
25+
end
26+
end

lib/rdoc/options.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ class RDoc::Options
268268

269269
attr_accessor :pipe
270270

271+
##
272+
# Currently enabled plugins
273+
274+
attr_reader :plugins
275+
271276
##
272277
# Array of directories to search for files to satisfy an :include:
273278

@@ -395,6 +400,7 @@ def init_ivars # :nodoc:
395400
@coverage_report = false
396401
@op_dir = nil
397402
@page_dir = nil
403+
@plugins = []
398404
@pipe = false
399405
@output_decoration = true
400406
@rdoc_include = []
@@ -436,6 +442,7 @@ def init_with map # :nodoc:
436442
@main_page = map['main_page']
437443
@markup = map['markup']
438444
@op_dir = map['op_dir']
445+
@plugins = map['plugins']
439446
@show_hash = map['show_hash']
440447
@tab_width = map['tab_width']
441448
@template_dir = map['template_dir']
@@ -503,6 +510,7 @@ def == other # :nodoc:
503510
@main_page == other.main_page and
504511
@markup == other.markup and
505512
@op_dir == other.op_dir and
513+
@plugins == other.plugins and
506514
@rdoc_include == other.rdoc_include and
507515
@show_hash == other.show_hash and
508516
@static_path == other.static_path and
@@ -868,6 +876,12 @@ def parse argv
868876

869877
opt.separator nil
870878

879+
opt.on("--plugins=PLUGINS", "-P", Array, "Use plugins") do |value|
880+
@plugins.concat value
881+
end
882+
883+
opt.separator nil
884+
871885
opt.on("--tab-width=WIDTH", "-w", Integer,
872886
"Set the width of tab characters.") do |value|
873887
raise OptionParser::InvalidArgument,
@@ -1344,6 +1358,16 @@ def visibility= visibility
13441358
end
13451359
end
13461360

1361+
# Load plugins specified with options
1362+
# Currently plugin search logic is very simple, but it's not practical.
1363+
# TODO: We will improve this later.
1364+
1365+
def load_plugins
1366+
@plugins.each do |plugin_name|
1367+
require_relative "./#{plugin_name}.rb"
1368+
end
1369+
end
1370+
13471371
##
13481372
# Displays a warning using Kernel#warn if we're being verbose
13491373

lib/rdoc/rdoc.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ class RDoc::RDoc
7171

7272
attr_accessor :store
7373

74+
##
75+
# Event registry for RDoc plugins
76+
77+
attr_accessor :event_registry
78+
7479
##
7580
# Add +klass+ that can generate output after parsing
7681

@@ -105,6 +110,7 @@ def initialize
105110
@options = nil
106111
@stats = nil
107112
@store = nil
113+
@event_registry = ::RDoc::EventRegistry.new
108114
end
109115

110116
##
@@ -449,6 +455,9 @@ def document options
449455
end
450456
@options.finish
451457

458+
::RDoc::BasePlugin.activate_with(self)
459+
@options.load_plugins
460+
452461
@store = RDoc::Store.new(@options)
453462

454463
if @options.pipe then
@@ -469,6 +478,7 @@ def document options
469478
@options.default_title = "RDoc Documentation"
470479

471480
@store.complete @options.visibility
481+
@event_registry.trigger :rdoc_store_complete, @store
472482

473483
@stats.coverage_level = @options.coverage_report
474484

0 commit comments

Comments
 (0)