Skip to content

Make it loose coupling between RubyGems and RDoc #1171

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

Merged
merged 14 commits into from
Dec 13, 2024
62 changes: 56 additions & 6 deletions lib/rdoc/rubygems_hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
require 'fileutils'
require_relative '../rdoc'

##
# Gem::RDoc provides methods to generate RDoc and ri data for installed gems
# upon gem installation.
# We define the following two similar name classes in this file:
#
# This file is automatically required by RubyGems 1.9 and newer.
# - RDoc::RubyGemsHook
# - RDoc::RubygemsHook
#
# RDoc::RubyGemsHook is the main class that has real logic.
#
# RDoc::RubygemsHook is a class that is only for
# compatibility. RDoc::RubygemsHook is used by RubyGems directly. We
# can remove this when all maintained RubyGems remove
# `rubygems/rdoc.rb`.

class RDoc::RubygemsHook
class RDoc::RubyGemsHook

include Gem::UserInteraction
extend Gem::UserInteraction
Expand Down Expand Up @@ -45,7 +51,7 @@ class << self
# Post installs hook that generates documentation for each specification in
# +specs+

def self.generation_hook installer, specs
def self.generate installer, specs
start = Time.now
types = installer.document

Expand All @@ -64,6 +70,10 @@ def self.generation_hook installer, specs
say "Done installing documentation for #{names} after #{duration} seconds"
end

def self.remove uninstaller
new(uninstaller.spec).remove
end

##
# Loads the RDoc generator

Expand Down Expand Up @@ -246,3 +256,43 @@ def setup
end

end

# This class is referenced by RubyGems to create documents.
# All implementations are moved to the above RubyGemsHook.
#
# This class does nothing when this RDoc is installed as a normal gem
# or a bundled gem.
#
# This class does generate/remove documents for compatibility when
# this RDoc is installed as a default gem.
#
# We can remove this when all maintained RubyGems remove
# `rubygems/rdoc.rb`.
module RDoc
class RubygemsHook
def self.default_gem?
!File.exist?(File.join(__dir__, "..", "rubygems_plugin.rb"))
end

def initialize(spec)
@spec = spec
end

def remove
# Do nothing if this is NOT a default gem.
return unless self.class.default_gem?

# Remove generated document for compatibility if this is a
# default gem.
RubyGemsHook.new(@spec).remove
end

def self.generation_hook installer, specs
# Do nothing if this is NOT a default gem.
return unless default_gem?

# Generate document for compatibility if this is a default gem.
RubyGemsHook.generate(installer, specs)
end
end
end
23 changes: 23 additions & 0 deletions lib/rubygems_plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true
Copy link
Member

Choose a reason for hiding this comment

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

Can we add comments to explain when and by what this file will be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added comment.
Can you check that?


# If this file is exist, RDoc generates and removes documents by rubygems plugins.
#
# In follwing cases,
# RubyGems directly exectute RDoc::RubygemsHook.generation_hook and RDoc::RubygemsHook#remove to generate and remove documents.
#
# - RDoc is used as a default gem.
# - RDoc is a old version that doesn't have rubygems_plugin.rb.

require_relative 'rdoc/rubygems_hook'

# To install dependency libraries of RDoc, you need to run bundle install.
# At that time, rdoc/markdown is not generated.
# If generate and remove are executed at that time, an error will occur.
# So, we can't register generate and remove to Gem at that time.
Copy link
Member

Choose a reason for hiding this comment

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

I don't quite understand what this comment intends to express. Do you mind elaborate it a bit more?

begin
require_relative 'rdoc/markdown'
Copy link
Member

Choose a reason for hiding this comment

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

rdoc/rd/block_parser and rdoc/rd/inline_parser have similar problems to markdown too.

Copy link
Member

Choose a reason for hiding this comment

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

Right.
We can use one of rdoc/markdown, rdoc/rd/block_parser or rdoc/rd/inline_parser here.
This just wants to fix a bootstrap problem.

We want to run bundle install when we start developing cloned ruby/rdoc.
In the time, this lib/rubygems_plugin.rb is used. But RDoc isn't ready yet because rdoc/markdown.rb and so on aren't generated yet. So bundle install is failed.

This disables this lib/rubygems_plugin.rb only when the initial bundle install to fix the bootstrap problem.

rescue LoadError
else
Gem.done_installing(&RDoc::RubyGemsHook.method(:generate))
Gem.pre_uninstall(&RDoc::RubyGemsHook.method(:remove))
end
8 changes: 4 additions & 4 deletions test/rdoc/test_rdoc_rubygems_hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require_relative '../../lib/rdoc/rubygems_hook'
require 'test/unit'

class TestRDocRubygemsHook < Test::Unit::TestCase
class TestRDocRubyGemsHook < Test::Unit::TestCase
def setup
@a = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
Expand Down Expand Up @@ -40,10 +40,10 @@ def setup
FileUtils.touch File.join(@tempdir, 'a-2', 'lib', 'a.rb')
FileUtils.touch File.join(@tempdir, 'a-2', 'README')

@hook = RDoc::RubygemsHook.new @a
@hook = RDoc::RubyGemsHook.new @a

begin
RDoc::RubygemsHook.load_rdoc
RDoc::RubyGemsHook.load_rdoc
rescue Gem::DocumentError => e
omit e.message
end
Expand All @@ -63,7 +63,7 @@ def test_initialize
refute @hook.generate_rdoc
assert @hook.generate_ri

rdoc = RDoc::RubygemsHook.new @a, false, false
rdoc = RDoc::RubyGemsHook.new @a, false, false

refute rdoc.generate_rdoc
refute rdoc.generate_ri
Expand Down
Loading