1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
|
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'fileutils'
require 'rubygems'
##
# The documentation manager generates RDoc and RI for RubyGems.
class Gem::DocManager
include Gem::UserInteraction
@configured_args = []
def self.configured_args
@configured_args ||= []
end
def self.configured_args=(args)
case args
when Array
@configured_args = args
when String
@configured_args = args.split
end
end
##
# Load RDoc from a gem if it is available, otherwise from Ruby's stdlib
def self.load_rdoc
begin
gem 'rdoc'
rescue Gem::LoadError
# use built-in RDoc
end
begin
require 'rdoc/rdoc'
@rdoc_version = if defined? RDoc::VERSION then
Gem::Version.new RDoc::VERSION
else
Gem::Version.new '1.0.1' # HACK parsing is hard
end
rescue LoadError => e
raise Gem::DocumentError,
"ERROR: RDoc documentation generator not installed: #{e}"
end
end
def self.rdoc_version
@rdoc_version
end
##
# Updates the RI cache for RDoc 2 if it is installed
def self.update_ri_cache
load_rdoc rescue return
return unless defined? RDoc::VERSION # RDoc 1 does not have VERSION
require 'rdoc/ri/driver'
options = {
:use_cache => true,
:use_system => true,
:use_site => true,
:use_home => true,
:use_gems => true,
:formatter => RDoc::RI::Formatter,
}
driver = RDoc::RI::Driver.new(options).class_cache
end
##
# Create a document manager for +spec+. +rdoc_args+ contains arguments for
# RDoc (template etc.) as a String.
def initialize(spec, rdoc_args="")
@spec = spec
@doc_dir = File.join(spec.installation_path, "doc", spec.full_name)
@rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split
end
##
# Is the RDoc documentation installed?
def rdoc_installed?
File.exist?(File.join(@doc_dir, "rdoc"))
end
##
# Is the RI documentation installed?
def ri_installed?
File.exist?(File.join(@doc_dir, "ri"))
end
##
# Generate the RI documents for this gem spec.
#
# Note that if both RI and RDoc documents are generated from the same
# process, the RI docs should be done first (a likely bug in RDoc will cause
# RI docs generation to fail if run after RDoc).
def generate_ri
setup_rdoc
install_ri # RDoc bug, ri goes first
FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
end
##
# Generate the RDoc documents for this gem spec.
#
# Note that if both RI and RDoc documents are generated from the same
# process, the RI docs should be done first (a likely bug in RDoc will cause
# RI docs generation to fail if run after RDoc).
def generate_rdoc
setup_rdoc
install_rdoc
FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
end
##
# Generate and install RDoc into the documentation directory
def install_rdoc
rdoc_dir = File.join @doc_dir, 'rdoc'
FileUtils.rm_rf rdoc_dir
say "Installing RDoc documentation for #{@spec.full_name}..."
run_rdoc '--op', rdoc_dir
end
##
# Generate and install RI into the documentation directory
def install_ri
ri_dir = File.join @doc_dir, 'ri'
FileUtils.rm_rf ri_dir
say "Installing ri documentation for #{@spec.full_name}..."
run_rdoc '--ri', '--op', ri_dir
end
##
# Run RDoc with +args+, which is an ARGV style argument list
def run_rdoc(*args)
args << @spec.rdoc_options
args << self.class.configured_args
args << '--quiet'
args << @spec.require_paths.clone
args << @spec.extra_rdoc_files
args << '--title' << "#{@spec.full_name} Documentation"
args = args.flatten.map do |arg| arg.to_s end
if self.class.rdoc_version >= Gem::Version.new('2.4.0') then
args.delete '--inline-source'
args.delete '--promiscuous'
args.delete '-p'
args.delete '--one-file'
# HACK more
end
r = RDoc::RDoc.new
old_pwd = Dir.pwd
Dir.chdir(@spec.full_gem_path)
begin
r.document args
rescue Errno::EACCES => e
dirname = File.dirname e.message.split("-")[1].strip
raise Gem::FilePermissionError.new(dirname)
rescue RuntimeError => ex
alert_error "While generating documentation for #{@spec.full_name}"
ui.errs.puts "... MESSAGE: #{ex}"
ui.errs.puts "... RDOC args: #{args.join(' ')}"
ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
Gem.configuration.backtrace
ui.errs.puts "(continuing with the rest of the installation)"
ensure
Dir.chdir(old_pwd)
end
end
def setup_rdoc
if File.exist?(@doc_dir) && !File.writable?(@doc_dir) then
raise Gem::FilePermissionError.new(@doc_dir)
end
FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
self.class.load_rdoc
end
##
# Remove RDoc and RI documentation
def uninstall_doc
raise Gem::FilePermissionError.new(@spec.installation_path) unless
File.writable? @spec.installation_path
original_name = [
@spec.name, @spec.version, @spec.original_platform].join '-'
doc_dir = File.join @spec.installation_path, 'doc', @spec.full_name
unless File.directory? doc_dir then
doc_dir = File.join @spec.installation_path, 'doc', original_name
end
FileUtils.rm_rf doc_dir
ri_dir = File.join @spec.installation_path, 'ri', @spec.full_name
unless File.directory? ri_dir then
ri_dir = File.join @spec.installation_path, 'ri', original_name
end
FileUtils.rm_rf ri_dir
end
end
|