class YARD::CLI::Yardoc
Yardoc
is the default YARD
CLI
command (+yard doc+ and historic yardoc
executable) used to generate and output (mainly) HTML documentation given a set of source files.
Usage¶ ↑
Main usage for this command is:
$ yardoc [options] [source_files [- extra_files]]
See +yardoc –help+ for details on valid options.
Options
File
(.yardopts
)¶ ↑
If a .yardopts
file is found in the source directory being processed, YARD
will use the contents of the file as arguments to the command, treating newlines as spaces. You can use shell-style quotations to group space delimited arguments, just like on the command line.
A valid .yardopts
file might look like:
--no-private --title "My Title" --exclude foo --exclude bar lib/**/*.erb lib/**/*.rb - HACKING.rdoc LEGAL COPYRIGHT
Note that Yardoc
also supports the legacy RDoc style .document
file, though this file can only specify source globs to parse, not options.
Queries (--query
)¶ ↑
Yardoc
supports queries to select specific code objects for which to generate documentation. For example, you might want to generate documentation only for your public API. If you’ve documented your public methods with +@api public+, you can use the following query to select all of these objects:
--query '@api.text == "public"'
Note that the syntax for queries is mostly Ruby with a few syntactic simplifications for meta-data tags. See the {Verifier} class for an overview of this syntax.
Adding Custom Ad-Hoc Meta-data Tags
(--tag
)¶ ↑
YARD
allows specification of {file:docs/Tags.md meta-data tags} programmatically via the {YARD::Tags::Library} class, but often this is not practical for users writing documentation. To make adding custom tags easier, Yardoc
has a few command-line switches for creating basic tags and displaying them in generated HTML output.
To specify a custom tag to be displayed in output, use any of the following:
-
--tag
TAG:TITLE -
--name-tag
TAG:TITLE -
--type-tag
TAG:TITLE -
--type-name-tag
TAG:TITLE -
--title-tag
TAG:TITLE
“TAG:TITLE” is of the form: name:“Display Title”, for example:
--tag overload:"Overloaded Method"
See +yard help doc+ for a description of the various options.
Tags
added in this way are automatically displayed in output. To add a meta-data tag that does not show up in output, use +–hide-tag TAG+. Note that you can also use this option on existing tags to hide builtin tags, for instance.
Processed Data Storage (.yardoc
directory)¶ ↑
When Yardoc
parses a source directory, it creates a .yardoc
directory (by default, override with -b
) at the root of the project. This directory contains marshal dumps for all raw object data in the source, so that you can access it later for various commands (stats
, graph
, etc.). This directory is also used as a cache for any future calls to yardoc
so as to process only the files which have changed since the last call.
When Yardoc
uses the cache in subsequent calls to yardoc
, methods or classes that have been deleted from source since the last parsing will not be erased from the cache (YARD
never deletes objects). In such a case, you should wipe the cache and do a clean parsing of the source tree. You can do this by deleting the .yardoc
directory manually, or running Yardoc
without --use-cache
(-c
).
@since 0.2.1 @see Verifier
Attributes
Keep track of which APIs are to be shown @return [Array<String>] a list of APIs @since 0.8.1
@return [Array<String>] a list of assets to copy after generation @since 0.6.0
@return [Array<String>] list of excluded paths (regexp matches) @since 0.5.3
@return [Boolean] whether yard exits with error status code if a warning occurs
@return [Array<String>] list of Ruby source files to process
@return [Boolean] whether to generate output
@return [Boolean] whether markup option was specified @since 0.7.0
@return [Boolean] whether to print a list of objects @since 0.5.5
@return [Hash] the hash of options passed to the template. @see Templates::Engine#render
@return [Boolean] whether objects should be serialized to .yardoc db
@return [Boolean] whether to print statistics after parsing @since 0.6.0
@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.
Keep track of which visibilities are to be shown @return [Array<Symbol>] a list of visibilities @since 0.5.6
Public Class Methods
Source
# File lib/yard/cli/yardoc.rb, line 207 def initialize super @options = YardocOptions.new @options.reset_defaults @visibilities = [:public] @apis = [] @hidden_apis = [] @assets = {} @excluded = [] @files = [] @hidden_tags = [] @use_cache = false @generate = true @statistics = true @list = false @save_yardoc = true @has_markup = false @fail_on_warning = false if defined?(::Encoding) && ::Encoding.respond_to?(:default_external=) utf8 = ::Encoding.find('utf-8') ::Encoding.default_external = utf8 unless ::Encoding.default_external == utf8 ::Encoding.default_internal = utf8 unless ::Encoding.default_internal == utf8 end end
Creates a new instance of the commandline utility
Public Instance Methods
Source
# File lib/yard/cli/yardoc.rb, line 330 def all_objects Registry.all(:root, :module, :class) end
The list of all objects to process. Override this method to change which objects YARD
should generate documentation for.
@deprecated To hide methods use the +@private+ tag instead. @return [Array<CodeObjects::Base>] a list of code objects to process
Source
# File lib/yard/cli/yardoc.rb, line 234 def description "Generates documentation" end
Source
# File lib/yard/cli/yardoc.rb, line 291 def parse_arguments(*args) super(*args) # Last minute modifications self.files = Parser::SourceParser::DEFAULT_PATH_GLOB if files.empty? files.delete_if {|x| x =~ /\A\s*\Z/ } # remove empty ones readme = Dir.glob('README{,*[^~]}'). select {|f| extra_file_valid?(f)}. sort_by {|r| [r.count('.'), r.index('.'), r] }.first readme ||= Dir.glob(files.first).first if options.onefile && !files.empty? options.readme ||= CodeObjects::ExtraFileObject.new(readme) if readme && extra_file_valid?(readme) options.files.unshift(options.readme).uniq! if options.readme Tags::Library.visible_tags -= hidden_tags add_visibility_verifier add_api_verifier apply_locale # US-ASCII is invalid encoding for onefile if defined?(::Encoding) && options.onefile if ::Encoding.default_internal == ::Encoding::US_ASCII log.warn "--one-file is not compatible with US-ASCII encoding, using ASCII-8BIT" ::Encoding.default_external, ::Encoding.default_internal = ['ascii-8bit'] * 2 end end if generate && !verify_markup_options false else true end end
Parses commandline arguments @param [Array<String>] args the list of arguments @return [Boolean] whether or not arguments are valid @since 0.5.6
Source
# File lib/yard/cli/yardoc.rb, line 244 def run(*args) log.show_progress = true if args.empty? || !args.first.nil? # fail early if arguments are not valid return unless parse_arguments(*args) end checksums = nil if use_cache Registry.load checksums = Registry.checksums.dup end if save_yardoc Registry.lock_for_writing do YARD.parse(files, excluded) Registry.save(use_cache) end else YARD.parse(files, excluded) end if generate run_generate(checksums) copy_assets elsif list print_list end if !list && statistics && log.level < Logger::ERROR Registry.load_all log.enter_level(Logger::ERROR) do Stats.new(false).run(*args) end end abort if fail_on_warning && log.warned true ensure log.show_progress = false end
Runs the commandline utility, parsing arguments and generating output if set.
@param [Array<String>] args the list of arguments. If the list only
contains a single nil value, skip calling of {#parse_arguments}
@return [void]
Private Instance Methods
Source
# File lib/yard/cli/yardoc.rb, line 474 def add_api_verifier no_api = true if apis.delete('') exprs = [] exprs << "#{apis.uniq.inspect}.include?(@api.text)" unless apis.empty? unless hidden_apis.empty? exprs << "!#{hidden_apis.uniq.inspect}.include?(@api.text)" end exprs = !exprs.empty? ? [exprs.join(' && ')] : [] exprs << "!@api" if no_api expr = exprs.join(' || ') options.verifier.add_expressions(expr) unless expr.empty? end
Adds verifier rule for APIs @return [void] @since 0.8.1
Source
# File lib/yard/cli/yardoc.rb, line 413 def add_extra_files(*files) files.map! {|f| f.include?("*") ? Dir.glob(f) : f }.flatten! files.each do |file| if extra_file_valid?(file) options.files << CodeObjects::ExtraFileObject.new(file) end end end
Adds a set of extra documentation files to be processed @param [Array<String>] files the set of documentation files
Source
# File lib/yard/cli/yardoc.rb, line 507 def add_tag(tag_data, factory_method = nil) tag, title = *tag_data.split(':') title ||= tag.capitalize Tags::Library.define_tag(title, tag.to_sym, factory_method) Tags::Library.visible_tags |= [tag.to_sym] end
@since 0.6.0
Source
# File lib/yard/cli/yardoc.rb, line 466 def add_visibility_verifier vis_expr = "#{visibilities.uniq.inspect}.include?(object.visibility)" options.verifier.add_expressions(vis_expr) end
Adds verifier rule for visibilities @return [void] @since 0.5.6
Source
# File lib/yard/cli/yardoc.rb, line 494 def apply_locale YARD::I18n::Locale.default = options.locale options.files.each do |file| file.locale = options.locale end end
Applies the specified locale to collected objects @return [void] @since 0.8.3
Source
# File lib/yard/cli/yardoc.rb, line 389 def copy_assets return unless options.serializer outpath = options.serializer.basepath assets.each do |from, to| to = File.join(outpath, to) log.debug "Copying asset '#{from}' to '#{to}'" from += '/.' if File.directory?(from) FileUtils.cp_r(from, to) end end
Copies any assets to the output directory @return [void] @since 0.6.0
Source
# File lib/yard/cli/yardoc.rb, line 425 def extra_file_valid?(file, check_exists = true) if file =~ %r{^(?:\.\./|/)} log.warn "Invalid file: #{file}" false elsif check_exists && !File.file?(file) log.warn "Could not find file: #{file}" false else true end end
@param file [String] the filename to validate @param check_exists [Boolean] whether the file should exist on disk @return [Boolean] whether the file is allowed to be used
Source
# File lib/yard/cli/yardoc.rb, line 541 def general_options(opts) opts.separator "" opts.separator "General Options:" 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 opts.on('--[no-]single-db', 'Whether code objects should be stored to single', ' database file (advanced)') do |use_single_db| Registry.single_object_db = use_single_db end opts.on('-n', '--no-output', 'Only generate .yardoc database, no documentation.') do self.generate = false end opts.on('-c', '--use-cache [FILE]', "Use the cached .yardoc db to generate documentation.", " (defaults to no cache)") do |file| YARD::Registry.yardoc_file = file if file self.use_cache = true end opts.on('--no-cache', "Clear .yardoc db before parsing source.") do self.use_cache = false end yardopts_options(opts) opts.on('--no-save', 'Do not save the parsed data to the yardoc db') do self.save_yardoc = false end opts.on('--exclude REGEXP', 'Ignores a file if it matches path match (regexp)') do |path| excluded << path end opts.on('--fail-on-warning', 'Exit with error status code if a warning occurs') do self.fail_on_warning = true end end
Adds general options
Source
# File lib/yard/cli/yardoc.rb, line 516 def optparse(*args) opts = OptionParser.new opts.banner = "Usage: yard doc [options] [source_files [- extra_files]]" opts.separator "(if a list of source files is omitted, " opts.separator " {lib,app}/**/*.rb ext/**/*.{c,rb} 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." opts.separator "" opts.separator "A base set of options can be specified by adding a .yardopts" opts.separator "file to your base path containing all extra options separated" opts.separator "by whitespace." general_options(opts) output_options(opts) tag_options(opts) common_options(opts) parse_options(opts, args) parse_files(*args) unless args.empty? end
Parses commandline options. @param [Array<String>] args each tokenized argument
Source
# File lib/yard/cli/yardoc.rb, line 586 def output_options(opts) opts.separator "" opts.separator "Output options:" opts.on('--one-file', 'Generates output as a single file') do options.onefile = true end opts.on('--list', 'List objects to standard out (implies -n)') do |_format| self.generate = false self.list = true end opts.on('--no-public', "Don't show public methods. (default shows public)") do visibilities.delete(:public) end opts.on('--protected', "Show protected methods. (default hides protected)") do visibilities.push(:protected) end opts.on('--private', "Show private methods. (default hides private)") do visibilities.push(:private) end opts.on('--no-private', "Hide objects with @private tag") do options.verifier.add_expressions '!object.tag(:private) && (object.namespace.is_a?(CodeObjects::Proxy) || !object.namespace.tag(:private))' end opts.on('--[no-]api API', 'Generates documentation for a given API', '(objects which define the correct @api tag).', 'If --no-api is given, displays objects with', 'no @api tag.') do |api| api = '' if api == false apis.push(api) end opts.on('--hide-api API', 'Hides given @api tag from documentation') do |api| hidden_apis.push(api) end opts.on('--embed-mixins', "Embeds mixin methods into class documentation") do options.embed_mixins << '*' end opts.on('--embed-mixin [MODULE]', "Embeds mixin methods from a particular", " module into class documentation") do |mod| options.embed_mixins << mod end opts.on('--no-highlight', "Don't highlight code blocks in output.") do options.highlight = false 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| next if YARD::Config.options[:safe_mode] query.taint if query.respond_to?(:taint) options.verifier.add_expressions(query) end opts.on('--title TITLE', 'Add a specific title to HTML documents') do |title| options.title = title end opts.on('-r', '--readme FILE', '--main FILE', 'The readme file used as the title page', ' of documentation.') do |readme| if extra_file_valid?(readme) options.readme = CodeObjects::ExtraFileObject.new(readme) end end opts.on('--files FILE1,FILE2,...', 'Any extra comma separated static files to be ', ' included (eg. FAQ)') do |files| add_extra_files(*files.split(",")) end opts.on('--asset FROM[:TO]', 'A file or directory to copy over to output ', ' directory after generating') do |asset| from, to = *asset.split(':').map {|f| File.cleanpath(f, true) } to ||= from if extra_file_valid?(from, false) && extra_file_valid?(to, false) assets[from] = to end end opts.on('-o', '--output-dir PATH', 'The output directory. (defaults to ./doc)') do |dir| options.serializer.basepath = dir end opts.on('-m', '--markup MARKUP', 'Markup style used in documentation, like textile, ', ' markdown or rdoc. (defaults to rdoc)') do |markup| self.has_markup = true options.markup = markup.to_sym end opts.on('-M', '--markup-provider MARKUP_PROVIDER', 'Overrides the library used to process markup ', ' formatting (specify the gem name)') do |markup_provider| options.markup_provider = markup_provider.to_sym end opts.on('--charset ENC', 'Character set to use when parsing files ', ' (default is system locale)') do |encoding| begin if defined?(Encoding) && Encoding.respond_to?(:default_external=) Encoding.default_external = encoding Encoding.default_internal = encoding end rescue ArgumentError => e raise OptionParser::InvalidOption, e end end opts.on('-t', '--template TEMPLATE', 'The template to use. (defaults to "default")') do |template| options.template = template.to_sym end opts.on('-p', '--template-path PATH', 'The template path to look for templates in.', ' (used with -t).') do |path| next if YARD::Config.options[:safe_mode] YARD::Templates::Engine.register_template_path(File.expand_path(path)) end opts.on('-f', '--format FORMAT', 'The output format for the template.', ' (defaults to html)') do |format| options.format = format.to_sym end opts.on('--no-stats', 'Don\'t print statistics') do self.statistics = false end opts.on('--no-progress', 'Don\'t show progress bar') do log.show_progress = false end opts.on('--locale LOCALE', 'The locale for generated documentation.', ' (defaults to en)') do |locale| options.locale = locale end opts.on('--po-dir DIR', 'The directory that has .po files.', " (defaults to #{YARD::Registry.po_dir})") do |dir| YARD::Registry.po_dir = dir end end
Adds output options
Source
# File lib/yard/cli/yardoc.rb, line 446 def parse_files(*files) seen_extra_files_marker = false files.each do |file| if file == "-" seen_extra_files_marker = true next end if seen_extra_files_marker add_extra_files(file) else self.files << file end end end
Parses the file arguments into Ruby files and extra files, which are separated by a ‘-’ element.
@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 [void]
Source
# File lib/yard/cli/yardoc.rb, line 403 def print_list Registry.load_all run_verifier(Registry.all). sort_by {|item| [item.file || '', item.line || 0] }.each do |item| log.puts "#{item.file}:#{item.line}: #{item.path}" end end
Prints a list of all objects @return [void] @since 0.5.5
Source
# File lib/yard/cli/yardoc.rb, line 340 def run_generate(checksums) if checksums changed_files = [] Registry.checksums.each do |file, hash| changed_files << file if checksums[file] != hash end end Registry.load_all if use_cache objects = run_verifier(all_objects).reject do |object| serialized = !options.serializer || options.serializer.exists?(object) if checksums && serialized && !object.files.any? {|f, _line| changed_files.include?(f) } true else log.debug "Re-generating object #{object.path}..." false end end Templates::Engine.generate(objects, options) end
Generates output for objects @param [Hash, nil] checksums if supplied, a list of checksums for files. @return [void] @since 0.5.1
Source
# File lib/yard/cli/yardoc.rb, line 502 def run_verifier(list) options.verifier ? options.verifier.run(list) : list end
Source
# File lib/yard/cli/yardoc.rb, line 753 def tag_options(opts) opts.separator "" opts.separator "Tag options: (TAG:TITLE looks like: 'overload:Overloaded Method')" opts.on('--tag TAG:TITLE', 'Registers a new free-form metadata @tag') do |tag| add_tag(tag) end opts.on('--type-tag TAG:TITLE', 'Tag with an optional types field') do |tag| add_tag(tag, :with_types) end opts.on('--type-name-tag TAG:TITLE', 'Tag with optional types and a name field') do |tag| add_tag(tag, :with_types_and_name) end opts.on('--name-tag TAG:TITLE', 'Tag with a name field') do |tag| add_tag(tag, :with_name) end opts.on('--title-tag TAG:TITLE', 'Tag with first line as title field') do |tag| add_tag(tag, :with_title_and_text) end opts.on('--hide-tag TAG', 'Hides a previously defined tag from templates') do |tag| self.hidden_tags |= [tag.to_sym] end opts.on('--transitive-tag TAG', 'Marks a tag as transitive') do |tag| Tags::Library.transitive_tags |= [tag.to_sym] end opts.on('--non-transitive-tag TAG', 'Marks a tag as not transitive') do |tag| Tags::Library.transitive_tags -= [tag.to_sym] end end
Adds tag options @since 0.6.0
Source
# File lib/yard/cli/yardoc.rb, line 364 def verify_markup_options result = false lvl = has_markup ? log.level : Logger::FATAL obj = Struct.new(:options).new(options) obj.extend(Templates::Helpers::MarkupHelper) options.files.each do |file| markup = file.attributes[:markup] || obj.markup_for_file('', file.filename) result = obj.load_markup_provider(markup) return false if !result && markup != :rdoc end options.markup = :rdoc unless has_markup log.enter_level(lvl) { result = obj.load_markup_provider } if !result && !has_markup log.warn "Could not load default RDoc formatter, " \ "ignoring any markup (install RDoc to get default formatting)." options.markup = :none true else result end end
Verifies that the markup options are valid before parsing any code. Failing early is better than failing late.
@return (see YARD::Templates::Helpers::MarkupHelper#load_markup_provider
)