Documentation
¶
Overview ¶
Package thor is a pure-Go (CGO-free) MRI-faithful reimplementation of the deterministic core of Ruby's Thor CLI-framework gem (thor 1.5.0). It covers the three interpreter-independent halves of Thor a host embeds: declarative option/argument parsing (Options, [Arguments]), the command registry and argv-to-command dispatch (Base), and byte-faithful usage/help generation.
Running a command body invokes user Ruby (or Go) code; that is the host seam. This package resolves argv into (command, parsed-options, remaining-args) and renders help exactly as the gem does, so go-embedded-ruby can bind Thor with no Ruby runtime and reproduce the gem's output and error text byte-for-byte.
Value model ¶
Parsed option values use a small, fixed set of Go types so a host can map its object graph to and from this package. The mapping mirrors the one Thor's parser produces:
Ruby (Thor) Go ----------- -- nil nil true / false bool :string value string :numeric int int64 :numeric float float64 :array []string :hash *OrderedMap (string->string, insertion order)
A parse yields a *Result: its Options is an insertion-ordered map from the option human name to its value, and Args holds the non-option remainder.
Terminal width ¶
Help/table/wrap layout depends on terminal width. For deterministic, ruby-free golden output this package uses a fixed default of 80 columns, overridable per call via Config.TerminalWidth or the THOR_COLUMNS environment variable, matching Thor::Shell::Terminal.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Base ¶
type Base struct {
// Namespace is the class namespace used in usage prefixes (e.g. "myapp").
Namespace string
// ClassOptions are options shared by every command (Thor `class_option`),
// in declaration order.
ClassOptions []*Option
// Arguments are the class's declared positional arguments, in order.
Arguments []*Option
// DefaultCommand is invoked when argv names none; "" means "help".
DefaultCommand string
// Map holds `map` aliases (input token -> command name).
Map map[string]string
// contains filtered or unexported fields
}
Base is a command registry: the Go analogue of a Thor subclass. It resolves an argv to a command, parses that command's options, and renders help — all deterministically, with command-body invocation left to the host.
func (*Base) AddCommand ¶
AddCommand registers a command (normalizing foo-bar to foo_bar as the key).
func (*Base) CommandHelp ¶
CommandHelp renders the per-command help block (Thor::command_help) for the named command, byte-faithful to the gem, or a KindUndefinedCommand error.
func (*Base) Dispatch ¶
Dispatch resolves argv into a command, its parsed options, and the remaining positional arguments. It mirrors the deterministic half of Thor::dispatch: pick the command name, split argv at the first switch, and parse options. Invoking the resolved command body is the host seam.
func (*Base) Help ¶
Help renders the class-level help (Thor::help): the command listing followed by the class options table, byte-faithful to the gem.
func (*Base) NormalizeCommandName ¶
NormalizeCommandName resolves a user token to a command name the way Thor::normalize_command_name does: nil -> default; prefix completion; map aliases; ambiguity is an error. The final name uses underscores.
type Command ¶
type Command struct {
// Name is the command's normalized method name (underscores).
Name string
// Description is the one-line `desc` text.
Description string
// LongDescription is the `long_desc` text ("" if none).
LongDescription string
// WrapLongDescription toggles word-wrapping of LongDescription (long_desc
// wrap: option; default true).
WrapLongDescription bool
// Usage is the raw usage line (`desc "usage", ...`).
Usage string
// Options are the command's options in declaration order.
Options []*Option
// AncestorName, when set, prefixes the usage (subcommand ancestor).
AncestorName string
// Hidden hides the command from help listings.
Hidden bool
// Relations holds this command's exclusive / at-least-one option groups.
Relations Relations
}
Command models a registered command (Thor::Command): its name, description, usage line, and the options declared for it. Invoking the command body is the host seam; this type carries only the metadata used for dispatch and help.
func NewCommand ¶
NewCommand builds a Command with WrapLongDescription defaulting to true.
func (*Command) FormattedUsage ¶
func (c *Command) FormattedUsage(namespace string, args []*Option, useNamespace, subcommand bool) string
FormattedUsage renders the command's usage line as Thor::Command#formatted_usage does: an ancestor / namespace / subcommand prefix, the usage with required class arguments injected, then required options. namespace is the class's namespace; args are the class's declared positional arguments (may be nil).
type Config ¶
type Config struct {
// Basename is the program name shown at the head of usage/banner lines
// (Thor's basename, e.g. "myapp"). Defaults to "thor" when empty.
Basename string
// TerminalWidth overrides the layout width; 0 uses THOR_COLUMNS then 80.
TerminalWidth int
// PackageName, when set, heads the command listing with
// "<PackageName> commands:" instead of "Commands:".
PackageName string
// Getenv resolves environment variables (for THOR_COLUMNS); nil means the
// process environment is not consulted and only TerminalWidth/80 apply.
Getenv func(string) string
}
Config tunes dispatch and help rendering.
type Error ¶
Error is a Thor parse or dispatch error. Msg is byte-identical to the message the gem raises, and Kind names the gem exception class so the host can re-raise it faithfully.
type ErrorKind ¶
type ErrorKind int
ErrorKind classifies a Thor parse/dispatch error by the gem exception class it corresponds to, so a host can re-raise the matching Ruby exception.
const ( // KindRequiredArgumentMissing maps to Thor::RequiredArgumentMissingError. KindRequiredArgumentMissing ErrorKind = iota // KindMalformattedArgument maps to Thor::MalformattedArgumentError. KindMalformattedArgument // KindUnknownArgument maps to Thor::UnknownArgumentError. KindUnknownArgument // KindExclusiveArgument maps to Thor::ExclusiveArgumentError. KindExclusiveArgument // KindAtLeastOneRequiredArgument maps to Thor::AtLeastOneRequiredArgumentError. KindAtLeastOneRequiredArgument // KindUndefinedCommand maps to Thor::UndefinedCommandError. KindUndefinedCommand // KindAmbiguousCommand maps to Thor::AmbiguousCommandError. KindAmbiguousCommand // KindArgument maps to Ruby's ArgumentError (invalid declaration). KindArgument )
type Option ¶
type Option struct {
// Name is the raw declared name (may use "_" or "-"). It drives SwitchName
// and HumanName below.
Name string
// Desc is the one-line description shown in the option table.
Desc string
// Required marks the option as required (defaults to false for options).
Required bool
// Type is the value type; empty means String.
Typ Type
// Default is the default value (any of the mapped Go value types), or nil.
Default any
// LazyDefault is Thor's :lazy_default — the value used when the switch is
// given without an inline value.
LazyDefault any
// Aliases are the short/long alias switches (e.g. "-f", "--flag"),
// normalized to carry a leading dash.
Aliases []string
// Banner overrides the value placeholder shown in usage; empty uses the
// per-type default banner.
Banner string
// BannerSet records whether Banner was explicitly provided (so an explicit
// empty banner suppresses the placeholder).
BannerSet bool
// Enum, when non-empty, restricts accepted values.
Enum []string
// Group is the capitalized option group name ("" is the default group).
Group string
// Hide hides the option from help output.
Hide bool
// Repeatable accumulates repeated switches into an array (or merged hash).
Repeatable bool
}
Option models a single declared option (Thor::Option), i.e. a switch given via `option`/`method_option`/`method_options`. The zero value is not valid; build one with NewOption.
func NewOption ¶
NewOption returns an Option with the Thor defaults applied: Type defaults to String and, when unset, the banner defaults per type. It normalizes aliases to carry a leading dash. It returns an error for the invalid declarations Thor rejects (boolean+required).
func (*Option) HumanName ¶
HumanName is the option's programmatic name (the key in the options hash).
func (*Option) PrintDefault ¶
PrintDefault renders the default value as it appears after "# Default:".
func (*Option) ShowDefault ¶
ShowDefault reports whether a "# Default:" line is shown for this option.
func (*Option) StringType ¶
StringType reports whether the option is of string type.
func (*Option) SwitchName ¶
SwitchName is the canonical switch (e.g. "--flag") used as the map key.
type Options ¶
type Options struct {
// contains filtered or unexported fields
}
Options declares a set of options to parse against. Build one with NewOptions; call Options.Parse to parse an argv.
func NewOptions ¶
func NewOptions(options []*Option, defaults *ValueMap, stopOnUnknown, disableRequiredCheck bool, relations Relations) *Options
NewOptions builds an Options parser from declared options and a defaults map (option human name -> value; Thor's `defaults` seeded from class/method options). Pass a zero Relations for no exclusive/at-least-one groups.
type OrderedMap ¶
type OrderedMap struct {
// contains filtered or unexported fields
}
OrderedMap is an insertion-ordered string->string map, the Go shape of a Thor :hash option value. Thor builds hash values by walking "key:value" tokens left to right, so insertion order is meaningful and preserved here.
func (*OrderedMap) Get ¶
func (m *OrderedMap) Get(key string) (string, bool)
Get returns the value for key and whether it was present.
func (*OrderedMap) Has ¶
func (m *OrderedMap) Has(key string) bool
Has reports whether key is present.
func (*OrderedMap) Keys ¶
func (m *OrderedMap) Keys() []string
Keys returns the keys in insertion order. The slice must not be mutated.
func (*OrderedMap) Merge ¶
func (m *OrderedMap) Merge(other *OrderedMap)
Merge copies every entry of other into m in other's insertion order, mirroring how a repeatable :hash option accumulates via Hash#merge!.
func (*OrderedMap) Set ¶
func (m *OrderedMap) Set(key, val string)
Set inserts or replaces key. A repeated key keeps its original position and overwrites the value, matching Ruby Hash#[]= semantics (though Thor's parser rejects duplicate keys before they reach here).
type Relations ¶
Relations groups options for the exclusive / at-least-one checks. Each entry is a slice of option human names.
type Result ¶
type Result struct {
// Options maps each option's human name to its parsed value (a string,
// int64, float64, bool, []string, or *OrderedMap), in declaration order.
Options *ValueMap
// Args holds the arguments left over after option parsing (Thor's #remaining).
Args []string
}
Result is the outcome of a successful parse: the parsed option values keyed by option human name in declaration order, and the non-option remainder.
type ValueMap ¶
type ValueMap struct {
// contains filtered or unexported fields
}
ValueMap is an insertion-ordered map from option human name to parsed value.