lib/yard/cli/yardoc.rb in yard-0.7.5 vs lib/yard/cli/yardoc.rb in yard-0.8.0

- old
+ new

@@ -1,10 +1,54 @@ require 'digest/sha1' require 'fileutils' module YARD module CLI + # Default options used in +yard doc+ command. + class YardocOptions < Templates::TemplateOptions + # @return [Array<CodeObjects::ExtraFileObject>] + # the list of extra files rendered along with objects + default_attr :files, lambda { [] } + + # @return [String] the default title appended to each generated page + default_attr :title, "Documentation by YARD #{YARD::VERSION}" + + # @return [Verifier] the default verifier object to filter queries + default_attr :verifier, lambda { Verifier.new } + + # @return [Serializers::Base] the default serializer for generating output + # to disk. + default_attr :serializer, lambda { Serializers::FileSystemSerializer.new } + + # @return [Symbol] the default output format (:html). + default_attr :format, :html + + # @return [Boolean] whether the data should be rendered in a single page, + # if the template supports it. + default_attr :onefile, false + + # @return [CodeObjects::ExtraFileObject] the README file object rendered + # along with objects + attr_accessor :readme + + # @return [Array<CodeObjects::Base>] the list of code objects to render + # the templates with. + attr_accessor :objects + + # @return [Numeric] An index value for rendering sequentially related templates + attr_accessor :index + + # @return [CodeObjects::Base] an extra item to send to a template that is not + # the main rendered object + attr_accessor :item + + # @return [CodeObjects::ExtraFileObject] the file object being rendered. + # The +object+ key is not used so that a file may be rendered in the context + # of an object's namespace (for generating links). + attr_accessor :file + end + # 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 @@ -148,31 +192,20 @@ attr_accessor :statistics # @return [Array<String>] a list of assets to copy after generation # @since 0.6.0 attr_accessor :assets - + # @return [Boolean] whether markup option was specified # @since 0.7.0 attr_accessor :has_markup # Creates a new instance of the commandline utility def initialize super - @options = SymbolHash.new(false) - @options.update( - :format => :html, - :template => :default, - :markup => :rdoc, # default is :rdoc but falls back on :none - :serializer => YARD::Serializers::FileSystemSerializer.new, - :default_return => "Object", - :hide_void_return => false, - :no_highlight => false, - :files => [], - :title => "Documentation by YARD #{YARD::VERSION}", - :verifier => Verifier.new - ) + @options = YardocOptions.new + @options.reset_defaults @visibilities = [:public] @assets = {} @excluded = [] @files = [] @hidden_tags = [] @@ -246,17 +279,25 @@ # Last minute modifications self.files = ['{lib,app}/**/*.rb', 'ext/**/*.c'] if self.files.empty? self.files.delete_if {|x| x =~ /\A\s*\Z/ } # remove empty ones readme = Dir.glob('README*').first - readme ||= Dir.glob(files.first).first if options[:onefile] - options[:readme] ||= CodeObjects::ExtraFileObject.new(readme) if readme - options[:files].unshift(options[:readme]).uniq! if options[:readme] + readme ||= Dir.glob(files.first).first if options.onefile + options.readme ||= CodeObjects::ExtraFileObject.new(readme) if readme + options.files.unshift(options.readme).uniq! if options.readme Tags::Library.visible_tags -= hidden_tags add_visibility_verifier + # 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 @@ -293,11 +334,11 @@ 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) + serialized = !options.serializer || options.serializer.exists?(object) if checksums && serialized && !object.files.any? {|f, line| changed_files.include?(f) } true else log.info "Re-generating object #{object.path}..." false @@ -312,33 +353,33 @@ # @return (see YARD::Templates::Helpers::MarkupHelper#load_markup_provider) def verify_markup_options result, lvl = false, has_markup ? log.level : Logger::FATAL obj = Struct.new(:options).new(options) obj.extend(Templates::Helpers::MarkupHelper) - options[:files].each do |file| + 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 + 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 + options.markup = :none true else result end end # Copies any assets to the output directory # @return [void] # @since 0.6.0 def copy_assets - return unless options[:serializer] - outpath = options[:serializer].basepath + 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) @@ -353,11 +394,11 @@ run_verifier(Registry.all). sort_by {|item| [item.file || '', item.line || 0] }.each do |item| puts "#{item.file}:#{item.line}: #{item.path}" end end - + # Parses out the yardopts/document options def parse_yardopts_options(*args) opts = OptionParser.new opts.base.long.clear # HACK: why are --help and --version defined? yardopts_options(opts) @@ -384,11 +425,11 @@ # @param [Array<String>] files the set of documentation files def add_extra_files(*files) files.map! {|f| f.include?("*") ? Dir.glob(f) : f }.flatten! files.each do |file| if File.file?(file) - options[:files] << CodeObjects::ExtraFileObject.new(file) + options.files << CodeObjects::ExtraFileObject.new(file) else log.warn "Could not find extra file: #{file}" end end end @@ -422,16 +463,16 @@ # Adds verifier rule for visibilities # @return [void] # @since 0.5.6 def add_visibility_verifier vis_expr = "object.type != :method || #{visibilities.uniq.inspect}.include?(object.visibility)" - options[:verifier].add_expressions(vis_expr) + options.verifier.add_expressions(vis_expr) end # (see Templates::Helpers::BaseHelper#run_verifier) def run_verifier(list) - options[:verifier] ? options[:verifier].run(list) : list + options.verifier ? options.verifier.run(list) : list end # @since 0.6.0 def add_tag(tag_data, factory_method = nil) tag, title = *tag_data.split(':') @@ -504,14 +545,14 @@ opts.on('--exclude REGEXP', 'Ignores a file if it matches path match (regexp)') do |path| self.excluded << path end end - + # Adds --[no-]yardopts / --[no-]document def yardopts_options(opts) - opts.on('--[no-]yardopts [FILE]', + opts.on('--[no-]yardopts [FILE]', "If arguments should be read from FILE", " (defaults to yes, FILE defaults to .yardopts)") do |use_yardopts| if use_yardopts.is_a?(String) self.options_file = use_yardopts self.use_yardopts_file = true @@ -530,11 +571,11 @@ def output_options(opts) opts.separator "" opts.separator "Output options:" opts.on('--one-file', 'Generates output as a single file') do - options[:onefile] = true + options.onefile = true end opts.on('--list', 'List objects to standard out (implies -n)') do |format| self.generate = false self.list = true @@ -551,41 +592,50 @@ 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) && + options.verifier.add_expressions '!object.tag(:private) && (object.namespace.is_a?(CodeObjects::Proxy) || !object.namespace.tag(:private))' 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[:no_highlight] = true + 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 + 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 + 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] - options[:verifier].add_expressions(query.taint) + options.verifier.add_expressions(query.taint) end opts.on('--title TITLE', 'Add a specific title to HTML documents') do |title| - options[:title] = 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 File.file?(readme) - options[:readme] = CodeObjects::ExtraFileObject.new(readme) + options.readme = CodeObjects::ExtraFileObject.new(readme) else log.warn "Could not find readme file: #{readme}" end end @@ -606,27 +656,27 @@ end end opts.on('-o', '--output-dir PATH', 'The output directory. (defaults to ./doc)') do |dir| - options[:serializer].basepath = 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 + options.markup = markup.to_sym end opts.on('-M', '--markup-provider MARKUP_PROVIDER', - 'Overrides the library used to process markup ', + 'Overrides the library used to process markup ', ' formatting (specify the gem name)') do |markup_provider| - options[:markup_provider] = markup_provider.to_sym + options.markup_provider = markup_provider.to_sym end - opts.on('--charset ENC', 'Character set to use when parsing files ', + 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.default_internal = encoding, encoding end @@ -635,23 +685,23 @@ end end opts.on('-t', '--template TEMPLATE', 'The template to use. (defaults to "default")') do |template| - options[:template] = template.to_sym + 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(path) + 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 + options.format = format.to_sym end opts.on('--no-stats', 'Don\'t print statistics') do self.statistics = false end