-
Notifications
You must be signed in to change notification settings - Fork 438
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from kou/add-rubygems-hook-default-gem
Add support for the case that RDoc is installed as a default gem
- Loading branch information
Showing
2 changed files
with
291 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,300 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rubygems/user_interaction' | ||
require 'fileutils' | ||
|
||
require_relative '../rdoc' | ||
|
||
# We define the following two similar name classes in this file: | ||
# | ||
# - 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 | ||
|
||
include Gem::UserInteraction | ||
extend Gem::UserInteraction | ||
|
||
@rdoc_version = nil | ||
@specs = [] | ||
|
||
## | ||
# Force installation of documentation? | ||
|
||
attr_accessor :force | ||
|
||
## | ||
# Generate rdoc? | ||
|
||
attr_accessor :generate_rdoc | ||
|
||
## | ||
# Generate ri data? | ||
|
||
attr_accessor :generate_ri | ||
|
||
class << self | ||
|
||
## | ||
# Loaded version of RDoc. Set by ::load_rdoc | ||
|
||
attr_reader :rdoc_version | ||
|
||
end | ||
|
||
## | ||
# Post installs hook that generates documentation for each specification in | ||
# +specs+ | ||
|
||
def self.generate installer, specs | ||
start = Time.now | ||
types = installer.document | ||
|
||
generate_rdoc = types.include? 'rdoc' | ||
generate_ri = types.include? 'ri' | ||
|
||
specs.each do |spec| | ||
new(spec, generate_rdoc, generate_ri).generate | ||
end | ||
|
||
return unless generate_rdoc or generate_ri | ||
|
||
duration = (Time.now - start).to_i | ||
names = specs.map(&:name).join ', ' | ||
|
||
say "Done installing documentation for #{names} after #{duration} seconds" | ||
end | ||
|
||
def self.remove uninstaller | ||
new(uninstaller.spec).remove | ||
end | ||
|
||
## | ||
# Loads the RDoc generator | ||
|
||
def self.load_rdoc | ||
return if @rdoc_version | ||
|
||
require_relative 'rdoc' | ||
|
||
@rdoc_version = Gem::Version.new ::RDoc::VERSION | ||
end | ||
|
||
## | ||
# Creates a new documentation generator for +spec+. RDoc and ri data | ||
# generation can be enabled or disabled through +generate_rdoc+ and | ||
# +generate_ri+ respectively. | ||
# | ||
# Only +generate_ri+ is enabled by default. | ||
|
||
def initialize spec, generate_rdoc = false, generate_ri = true | ||
@doc_dir = spec.doc_dir | ||
@force = false | ||
@rdoc = nil | ||
@spec = spec | ||
|
||
@generate_rdoc = generate_rdoc | ||
@generate_ri = generate_ri | ||
|
||
@rdoc_dir = spec.doc_dir 'rdoc' | ||
@ri_dir = spec.doc_dir 'ri' | ||
end | ||
|
||
## | ||
# Removes legacy rdoc arguments from +args+ | ||
#-- | ||
# TODO move to RDoc::Options | ||
|
||
def delete_legacy_args args | ||
args.delete '--inline-source' | ||
args.delete '--promiscuous' | ||
args.delete '-p' | ||
args.delete '--one-file' | ||
end | ||
|
||
## | ||
# Generates documentation using the named +generator+ ("darkfish" or "ri") | ||
# and following the given +options+. | ||
# | ||
# Documentation will be generated into +destination+ | ||
|
||
def document generator, options, destination | ||
generator_name = generator | ||
|
||
options = options.dup | ||
options.exclude ||= [] # TODO maybe move to RDoc::Options#finish | ||
options.setup_generator generator | ||
options.op_dir = destination | ||
Dir.chdir @spec.full_gem_path do | ||
options.finish | ||
end | ||
|
||
generator = options.generator.new @rdoc.store, options | ||
|
||
@rdoc.options = options | ||
@rdoc.generator = generator | ||
|
||
say "Installing #{generator_name} documentation for #{@spec.full_name}" | ||
|
||
FileUtils.mkdir_p options.op_dir | ||
|
||
Dir.chdir options.op_dir do | ||
begin | ||
@rdoc.class.current = @rdoc | ||
@rdoc.generator.generate | ||
ensure | ||
@rdoc.class.current = nil | ||
end | ||
end | ||
end | ||
|
||
## | ||
# Generates RDoc and ri data | ||
|
||
def generate | ||
return if @spec.default_gem? | ||
return unless @generate_ri or @generate_rdoc | ||
|
||
setup | ||
|
||
options = nil | ||
|
||
args = @spec.rdoc_options | ||
args.concat @spec.source_paths | ||
args.concat @spec.extra_rdoc_files | ||
|
||
case config_args = Gem.configuration[:rdoc] | ||
when String then | ||
args = args.concat config_args.split(' ') | ||
when Array then | ||
args = args.concat config_args | ||
end | ||
|
||
delete_legacy_args args | ||
|
||
Dir.chdir @spec.full_gem_path do | ||
options = ::RDoc::Options.new | ||
options.default_title = "#{@spec.full_name} Documentation" | ||
options.parse args | ||
end | ||
|
||
options.quiet = !Gem.configuration.really_verbose | ||
|
||
@rdoc = new_rdoc | ||
@rdoc.options = options | ||
|
||
store = RDoc::Store.new | ||
store.encoding = options.encoding | ||
store.dry_run = options.dry_run | ||
store.main = options.main_page | ||
store.title = options.title | ||
|
||
@rdoc.store = store | ||
|
||
say "Parsing documentation for #{@spec.full_name}" | ||
|
||
Dir.chdir @spec.full_gem_path do | ||
@rdoc.parse_files options.files | ||
end | ||
|
||
document 'ri', options, @ri_dir if | ||
@generate_ri and (@force or not File.exist? @ri_dir) | ||
|
||
document 'darkfish', options, @rdoc_dir if | ||
@generate_rdoc and (@force or not File.exist? @rdoc_dir) | ||
end | ||
|
||
## | ||
# #new_rdoc creates a new RDoc instance. This method is provided only to | ||
# make testing easier. | ||
|
||
def new_rdoc # :nodoc: | ||
::RDoc::RDoc.new | ||
end | ||
|
||
## | ||
# Is rdoc documentation installed? | ||
|
||
def rdoc_installed? | ||
File.exist? @rdoc_dir | ||
end | ||
|
||
## | ||
# Removes generated RDoc and ri data | ||
|
||
def remove | ||
base_dir = @spec.base_dir | ||
|
||
raise Gem::FilePermissionError, base_dir unless File.writable? base_dir | ||
|
||
FileUtils.rm_rf @rdoc_dir | ||
FileUtils.rm_rf @ri_dir | ||
end | ||
|
||
## | ||
# Is ri data installed? | ||
|
||
def ri_installed? | ||
File.exist? @ri_dir | ||
end | ||
|
||
## | ||
# Prepares the spec for documentation generation | ||
|
||
def setup | ||
self.class.load_rdoc | ||
|
||
raise Gem::FilePermissionError, @doc_dir if | ||
File.exist?(@doc_dir) and not File.writable?(@doc_dir) | ||
|
||
FileUtils.mkdir_p @doc_dir unless File.exist? @doc_dir | ||
end | ||
|
||
end | ||
|
||
# This class is referenced by RubyGems to create documents. | ||
# Now, methods are moved to rubygems_plugin.rb. | ||
# 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. | ||
# | ||
# When old version RDoc is not used, | ||
# this class is not used from RubyGems too. | ||
# Then, remove this class. | ||
# 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 initialize(spec); end | ||
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 generate document for compatibility if this is a | ||
# default gem. | ||
RubyGemsHook.new(@spec).remove | ||
end | ||
|
||
def remove; end | ||
def self.generation_hook installer, specs | ||
# Do nothing if this is NOT a default gem. | ||
return unless default_gem? | ||
|
||
def self.generation_hook installer, specs; end | ||
# Generate document for compatibility if this is a default gem. | ||
RubyGemsHook.generate(installer, specs) | ||
end | ||
end | ||
end |
Oops, something went wrong.