lib/yard/cli/yardoc.rb in yard-0.4.0 vs lib/yard/cli/yardoc.rb in yard-0.5.0
- old
+ new
@@ -1,23 +1,25 @@
-require 'optparse'
+require 'digest/sha1'
+require 'fileutils'
module YARD
module CLI
- class Yardoc
+ class Yardoc < Base
# The configuration filename to load extra options from
DEFAULT_YARDOPTS_FILE = ".yardopts"
# @return [Hash] the hash of options passed to the template.
# @see Templates::Engine#render
attr_reader :options
# @return [Array<String>] list of Ruby source files to process
attr_accessor :files
- # @return [Boolean] whether to reparse the source files even if the
- # .yardoc already exists.
- attr_accessor :reload
+ # @return [Boolean] whether to use the existing yardoc db if the
+ # .yardoc already exists. Also makes use of file checksums to
+ # parse only changed files.
+ attr_accessor :use_cache
# @return [Boolean] whether to generate output
attr_accessor :generate
# The options file name (defaults to {DEFAULT_YARDOPTS_FILE})
@@ -28,65 +30,93 @@
# @see #run
def self.run(*args) new.run(*args) end
# Creates a new instance of the commandline utility
def initialize
- @options = SymbolHash[
+ @options = SymbolHash.new(false)
+ @options.update(
:format => :html,
:template => :default,
:markup => :rdoc,
- :serializer => YARD::Serializers::FileSystemSerializer.new,
+ :serializer => YARD::Serializers::FileSystemSerializer.new,
+ :default_return => "Object",
+ :hide_void_return => false,
+ :no_highlight => false,
:files => [],
:visibilities => [:public],
:verifier => nil
- ]
+ )
@files = []
- @reload = true
+ @use_cache = false
@generate = true
@options_file = DEFAULT_YARDOPTS_FILE
end
# Runs the commandline utility, parsing arguments and generating
# output if set.
#
# @param [Array<String>] args the list of arguments
- # @return [nil]
+ # @return [void]
def run(*args)
args += support_rdoc_document_file!
optparse(*yardopts)
optparse(*args)
- Registry.load(files, reload)
+ Registry.load if use_cache
+ YARD.parse(files)
+ Registry.save(use_cache)
+
if generate
- Templates::Engine.generate(all_objects, options)
+ if use_cache
+ objects = all_objects
+ Registry.all # load all
+ objects.each do |object|
+ opts = options.merge(:object => object, :type => :layout)
+ Templates::Engine.render(opts)
+ end
+ else
+ Templates::Engine.generate(all_objects, options)
+ end
end
true
end
# The list of all objects to process. Override this method to change
# which objects YARD should generate documentation for.
#
# @return [Array<CodeObjects::Base>] a list of code objects to process
def all_objects
- Registry.all(:root, :module, :class)
+ types = [:root, :module, :class]
+ if use_cache
+ Registry.paths(false).map do |path|
+ obj = Registry.at(path)
+ if types.include?(obj.type)
+ obj
+ else
+ nil
+ end
+ end.compact
+ else
+ Registry.all(*types)
+ end
end
# Parses the .yardopts file for default yard options
- # @return [nil]
+ # @return [void]
def yardopts
- IO.read(options_file).split(/\s+/)
+ IO.read(options_file).shell_split
rescue Errno::ENOENT
[]
end
private
# Reads a .document file in the directory to get source file globs
- # @return [nil]
+ # @return [void]
def support_rdoc_document_file!
- IO.read(".document").split(/\s+/)
+ IO.read(".document").gsub(/^[ \t]*#.+/m, '').split(/\s+/)
rescue Errno::ENOENT
[]
end
# Adds a set of extra documentation files to be processed
@@ -105,11 +135,11 @@
# @example Parses a set of Ruby source files
# parse_files %w(file1 file2 file3)
# @example Parses a set of Ruby files with a separator and extra files
# parse_files %w(file1 file2 - extrafile1 extrafile2)
# @param [Array<String>] files the list of files to parse
- # @return [nil]
+ # @return [void]
def parse_files(*files)
self.files = []
seen_extra_files_marker = false
files.each do |file|
@@ -124,26 +154,43 @@
self.files << file
end
end
end
- # @param [Array<String>] expressions a list of query expressions to
- # turn into a proc
- def add_verifier(*expressions)
-
+ # Builds .yardoc files for all non-existing gems
+ # @param [Boolean] rebuild Forces rebuild of all gems
+ def build_gems(rebuild = false)
+ require 'rubygems'
+ Gem.source_index.find_name('').each do |spec|
+ reload = true
+ dir = Registry.yardoc_file_for_gem(spec.name)
+ next unless dir
+ if File.directory?(dir) && !rebuild
+ log.debug "#{spec.name} index already exists at '#{dir}'"
+ else
+ Dir.chdir(spec.full_gem_path)
+ log.info "Building yardoc index for gem: #{spec.full_name}"
+ yfile = Registry.yardoc_file_for_gem(spec.name, ">= 0", true)
+ Registry.clear
+ Yardoc.run('-n', '-b', yfile)
+ reload = false
+ end
+ end
+ exit(0)
end
# Parses commandline options.
# @param [Array<String>] args each tokenized argument
def optparse(*args)
query_expressions = []
+ do_build_gems, do_rebuild_gems = false, false
serialopts = SymbolHash.new
opts = OptionParser.new
opts.banner = "Usage: yardoc [options] [source_files [- extra_files]]"
- opts.separator "(if a list of source files is omitted, lib/**/*.rb is used.)"
+ opts.separator "(if a list of source files is omitted, lib/**/*.rb ext/**/*.c is used.)"
opts.separator ""
opts.separator "Example: yardoc -o documentation/ - FAQ LICENSE"
opts.separator " The above example outputs documentation for files in"
opts.separator " lib/**/*.rb to documentation/ including the extra files"
opts.separator " FAQ and LICENSE."
@@ -153,13 +200,13 @@
opts.separator "by whitespace."
opts.separator ""
opts.separator "General Options:"
opts.on('-c', '--use-cache [FILE]',
- 'Use the cached .yardoc db to generate documentation. (defaults to no cache)') do |file|
+ "Use the cached .yardoc db to generate documentation. (defaults to no cache)") do |file|
YARD::Registry.yardoc_file = file if file
- self.reload = false
+ self.use_cache = true
end
opts.on('-b', '--db FILE', 'Use a specified .yardoc db to load from or save to. (defaults to .yardoc)') do |yfile|
YARD::Registry.yardoc_file = yfile
end
@@ -176,11 +223,20 @@
end
opts.on('--legacy', 'Use old style parser and handlers. Unavailable under Ruby 1.8.x') do
YARD::Parser::SourceParser.parser_type = :ruby18
end
+
+ opts.on('--build-gems', 'Builds .yardoc files for all gems (implies -n)') do
+ do_build_gems = true
+ end
+ opts.on('--re-build-gems', 'Forces building .yardoc files for all gems (implies -n)') do
+ do_build_gems = true
+ do_rebuild_gems = true
+ end
+
opts.separator ""
opts.separator "Output options:"
opts.on('--no-public', "Don't show public methods. (default shows public)") do
options[:visibilities].delete(:public)
@@ -200,10 +256,18 @@
opts.on('--no-highlight', "Don't highlight code in docs as Ruby.") do
options[:no_highlight] = true
end
+ opts.on('--default-return TYPE', "Shown if method has no return type. Defaults to 'Object'") do |type|
+ options[:default_return] = type
+ end
+
+ opts.on('--hide-void-return', "Hides return types specified as 'void'. Default is shown.") do
+ options[:hide_void_return] = true
+ end
+
opts.on('--query QUERY', "Only show objects that match a specific query") do |query|
query_expressions << query.taint
end
opts.on('--title TITLE', 'Add a specific title to HTML documents') do |title|
@@ -245,30 +309,26 @@
YARD::Templates::Engine.register_template_path(path)
end
opts.on('-f', '--format FORMAT',
'The output format for the template. (defaults to html)') do |format|
- options[:format] = format
+ options[:format] = format.to_sym
end
- opts.separator ""
- opts.separator "Other options:"
- opts.on_tail('-q', '--quiet', 'Show no warnings.') { log.level = Logger::ERROR }
- opts.on_tail('--verbose', 'Show debugging information.') { log.level = Logger::DEBUG }
- opts.on_tail('-v', '--version', 'Show version.') { puts "yard #{YARD::VERSION}"; exit }
- opts.on_tail('-h', '--help', 'Show this help.') { puts opts; exit }
+ common_options(opts)
begin
opts.parse!(args)
rescue OptionParser::InvalidOption => e
STDERR.puts e.message
STDERR << "\n" << opts
exit
end
# Last minute modifications
+ build_gems(do_rebuild_gems) if do_build_gems
parse_files(*args) unless args.empty?
- self.files = ['lib/**/*.rb'] if self.files.empty?
+ self.files = ['lib/**/*.rb', 'ext/**/*.c'] if self.files.empty?
options[:verifier] = Verifier.new(*query_expressions) unless query_expressions.empty?
options[:visibilities].uniq!
options[:serializer] ||= Serializers::FileSystemSerializer.new(serialopts)
options[:readme] ||= Dir.glob('README*').first
end