class Toys::Utils::HelpText
A helper class that generates usage documentation for a tool.
This class generates full usage documentation, including description, flags, and arguments. It is used by middleware that implements help and related options.
This class is not loaded by default. Before using it directly, you should `require “toys/utils/help_text”`
Constants
- DEFAULT_INDENT
Default indent @return [Integer]
- DEFAULT_LEFT_COLUMN_WIDTH
Default width of first column @return [Integer]
Attributes
The ToolDefinition
being documented. @return [Toys::ToolDefinition]
Public Class Methods
Create a usage helper given an execution context.
@param context [Toys::Context] The current context. @return [Toys::Utils::HelpText]
# File lib/toys/utils/help_text.rb, line 34 def self.from_context(context) delegates = [] cur = context while (cur = cur[Context::Key::DELEGATED_FROM]) delegates << cur[Context::Key::TOOL] end cli = context[Context::Key::CLI] new(context[Context::Key::TOOL], cli.loader, cli.executable_name, delegates: delegates) end
Create a usage helper.
@param tool [Toys::ToolDefinition] The tool to document. @param loader [Toys::Loader] A loader that can provide subcommands. @param executable_name [String] The name of the executable.
e.g. `"toys"`.
@param delegates [Array<Toys::ToolDefinition>] The delegation path to
the tool.
@return [Toys::Utils::HelpText]
# File lib/toys/utils/help_text.rb, line 56 def initialize(tool, loader, executable_name, delegates: []) @tool = tool @loader = loader @executable_name = executable_name @delegates = delegates end
Public Instance Methods
Generate a long help string.
@param recursive [Boolean] If true, and the tool is a namespace,
display all subtools recursively. Defaults to false.
@param search [String,nil] An optional string to search for when
listing subtools. Defaults to `nil` which finds all subtools.
@param include_hidden [Boolean] Include hidden subtools (i.e. whose
names begin with underscore.) Default is false.
@param show_source_path [Boolean] If true, shows the source path
section. Defaults to false.
@param separate_sources [Boolean] Split up tool list by source root.
Defaults to false.
@param indent [Integer] Indent width. Default is {DEFAULT_INDENT}. @param indent2 [Integer] Second indent width. Default is
{DEFAULT_INDENT}.
@param wrap_width [Integer,nil] Wrap width of the column, or `nil` to
disable wrap. Default is `nil`.
@param styled [Boolean] Output ansi styles. Default is `true`.
@return [String] A usage string.
# File lib/toys/utils/help_text.rb, line 120 def help_string(recursive: false, search: nil, include_hidden: false, show_source_path: false, separate_sources: false, indent: nil, indent2: nil, wrap_width: nil, styled: true) indent ||= DEFAULT_INDENT indent2 ||= DEFAULT_INDENT subtools = collect_subtool_info(recursive, search, include_hidden, separate_sources) assembler = HelpStringAssembler.new( @tool, @executable_name, @delegates, subtools, search, show_source_path, separate_sources, indent, indent2, wrap_width, styled ) assembler.result end
Generate a subtool list string.
@param recursive [Boolean] If true, and the tool is a namespace,
display all subtools recursively. Defaults to false.
@param search [String,nil] An optional string to search for when
listing subtools. Defaults to `nil` which finds all subtools.
@param include_hidden [Boolean] Include hidden subtools (i.e. whose
names begin with underscore.) Default is false.
@param separate_sources [Boolean] Split up tool list by source root.
Defaults to false.
@param indent [Integer] Indent width. Default is {DEFAULT_INDENT}. @param wrap_width [Integer,nil] Wrap width of the column, or `nil` to
disable wrap. Default is `nil`.
@param styled [Boolean] Output ansi styles. Default is `true`.
@return [String] A usage string.
# File lib/toys/utils/help_text.rb, line 152 def list_string(recursive: false, search: nil, include_hidden: false, separate_sources: false, indent: nil, wrap_width: nil, styled: true) indent ||= DEFAULT_INDENT subtools = collect_subtool_info(recursive, search, include_hidden, separate_sources) assembler = ListStringAssembler.new(@tool, subtools, recursive, search, separate_sources, indent, wrap_width, styled) assembler.result end
Generate a short usage string.
@param recursive [Boolean] If true, and the tool is a namespace,
display all subtools recursively. Defaults to false.
@param include_hidden [Boolean] Include hidden subtools (i.e. whose
names begin with underscore.) Default is false.
@param separate_sources [Boolean] Split up tool list by source root.
Defaults to false.
@param left_column_width [Integer] Width of the first column. Default
is {DEFAULT_LEFT_COLUMN_WIDTH}.
@param indent [Integer] Indent width. Default is {DEFAULT_INDENT}. @param wrap_width [Integer,nil] Overall width to wrap to. Default is
`nil` indicating no wrapping.
@return [String] A usage string.
# File lib/toys/utils/help_text.rb, line 86 def usage_string(recursive: false, include_hidden: false, separate_sources: false, left_column_width: nil, indent: nil, wrap_width: nil) left_column_width ||= DEFAULT_LEFT_COLUMN_WIDTH indent ||= DEFAULT_INDENT subtools = collect_subtool_info(recursive, nil, include_hidden, separate_sources) assembler = UsageStringAssembler.new( @tool, @executable_name, subtools, separate_sources, indent, left_column_width, wrap_width ) assembler.result end
Private Instance Methods
# File lib/toys/utils/help_text.rb, line 192 def arrange_subtools(subtools_by_name, separate_sources) subtool_list = subtools_by_name.sort_by { |(local_name, _tool)| local_name } result = {} subtool_list.each do |(local_name, subtool)| key = separate_sources ? subtool.source_root : nil (result[key] ||= []) << [local_name, subtool] end result.sort_by { |source, _subtools| -(source&.priority || -999_999) } .map { |source, subtools| [source&.source_name || "unknown source", subtools] } end
# File lib/toys/utils/help_text.rb, line 163 def collect_subtool_info(recursive, search, include_hidden, separate_sources) subtools_by_name = list_subtools(recursive, include_hidden) filter_subtools(subtools_by_name, search) arrange_subtools(subtools_by_name, separate_sources) end
# File lib/toys/utils/help_text.rb, line 183 def filter_subtools(subtools_by_name, search) if !search.nil? && !search.empty? regex = ::Regexp.new(search, ::Regexp::IGNORECASE) subtools_by_name.delete_if do |local_name, tool| !regex.match?(local_name) && !regex.match?(tool.desc.to_s) end end end
# File lib/toys/utils/help_text.rb, line 169 def list_subtools(recursive, include_hidden) subtools_by_name = {} ([@tool] + @delegates).each do |tool| name_len = tool.full_name.length subtools = @loader.list_subtools(tool.full_name, recursive: recursive, include_hidden: include_hidden) subtools.each do |subtool| local_name = subtool.full_name.slice(name_len..-1).join(" ") subtools_by_name[local_name] = subtool end end subtools_by_name end