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

tool[R]

The ToolDefinition being documented. @return [Toys::ToolDefinition]

Public Class Methods

from_context(context) click to toggle source

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
new(tool, loader, executable_name, delegates: []) click to toggle source

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

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) click to toggle source

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
list_string(recursive: false, search: nil, include_hidden: false, separate_sources: false, indent: nil, wrap_width: nil, styled: true) click to toggle source

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
usage_string(recursive: false, include_hidden: false, separate_sources: false, left_column_width: nil, indent: nil, wrap_width: nil) click to toggle source

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

arrange_subtools(subtools_by_name, separate_sources) click to toggle source
# 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
collect_subtool_info(recursive, search, include_hidden, separate_sources) click to toggle source
# 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
filter_subtools(subtools_by_name, search) click to toggle source
# 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
list_subtools(recursive, include_hidden) click to toggle source
# 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