bonzai/z/cmd.go

698 lines
20 KiB
Go
Raw Normal View History

2022-02-20 00:22:03 +00:00
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
2022-02-17 23:09:19 +00:00
2022-04-01 10:12:53 +00:00
package Z
2022-02-17 23:09:19 +00:00
import (
"bytes"
"fmt"
2022-03-30 12:08:11 +00:00
"log"
2022-02-17 23:09:19 +00:00
"os"
2022-04-02 20:38:16 +00:00
"strconv"
"strings"
"text/template"
2022-02-17 23:09:19 +00:00
"github.com/rwxrob/bonzai"
"github.com/rwxrob/fn/each"
2022-03-28 16:32:05 +00:00
"github.com/rwxrob/fn/maps"
2022-04-02 20:38:16 +00:00
"github.com/rwxrob/fn/redu"
"github.com/rwxrob/structs/qstack"
"github.com/rwxrob/to"
2022-02-17 23:09:19 +00:00
)
type Cmd struct {
2022-04-02 11:40:00 +00:00
2022-04-11 08:01:29 +00:00
// main documentation, use Get* for filled template
Name string `json:"name,omitempty"` // plain
Aliases []string `json:"aliases,omitempty"` // plain
Summary string `json:"summary,omitempty"` // template
Usage string `json:"usage,omitempty"` // template
Version string `json:"version,omitempty"` // template
Copyright string `json:"copyright,omitempty"` // template
License string `json:"license,omitempty"` // template
Description string `json:"description,omitempty"` // template
Other []Section `json:"other,omitempty"` // template
// run-time additions to main documentation (ex: {{ exename }})
Dynamic template.FuncMap `json:"-"`
2022-04-11 09:41:40 +00:00
// administrative URLs
Site string `json:"site,omitempty"` // template, https:// assumed
2022-04-11 08:01:29 +00:00
Source string `json:"source,omitempty"` // template, usually git url
2022-04-11 09:41:40 +00:00
Issues string `json:"issues,omitempty"` // template, https:// assumed
2022-04-11 08:01:29 +00:00
// descending tree, completable
Commands []*Cmd `json:"commands,omitempty"`
Params []string `json:"params,omitempty"`
Hidden []string `json:"hidden,omitempty"`
// standard or custom completer, usually of form compfoo.New()
Comp bonzai.Completer `json:"-"`
2022-03-27 11:12:13 +00:00
2022-04-11 08:01:29 +00:00
// where the work happens
Caller *Cmd `json:"-"`
Call Method `json:"-"`
2022-04-11 08:01:29 +00:00
// faster than lots of "if" in Call
MinArgs int `json:"-"` // minimum number of args required (including parms)
2022-04-14 11:51:13 +00:00
MaxArgs int `json:"-"` // maximum number of args required (including parms)
NumArgs int `json:"-"` // exact number of args required (including parms)
2022-04-15 09:56:28 +00:00
NoArgs bool `json:"-"` // must not have any args
2022-04-11 08:01:29 +00:00
MinParm int `json:"-"` // minimum number of params required
MaxParm int `json:"-"` // maximum number of params required
2022-04-14 12:50:19 +00:00
UseConf bool `json:"-"` // requires Z.Conf be assigned
UseVars bool `json:"-"` // requires Z.Var be assigned
2022-04-11 08:01:29 +00:00
2022-04-09 06:51:43 +00:00
_aliases map[string]*Cmd // see cacheAliases called from Run->Seek->Resolve
2022-04-06 11:29:29 +00:00
_sections map[string]string // see cacheSections called from Run
}
// Section contains the Other sections of a command. Composition
// notation (without Title and Body) is not only supported but
// encouraged for clarity when reading the source for documentation.
type Section struct {
Title string
Body string
}
func (s Section) GetTitle() string { return s.Title }
func (s Section) GetBody() string { return s.Body }
2022-04-02 11:40:00 +00:00
// Names returns the Name and any Aliases grouped such that the Name is
// always last.
func (x *Cmd) Names() []string {
var names []string
names = append(names, x.Aliases...)
names = append(names, x.Name)
return names
}
// UsageNames returns single name, joined Names with bar (|) and wrapped
// in parentheses, or empty string if no names.
2022-04-02 20:38:16 +00:00
func (x *Cmd) UsageNames() string { return UsageGroup(x.Names(), 1, 1) }
// UsageParams returns the Params in UsageGroup notation.
func (x *Cmd) UsageParams() string {
return UsageGroup(x.Params, x.MinParm, x.MaxParm)
}
// UsageCmdNames returns the Names for each of its Commands joined, if
// more than one, with usage regex notation.
func (x *Cmd) UsageCmdNames() string {
var names []string
for _, n := range x.Commands {
names = append(names, n.UsageNames())
}
return UsageGroup(names, 1, 1)
}
2022-04-02 11:40:00 +00:00
// Title returns a dynamic field of Name and Summary combined (if
2022-04-02 20:38:16 +00:00
// exists). If the Name field of the commands is not defined will return
2022-04-11 08:01:29 +00:00
// a "{ERROR}". Fills template for Summary.
2022-04-02 11:40:00 +00:00
func (x *Cmd) Title() string {
2022-04-02 20:38:16 +00:00
if x.Name == "" {
return "{ERROR: Name is empty}"
}
2022-04-11 08:01:29 +00:00
summary := x.GetSummary()
2022-04-02 11:40:00 +00:00
switch {
2022-04-11 08:01:29 +00:00
case len(summary) > 0:
return x.Name + " - " + summary
2022-04-02 11:40:00 +00:00
default:
return x.Name
}
}
2022-04-10 21:05:53 +00:00
// GetLegal returns a single line with the combined values of the
2022-04-02 11:40:00 +00:00
// Name, Version, Copyright, and License. If Version is empty or nil an
2022-04-10 21:05:53 +00:00
// empty string is returned instead. GetLegal() is used by the
2022-04-02 11:40:00 +00:00
// version builtin command to aggregate all the version information into
// a single output.
2022-04-10 21:05:53 +00:00
func (x *Cmd) GetLegal() string {
copyright := x.GetCopyright()
license := x.GetLicense()
version := x.GetVersion()
2022-04-02 11:40:00 +00:00
switch {
2022-04-10 21:05:53 +00:00
case len(copyright) > 0 && len(license) == 0 && len(version) == 0:
return x.Name + " " + copyright
case len(copyright) > 0 && len(license) > 0 && len(version) > 0:
return x.Name + " (" + version + ") " +
copyright + "\nLicense " + license
case len(copyright) > 0 && len(license) > 0:
return x.Name + " " + copyright + "\nLicense " + license
case len(copyright) > 0 && len(version) > 0:
return x.Name + " (" + version + ") " + copyright
case len(copyright) > 0:
return x.Name + "\n" + copyright
2022-04-02 11:40:00 +00:00
default:
return ""
}
2022-04-10 21:05:53 +00:00
2022-04-02 11:40:00 +00:00
}
2022-04-06 11:29:29 +00:00
// OtherTitles returns just the ordered titles from Other.
func (x *Cmd) OtherTitles() []string { return maps.Keys(x._sections) }
func (x *Cmd) cacheAliases() {
x._aliases = map[string]*Cmd{}
if x.Commands == nil {
return
}
for _, c := range x.Commands {
if c.Aliases == nil {
continue
}
for _, a := range c.Aliases {
x._aliases[a] = c
}
}
2022-02-17 23:09:19 +00:00
}
2022-04-06 11:29:29 +00:00
func (x *Cmd) cacheSections() {
x._sections = map[string]string{}
if len(x.Other) == 0 {
return
}
for _, s := range x.Other {
x._sections[s.Title] = s.Body
}
}
2022-04-12 09:52:24 +00:00
// Run method resolves aliases and seeks the leaf Cmd. It then calls the
// leaf's first-class Call function passing itself as the first argument
// along with any remaining command line arguments. Run returns nothing
// because it usually exits the program. Normally, Run is called from
// within main() to convert the Cmd into an actual executable program.
// Exiting can be controlled, however, by calling ExitOn or ExitOff
// (primarily for testing). Use Call instead of Run when delegation is
// needed. However, avoid tight-coupling that comes from delegation with
2022-04-14 11:51:13 +00:00
// Call when possible. Also, Call automatically assumes the proper
// number and type of arguments have already been checked (see MinArgs,
// MaxArgs, NumArgs, etc.) which is normally done by Run. Use
// a high-level branch pkg instead (which is idiomatic for good Bonzai
// branch development).
2022-04-12 09:52:24 +00:00
//
// Handling Completion
//
// Since Run is the main execution entry point for all Bonzai command
// trees it is also responsible for handling completion (tab or
// otherwise). Therefore, all Run methods have two modes: delegation and
// completion (both are executions of the Bonzai binary command tree).
// Delegation is the default mode. Completion mode is triggered by the
// detection of the COMP_LINE environment variable.
//
// COMP_LINE
//
// When COMP_LINE is set, Run prints a list of possible completions to
// standard output by calling its Comp.Complete function
2022-04-12 09:52:24 +00:00
// (default Z.Comp). Each Cmd therefore manages its own completion and
// can draw from a rich ecosystem of Completers or assign its own custom
// one. This enables very powerful completions including dynamic
// completions that query the network or the local execution
// environment. Since Go can run on pretty much every device
// architecture right now, that's a lot of possibilities. Even
// a line-based calculator can be implemented as a Completer. AI
// completers are also fully supported by this approach. Intelligent
// completion eliminates the need for overly complex and error-prone
// (getopt) argument signatures for all Bonzai commands.
//
// Why COMP_LINE?
//
// Setting COMP_LINE has been a bash shell standard for more than a few
// decades. (Unfortunately, zsh dubiously chose to not support it for no
// good reason.) COMP_LINE completion, therefore, is the only planned
// method of detecting completion context. Enabling it in bash for any
// command becomes a simple matter of "complete -C foo foo" (rather than
// forcing users to evaluate thousands of lines of shell code to enable
// completion for even minimally complex command trees as other
// "commanders" require). Any code will work that sets COMP_LINE before
// calling Cmd.Run and receives a list of lines to standard
// output with completion candidates.
2022-02-17 23:09:19 +00:00
func (x *Cmd) Run() {
2022-04-08 07:59:50 +00:00
defer TrapPanic()
2022-02-17 23:09:19 +00:00
2022-04-14 11:51:13 +00:00
// returns throughout are because Exit* can be disabled
// see ExitOff/On
2022-04-06 11:29:29 +00:00
x.cacheSections()
2022-04-01 10:12:53 +00:00
// resolve Z.Aliases (if completion didn't replace them)
2022-03-30 13:30:41 +00:00
if len(os.Args) > 1 {
2022-03-28 16:32:05 +00:00
args := []string{os.Args[0]}
alias := Aliases[os.Args[1]]
if alias != nil {
args = append(args, alias...)
args = append(args, os.Args[2:]...)
os.Args = args
}
}
2022-04-14 11:51:13 +00:00
// COMPLETION
2022-04-09 06:51:43 +00:00
2022-04-12 09:52:24 +00:00
line := os.Getenv("COMP_LINE")
2022-02-17 23:09:19 +00:00
if line != "" {
2022-03-28 16:32:05 +00:00
var list []string
// find the leaf command
2022-03-28 16:32:05 +00:00
lineargs := ArgsFrom(line)
2022-03-30 00:08:31 +00:00
if len(lineargs) == 2 {
2022-03-28 16:32:05 +00:00
list = append(list, maps.KeysWithPrefix(Aliases, lineargs[1])...)
}
cmd, args := x.Seek(lineargs[1:])
// default completer or package aliases, always exits
if cmd.Comp == nil {
if Comp != nil {
list = append(list, Comp.Complete(cmd, args...)...)
}
2022-03-30 11:38:14 +00:00
if len(list) == 1 && len(lineargs) == 2 {
2022-03-30 00:08:31 +00:00
if v, has := Aliases[list[0]]; has {
2022-03-30 15:15:29 +00:00
fmt.Println(strings.Join(EscAll(v), " "))
2022-03-30 00:08:31 +00:00
Exit()
2022-04-14 11:51:13 +00:00
return
2022-03-30 00:08:31 +00:00
}
}
2022-02-27 07:02:28 +00:00
each.Println(list)
2022-02-18 03:06:48 +00:00
Exit()
2022-04-14 11:51:13 +00:00
return
2022-02-17 23:09:19 +00:00
}
// own completer, delegate
each.Println(cmd.Comp.Complete(cmd, args...))
2022-02-17 23:09:19 +00:00
Exit()
2022-04-14 11:51:13 +00:00
return
2022-02-17 23:09:19 +00:00
}
2022-04-14 11:51:13 +00:00
// DELEGATION
2022-04-12 09:52:24 +00:00
2022-02-18 03:06:48 +00:00
// seek should never fail to return something, but ...
cmd, args := x.Seek(os.Args[1:])
2022-04-09 06:51:43 +00:00
2022-02-18 03:06:48 +00:00
if cmd == nil {
2022-04-14 11:51:13 +00:00
ExitError(IncorrectUsage{cmd})
return
2022-02-18 03:06:48 +00:00
}
2022-02-17 23:09:19 +00:00
2022-02-18 03:06:48 +00:00
// default to first Command if no Call defined
if cmd.Call == nil {
2022-03-26 21:12:50 +00:00
if len(cmd.Commands) > 0 {
fcmd := cmd.Commands[0]
if fcmd.Call == nil {
ExitError(DefCmdReqCall{cmd})
return
2022-04-06 13:05:10 +00:00
}
fcmd.Caller = cmd
cmd = fcmd
2022-03-26 21:12:50 +00:00
} else {
ExitError(NoCallNoCommands{cmd})
return
2022-02-17 23:09:19 +00:00
}
2022-02-18 03:06:48 +00:00
}
switch {
2022-04-15 09:56:28 +00:00
case len(args) > 0 && cmd.NoArgs:
ExitError(TooManyArgs{cmd})
return
case len(args) < cmd.MinArgs:
ExitError(NotEnoughArgs{cmd})
2022-04-14 12:50:19 +00:00
return
case cmd.MaxArgs > 0 && len(args) > cmd.MaxArgs:
ExitError(TooManyArgs{cmd})
2022-04-14 12:50:19 +00:00
return
case cmd.NumArgs > 0 && len(args) != cmd.NumArgs:
ExitError(WrongNumArgs{cmd})
2022-04-14 12:50:19 +00:00
return
case cmd.UseConf && Conf == nil:
ExitError(UsesConf{cmd})
return
case cmd.UseVars && Vars == nil:
ExitError(UsesVars{cmd})
return
2022-04-09 20:27:24 +00:00
}
2022-02-18 03:06:48 +00:00
// delegate
2022-04-06 13:05:10 +00:00
if cmd.Caller == nil {
cmd.Caller = x
}
2022-03-26 21:12:50 +00:00
if err := cmd.Call(cmd, args...); err != nil {
2022-02-18 03:06:48 +00:00
ExitError(err)
2022-04-14 11:51:13 +00:00
return
2022-02-18 03:06:48 +00:00
}
Exit()
2022-02-17 23:09:19 +00:00
}
2022-04-11 18:08:31 +00:00
// Root returns the root Cmd from the current Path. This must always be
// calculated every time since any Cmd can change positions and
// pedigrees at any time at run time. Returns self if no PathCmds found.
func (x *Cmd) Root() *Cmd {
cmds := x.PathCmds()
if len(cmds) > 0 {
return cmds[0].Caller
}
return x.Caller
}
2022-02-17 23:09:19 +00:00
// Add creates a new Cmd and sets the name and aliases and adds to
// Commands returning a reference to the new Cmd. The name must be
// first.
func (x *Cmd) Add(name string, aliases ...string) *Cmd {
c := &Cmd{
Name: name,
Aliases: aliases,
}
x.Commands = append(x.Commands, c)
return c
}
2022-04-09 06:51:43 +00:00
// Resolve looks up a given Command by name or alias from Aliases
// (caching a lookup map of aliases in the process).
2022-04-02 20:38:16 +00:00
func (x *Cmd) Resolve(name string) *Cmd {
2022-04-09 06:51:43 +00:00
2022-02-17 23:09:19 +00:00
if x.Commands == nil {
return nil
}
2022-04-09 06:51:43 +00:00
2022-02-17 23:09:19 +00:00
for _, c := range x.Commands {
if name == c.Name {
return c
}
}
2022-04-09 06:51:43 +00:00
if x._aliases == nil {
x.cacheAliases()
}
if c, has := x._aliases[name]; has {
return c
}
2022-02-17 23:09:19 +00:00
return nil
}
2022-04-02 20:38:16 +00:00
// CmdNames returns the names of every Command.
2022-02-17 23:09:19 +00:00
func (x *Cmd) CmdNames() []string {
list := []string{}
for _, c := range x.Commands {
if c.Name == "" {
continue
}
list = append(list, c.Name)
}
return list
}
2022-04-02 20:38:16 +00:00
// UsageCmdTitles returns a single string with the titles of each
// subcommand indented and with a maximum title signature length for
// justification. Hidden commands are not included. Note that the order
// of the Commands is preserved (not necessarily alphabetic).
func (x *Cmd) UsageCmdTitles() string {
var set []string
var summaries []string
for _, c := range x.Commands {
set = append(set, strings.Join(c.Names(), "|"))
2022-04-10 21:05:53 +00:00
summaries = append(summaries, c.GetSummary())
2022-04-02 20:38:16 +00:00
}
longest := redu.Longest(set)
var buf string
for n := 0; n < len(set); n++ {
if len(summaries[n]) > 0 {
buf += fmt.Sprintf(`%-`+strconv.Itoa(longest)+"v - %v\n", set[n], summaries[n])
} else {
buf += fmt.Sprintf(`%-`+strconv.Itoa(longest)+"v\n", set[n])
}
}
return buf
}
2022-02-17 23:09:19 +00:00
// Param returns Param matching name if found, empty string if not.
func (x *Cmd) Param(p string) string {
if x.Params == nil {
return ""
}
for _, c := range x.Params {
if p == c {
return c
}
}
return ""
}
// IsHidden returns true if the specified name is in the list of
// Hidden commands.
func (x *Cmd) IsHidden(name string) bool {
if x.Hidden == nil {
return false
}
for _, h := range x.Hidden {
if h == name {
return true
}
}
return false
}
2022-04-10 21:05:53 +00:00
// Seek checks the args for command names returning the deepest along
// with the remaining arguments. Typically the args passed are directly
// from the command line.
2022-02-17 23:09:19 +00:00
func (x *Cmd) Seek(args []string) (*Cmd, []string) {
2022-02-25 07:37:29 +00:00
if args == nil || x.Commands == nil {
2022-02-17 23:09:19 +00:00
return x, args
}
cur := x
n := 0
for ; n < len(args); n++ {
2022-04-02 20:38:16 +00:00
next := cur.Resolve(args[n])
2022-02-17 23:09:19 +00:00
if next == nil {
break
}
2022-02-24 14:02:18 +00:00
next.Caller = cur
2022-02-17 23:09:19 +00:00
cur = next
}
return cur, args[n:]
}
2022-04-11 18:08:31 +00:00
// PathCmds returns the path of commands used to arrive at this
// command. The path is determined by walking backward from current
// Caller up rather than depending on anything from the command line
// used to invoke the composing binary. Also see Path, PathNames.
func (x *Cmd) PathCmds() []*Cmd {
path := qstack.New[*Cmd]()
path.Unshift(x)
for p := x.Caller; p != nil; p = p.Caller {
path.Unshift(p)
}
path.Shift()
return path.Items()
}
2022-04-10 21:05:53 +00:00
// PathNames returns the path of command names used to arrive at this
// command. The path is determined by walking backward from current
// Caller up rather than depending on anything from the command line
2022-04-10 21:05:53 +00:00
// used to invoke the composing binary. Also see Path.
func (x *Cmd) PathNames() []string {
path := qstack.New[string]()
path.Unshift(x.Name)
for p := x.Caller; p != nil; p = p.Caller {
path.Unshift(p.Name)
}
path.Shift()
return path.Items()
}
2022-04-10 21:05:53 +00:00
// Path returns a dotted notation of the PathNames including an initial
// dot (for root). This is compatible yq query expressions and useful
// for associating configuration and other data specifically with this
2022-04-14 13:10:21 +00:00
// command. If any arguments are passed then will be added with dots
// between them.
func (x *Cmd) Path(more ...string) string {
if len(more) > 0 {
list := x.PathNames()
list = append(list, more...)
return "." + strings.Join(list, ".")
}
2022-04-10 21:05:53 +00:00
return "." + strings.Join(x.PathNames(), ".")
2022-03-27 12:25:17 +00:00
}
2022-03-30 12:08:11 +00:00
// Log is currently short for log.Printf() but may be supplemented in
// the future to have more fine-grained control of logging.
func (x *Cmd) Log(format string, a ...any) {
log.Printf(format, a...)
}
// C is a shorter version of
// strings.TrimSpace(Z.Conf.Query(x.Path()+"."+q)) for convenience. The
// yq YAML/JSON queries unreliably add line returns sometimes and other
// times not. If a line return is wanted, the caller will need to use
// fmt.Println. Also see UseConf.
func (x *Cmd) C(q string) (string, error) {
if Conf == nil {
return "", UsesConf{x}
}
2022-04-11 11:47:36 +00:00
path := x.Path()
if path != "." {
path += "."
}
res, err := Conf.Query(path + q)
if err != nil {
return "", err
}
return strings.TrimSpace(res), nil
2022-04-11 11:47:36 +00:00
}
// Get is a shorter version of Z.Vars.Get(x.Path()+"."+key) for
// convenience. Also see UseVars.
func (x *Cmd) Get(key string) (string, error) {
2022-04-11 11:47:36 +00:00
if Vars == nil {
return "", UsesVars{x}
2022-04-11 11:47:36 +00:00
}
path := x.Path()
if path != "." {
path += "."
}
return Vars.Get(path + key), nil
2022-04-11 11:47:36 +00:00
}
// Set is a shorter version of Z.Vars.Set(x.Path()+"."+key.val) for
2022-04-14 12:50:19 +00:00
// convenience. Logs the error Z.Vars is not defined (see UseVars).
2022-04-11 11:47:36 +00:00
func (x *Cmd) Set(key, val string) error {
if Vars == nil {
2022-04-14 12:50:19 +00:00
return UsesVars{x}
2022-04-11 11:47:36 +00:00
}
path := x.Path()
if path != "." {
path += "."
}
return Vars.Set(path+key, val)
}
2022-02-17 23:09:19 +00:00
// Fill fills out the passed text/template string using the Cmd instance
// as the data object source for the template. It is called by the Get*
2022-04-10 21:05:53 +00:00
// family of field accessors but can be called directly as well. Also
// see markfunc.go for list of predefined template functions.
func (x *Cmd) Fill(tmpl string) string {
funcs := to.MergedMaps(markFuncMap, x.Dynamic)
t, err := template.New("t").Funcs(funcs).Parse(tmpl)
if err != nil {
log.Println(err)
}
var buf bytes.Buffer
if err := t.Execute(&buf, x); err != nil {
log.Println(err)
}
return buf.String()
}
2022-04-14 14:33:47 +00:00
// UsageError returns IncorrectUsage for self.
func (x *Cmd) UsageError() error {
return IncorrectUsage{x}
}
// --------------------- bonzai.Command interface ---------------------
2022-02-17 23:09:19 +00:00
2022-04-11 08:01:29 +00:00
// GetName fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetName() string { return x.Name }
2022-02-17 23:09:19 +00:00
2022-04-11 08:01:29 +00:00
// GetTitle fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetTitle() string { return x.Title() }
2022-04-10 21:05:53 +00:00
// GetAliases fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetAliases() []string { return x.Aliases }
2022-04-10 21:05:53 +00:00
// GetSummary fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetSummary() string { return x.Fill(x.Summary) }
2022-04-15 09:56:28 +00:00
// GetUsage fulfills the bonzai.Command interface. Uses x.Usage if not
// empty. Otherwise, calls UsageFunc to get usage, then uses Fill.
func (x *Cmd) GetUsage() string {
usage := x.Usage
if usage == "" {
usage = UsageFunc(x)
}
return x.Fill(usage)
}
2022-04-10 21:05:53 +00:00
// GetVersion fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetVersion() string { return x.Fill(x.Version) }
2022-04-10 21:05:53 +00:00
// GetCopyright fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetCopyright() string { return x.Fill(x.Copyright) }
2022-04-10 21:05:53 +00:00
// GetLicense fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetLicense() string { return x.Fill(x.License) }
2022-02-17 23:09:19 +00:00
2022-04-10 21:05:53 +00:00
// GetDescription fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetDescription() string { return x.Fill(x.Description) }
2022-04-10 21:05:53 +00:00
// GetSite fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetSite() string { return x.Fill(x.Site) }
2022-04-10 21:05:53 +00:00
// GetSource fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetSource() string { return x.Fill(x.Source) }
2022-04-10 21:05:53 +00:00
// GetIssues fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetIssues() string { return x.Fill(x.Issues) }
2022-04-10 21:05:53 +00:00
// GetMinArgs fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetMinArgs() int { return x.MinArgs }
2022-04-10 21:05:53 +00:00
// GetMinParm fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetMinParm() int { return x.MinParm }
2022-04-10 21:05:53 +00:00
// GetMaxParm fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetMaxParm() int { return x.MaxParm }
2022-04-14 12:50:19 +00:00
// GetUseConf fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetUseConf() bool { return x.UseConf }
2022-04-14 12:50:19 +00:00
// GetUseVars fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetUseVars() bool { return x.UseVars }
2022-04-09 20:27:24 +00:00
// GetCommands fulfills the bonzai.Command interface.
func (x *Cmd) GetCommands() []bonzai.Command {
var commands []bonzai.Command
for _, s := range x.Commands {
commands = append(commands, bonzai.Command(s))
}
return commands
}
2022-04-10 21:05:53 +00:00
// GetCommandNames fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetCommandNames() []string { return x.CmdNames() }
// GetHidden fulfills the bonzai.Command interface.
2022-02-17 23:09:19 +00:00
func (x *Cmd) GetHidden() []string { return x.Hidden }
// GetParams fulfills the bonzai.Command interface.
2022-02-17 23:09:19 +00:00
func (x *Cmd) GetParams() []string { return x.Params }
2022-04-10 21:05:53 +00:00
// GetOther fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetOther() []bonzai.Section {
var sections []bonzai.Section
for _, s := range x.Other {
s.Body = x.Fill(s.Body)
sections = append(sections, bonzai.Section(s))
}
return sections
}
2022-04-10 21:05:53 +00:00
// GetOtherTitles fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetOtherTitles() []string {
var titles []string
for _, title := range x.OtherTitles() {
2022-04-10 21:05:53 +00:00
titles = append(titles, title)
}
return titles
}
2022-02-24 14:02:18 +00:00
// GetComp fulfills the Command interface.
func (x *Cmd) GetComp() bonzai.Completer { return x.Comp }
2022-02-24 14:02:18 +00:00
// GetCaller fulfills the bonzai.Command interface.
func (x *Cmd) GetCaller() bonzai.Command { return x.Caller }