/tools/Ruby/lib/ruby/site_ruby/1.8/rubygems/doc_manager.rb

http://github.com/agross/netopenspace · Ruby · 244 lines · 144 code · 60 blank · 40 comment · 7 complexity · 8edbe10894581461dda7ba50cece4f9a MD5 · raw file

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