forked from mirror/cobra
Refactored code to eliminate need for a commander. Much simpler interface now.
This commit is contained in:
parent
a2845e7f7a
commit
79bdde5f6c
|
@ -41,7 +41,13 @@ var cmdTimes = &Command{
|
||||||
Run: timesRunner,
|
Run: timesRunner,
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmdRoot = &Command{
|
var cmdRootNoRun = &Command{
|
||||||
|
Use: "cobra-test",
|
||||||
|
Short: "The root can run it's own function",
|
||||||
|
Long: "The root description for help",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmdRootWithRun = &Command{
|
||||||
Use: "cobra-test",
|
Use: "cobra-test",
|
||||||
Short: "The root can run it's own function",
|
Short: "The root can run it's own function",
|
||||||
Long: "The root description for help",
|
Long: "The root description for help",
|
||||||
|
@ -58,7 +64,8 @@ func flagInit() {
|
||||||
cmdEcho.ResetFlags()
|
cmdEcho.ResetFlags()
|
||||||
cmdPrint.ResetFlags()
|
cmdPrint.ResetFlags()
|
||||||
cmdTimes.ResetFlags()
|
cmdTimes.ResetFlags()
|
||||||
cmdRoot.ResetFlags()
|
cmdRootNoRun.ResetFlags()
|
||||||
|
cmdRootWithRun.ResetFlags()
|
||||||
cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
|
cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
|
||||||
cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
|
cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
|
||||||
cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
|
cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
|
||||||
|
@ -76,24 +83,22 @@ func commandInit() {
|
||||||
cmdTimes.ResetCommands()
|
cmdTimes.ResetCommands()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initialize() *Commander {
|
func initialize() *Command {
|
||||||
tt, tp, te = nil, nil, nil
|
tt, tp, te = nil, nil, nil
|
||||||
var c = NewCommander()
|
var c = cmdRootNoRun
|
||||||
c.SetName("cobratest")
|
|
||||||
flagInit()
|
flagInit()
|
||||||
commandInit()
|
commandInit()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeWithRootCmd() *Commander {
|
func initializeWithRootCmd() *Command {
|
||||||
cmdRoot.ResetCommands()
|
cmdRootWithRun.ResetCommands()
|
||||||
tt, tp, te, rootcalled = nil, nil, nil, false
|
tt, tp, te, rootcalled = nil, nil, nil, false
|
||||||
cmdRoot.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
|
|
||||||
cmdRoot.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag intthree")
|
|
||||||
var c = cmdRoot.ToCommander()
|
|
||||||
flagInit()
|
flagInit()
|
||||||
|
cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
|
||||||
|
cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag intthree")
|
||||||
commandInit()
|
commandInit()
|
||||||
return c
|
return cmdRootWithRun
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSingleCommand(t *testing.T) {
|
func TestSingleCommand(t *testing.T) {
|
||||||
|
@ -314,7 +319,7 @@ func TestHelpCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCommandToCommander(t *testing.T) {
|
func TestRunnableRootCommand(t *testing.T) {
|
||||||
c := initializeWithRootCmd()
|
c := initializeWithRootCmd()
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
c.AddCommand(cmdPrint, cmdEcho)
|
||||||
c.SetArgs([]string(nil))
|
c.SetArgs([]string(nil))
|
||||||
|
|
255
command.go
255
command.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,28 +45,152 @@ type Command struct {
|
||||||
// Run runs the command.
|
// Run runs the command.
|
||||||
// The args are the arguments after the command name.
|
// The args are the arguments after the command name.
|
||||||
Run func(cmd *Command, args []string)
|
Run func(cmd *Command, args []string)
|
||||||
// Commands is the list of commands supported by this Commander program.
|
// Commands is the list of commands supported by this program.
|
||||||
commands []*Command
|
commands []*Command
|
||||||
// Parent Command for this command
|
// Parent Command for this command
|
||||||
parent *Command
|
parent *Command
|
||||||
cmdr *Commander
|
|
||||||
flagErrorBuf *bytes.Buffer
|
flagErrorBuf *bytes.Buffer
|
||||||
|
|
||||||
|
args []string
|
||||||
|
output *io.Writer // nil means stderr; use out() accessor
|
||||||
|
usageFunc func(*Command) error // Usage can be defined by application
|
||||||
|
usageTemplate string // Can be defined by Application
|
||||||
|
helpTemplate string // Can be defined by Application
|
||||||
|
helpFunc func(*Command, []string) // Help can be defined by application
|
||||||
|
helpCommand *Command // The help command
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a Command into an (initialized) Commander
|
// os.Args[1:] by default, if desired, can be overridden
|
||||||
func (cmd *Command) ToCommander() (c *Commander) {
|
// particularly useful when testing.
|
||||||
c = NewCommander()
|
func (c *Command) SetArgs(a []string) {
|
||||||
c.name = cmd.Name()
|
c.args = a
|
||||||
c.Use = cmd.Use
|
}
|
||||||
c.Short = cmd.Short
|
|
||||||
c.Long = cmd.Long
|
func (c *Command) Out() io.Writer {
|
||||||
c.flags = cmd.flags
|
if c.output != nil {
|
||||||
c.pflags = cmd.pflags
|
return *c.output
|
||||||
c.Run = cmd.Run
|
}
|
||||||
c.commands = cmd.commands
|
|
||||||
c.resetChildrensParents()
|
if c.HasParent() {
|
||||||
c.flagErrorBuf = cmd.flagErrorBuf
|
return c.parent.Out()
|
||||||
|
} else {
|
||||||
|
return os.Stderr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOutput sets the destination for usage and error messages.
|
||||||
|
// If output is nil, os.Stderr is used.
|
||||||
|
func (c *Command) SetOutput(output io.Writer) {
|
||||||
|
c.output = &output
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage can be defined by application
|
||||||
|
func (c *Command) SetUsageFunc(f func(*Command) error) {
|
||||||
|
c.usageFunc = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be defined by Application
|
||||||
|
func (c *Command) SetUsageTemplate(s string) {
|
||||||
|
c.usageTemplate = s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be defined by Application
|
||||||
|
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
||||||
|
c.helpFunc = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) SetHelpCommand(cmd *Command) {
|
||||||
|
c.helpCommand = cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be defined by Application
|
||||||
|
func (c *Command) SetHelpTemplate(s string) {
|
||||||
|
c.helpTemplate = s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) UsageFunc() (f func(*Command) error) {
|
||||||
|
if c.usageFunc != nil {
|
||||||
|
return c.usageFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.parent.UsageFunc()
|
||||||
|
} else {
|
||||||
|
return func(c *Command) error {
|
||||||
|
err := tmpl(c.Out(), c.UsageTemplate(), c)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c *Command) HelpFunc() func(*Command, []string) {
|
||||||
|
if c.helpFunc != nil {
|
||||||
|
return c.helpFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.parent.HelpFunc()
|
||||||
|
} else {
|
||||||
|
return func(c *Command, args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
// Help called without any topic, calling on root
|
||||||
|
c.Root().Help()
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd, _, e := c.Root().Find(args)
|
||||||
|
if cmd == nil || e != nil {
|
||||||
|
c.Printf("Unknown help topic %#q.", args)
|
||||||
|
|
||||||
|
c.Root().Usage()
|
||||||
|
} else {
|
||||||
|
err := cmd.Help()
|
||||||
|
if err != nil {
|
||||||
|
c.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) UsageTemplate() string {
|
||||||
|
if c.usageTemplate != "" {
|
||||||
|
return c.usageTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.parent.UsageTemplate()
|
||||||
|
} else {
|
||||||
|
return `{{ $cmd := . }}
|
||||||
|
Usage: {{if .Runnable}}
|
||||||
|
{{.UseLine}}{{if .HasFlags}} [flags]{{end}}{{end}}{{if .HasSubCommands}}
|
||||||
|
{{ .CommandPath}} [command]{{end}}
|
||||||
|
{{ if .HasSubCommands}}
|
||||||
|
Available Commands: {{range .Commands}}{{if .Runnable}}
|
||||||
|
{{.Use | printf "%-15s"}} :: {{.Short}}{{end}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
{{ if .HasFlags}} Available Flags:
|
||||||
|
{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }}
|
||||||
|
Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{.CommandPath | printf "%-11s"}} :: {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}}
|
||||||
|
{{.CommandPath | printf "%-11s"}} :: {{.Short}}{{end}}{{end}}{{end}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
Use "{{.Root.Name}} help [command]" for more information about that command.
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) HelpTemplate() string {
|
||||||
|
if c.helpTemplate != "" {
|
||||||
|
return c.helpTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.parent.HelpTemplate()
|
||||||
|
} else {
|
||||||
|
return `{{.Long | trim}}
|
||||||
|
{{if .Runnable}}{{.UsageString}}{{end}}
|
||||||
|
`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Really only used when casting a command to a commander
|
// Really only used when casting a command to a commander
|
||||||
|
@ -83,7 +208,7 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(arrs) == 0 {
|
if len(arrs) == 0 {
|
||||||
return c.Commander().cmd, arrs, nil
|
return c.Root(), arrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var innerfind func(*Command, []string) (*Command, []string)
|
var innerfind func(*Command, []string) (*Command, []string)
|
||||||
|
@ -124,19 +249,6 @@ func (c *Command) Root() *Command {
|
||||||
return findRoot(c)
|
return findRoot(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) Commander() *Commander {
|
|
||||||
cmdr := c.Root()
|
|
||||||
if cmdr.cmdr != nil {
|
|
||||||
return cmdr.cmdr
|
|
||||||
} else {
|
|
||||||
panic("commander not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Command) Out() io.Writer {
|
|
||||||
return c.Commander().out()
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute the command determined by args and the command tree
|
// execute the command determined by args and the command tree
|
||||||
func (c *Command) findAndExecute(args []string) (err error) {
|
func (c *Command) findAndExecute(args []string) (err error) {
|
||||||
|
|
||||||
|
@ -162,6 +274,77 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call execute to use the args (os.Args[1:] by default)
|
||||||
|
// and run through the command tree finding appropriate matches
|
||||||
|
// for commands and then corresponding flags.
|
||||||
|
func (c *Command) Execute() (err error) {
|
||||||
|
|
||||||
|
// Regardless of what command execute is called on, run on Root only
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.Root().Execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize help as the last point possible to allow for user
|
||||||
|
// overriding
|
||||||
|
c.initHelp()
|
||||||
|
|
||||||
|
var args []string
|
||||||
|
|
||||||
|
if len(c.args) == 0 {
|
||||||
|
args = os.Args[1:]
|
||||||
|
} else {
|
||||||
|
args = c.args
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) == 0 {
|
||||||
|
// Only the executable is called and the root is runnable, run it
|
||||||
|
if c.Runnable() {
|
||||||
|
err = c.execute([]string(nil))
|
||||||
|
} else {
|
||||||
|
c.Usage()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = c.findAndExecute(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now handle the case where the root is runnable and only flags are provided
|
||||||
|
if err != nil && c.Runnable() {
|
||||||
|
e := c.ParseFlags(args)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
} else {
|
||||||
|
argWoFlags := c.Flags().Args()
|
||||||
|
if len(argWoFlags) > 0 {
|
||||||
|
c.Usage()
|
||||||
|
} else {
|
||||||
|
c.Run(c, argWoFlags)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.Println("Error:", err.Error())
|
||||||
|
c.Printf("%v: invalid command %#q\n", c.Root().Name(), os.Args[1:])
|
||||||
|
c.Printf("Run '%v help' for usage\n", c.Root().Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) initHelp() {
|
||||||
|
if c.helpCommand == nil {
|
||||||
|
c.helpCommand = &Command{
|
||||||
|
Use: "help [command]",
|
||||||
|
Short: "Help about any command",
|
||||||
|
Long: `Help provides help for any command in the application.
|
||||||
|
Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
||||||
|
Run: c.HelpFunc(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.AddCommand(c.helpCommand)
|
||||||
|
}
|
||||||
|
|
||||||
// Used for testing
|
// Used for testing
|
||||||
func (c *Command) ResetCommands() {
|
func (c *Command) ResetCommands() {
|
||||||
c.commands = nil
|
c.commands = nil
|
||||||
|
@ -184,7 +367,7 @@ func (c *Command) AddCommand(cmds ...*Command) {
|
||||||
|
|
||||||
// Convenience method to Print to the defined output
|
// Convenience method to Print to the defined output
|
||||||
func (c *Command) Print(i ...interface{}) {
|
func (c *Command) Print(i ...interface{}) {
|
||||||
c.Commander().PrintOut(i...)
|
fmt.Fprint(c.Out(), i...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience method to Println to the defined output
|
// Convenience method to Println to the defined output
|
||||||
|
@ -201,10 +384,10 @@ func (c *Command) Printf(format string, i ...interface{}) {
|
||||||
|
|
||||||
// Output the usage for the command
|
// Output the usage for the command
|
||||||
// Used when a user provides invalid input
|
// Used when a user provides invalid input
|
||||||
// Can be defined by user by overriding Commander.UsageFunc
|
// Can be defined by user by overriding UsageFunc
|
||||||
func (c *Command) Usage() error {
|
func (c *Command) Usage() error {
|
||||||
c.mergePersistentFlags()
|
c.mergePersistentFlags()
|
||||||
err := c.Commander().UsageFunc(c)
|
err := c.UsageFunc()(c)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,16 +396,16 @@ func (c *Command) Usage() error {
|
||||||
// by the default HelpFunc in the commander
|
// by the default HelpFunc in the commander
|
||||||
func (c *Command) Help() error {
|
func (c *Command) Help() error {
|
||||||
c.mergePersistentFlags()
|
c.mergePersistentFlags()
|
||||||
err := tmpl(c.Commander().Out(), c.Commander().HelpTemplate, c)
|
err := tmpl(c.Out(), c.HelpTemplate(), c)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) UsageString() string {
|
func (c *Command) UsageString() string {
|
||||||
tmpOutput := c.Commander().cmdr.output
|
tmpOutput := c.output
|
||||||
bb := new(bytes.Buffer)
|
bb := new(bytes.Buffer)
|
||||||
c.Commander().SetOutput(bb)
|
c.SetOutput(bb)
|
||||||
c.Usage()
|
c.Usage()
|
||||||
c.Commander().cmdr.output = tmpOutput
|
c.output = tmpOutput
|
||||||
return bb.String()
|
return bb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
188
commander.go
188
commander.go
|
@ -1,188 +0,0 @@
|
||||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Commands similar to git, go tools and other modern CLI tools
|
|
||||||
// inspired by go, go-Commander, gh and subcommand
|
|
||||||
|
|
||||||
package cobra
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Commander holds the configuration for the command line tool.
|
|
||||||
type Commander struct {
|
|
||||||
// A Commander is also a Command for top level and global help & flags
|
|
||||||
Command
|
|
||||||
|
|
||||||
args []string
|
|
||||||
output *io.Writer // nil means stderr; use out() accessor
|
|
||||||
UsageFunc func(*Command) error // Usage can be defined by application
|
|
||||||
UsageTemplate string // Can be defined by Application
|
|
||||||
HelpTemplate string // Can be defined by Application
|
|
||||||
HelpFunc func(*Command, []string) // Help can be defined by application
|
|
||||||
HelpCommand *Command // The help command
|
|
||||||
cmd *Command // The command version of itself
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide the user with a new commander.
|
|
||||||
func NewCommander() (c *Commander) {
|
|
||||||
c = new(Commander)
|
|
||||||
c.cmdr = c
|
|
||||||
c.UsageFunc = c.defaultUsage
|
|
||||||
c.HelpFunc = c.defaultHelp
|
|
||||||
c.initTemplates()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commander) initHelp() {
|
|
||||||
if c.HelpCommand == nil {
|
|
||||||
c.HelpCommand = &Command{
|
|
||||||
Use: "help [command]",
|
|
||||||
Short: "Help about any command",
|
|
||||||
Long: `Help provides help for any command in the application.
|
|
||||||
Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
|
||||||
Run: c.HelpFunc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.AddCommand(c.HelpCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name for commander, should match application name
|
|
||||||
func (c *Commander) SetName(name string) {
|
|
||||||
c.name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
// os.Args[1:] by default, if desired, can be overridden
|
|
||||||
// particularly useful when testing.
|
|
||||||
func (c *Commander) SetArgs(a []string) {
|
|
||||||
c.args = a
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call execute to use the args (os.Args[1:] by default)
|
|
||||||
// and run through the command tree finding appropriate matches
|
|
||||||
// for commands and then corresponding flags.
|
|
||||||
func (c *Commander) Execute() (err error) {
|
|
||||||
// initialize help as the last point possible to allow for user
|
|
||||||
// overriding
|
|
||||||
c.initHelp()
|
|
||||||
var args []string
|
|
||||||
|
|
||||||
if len(c.args) == 0 {
|
|
||||||
args = os.Args[1:]
|
|
||||||
} else {
|
|
||||||
args = c.args
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) == 0 {
|
|
||||||
// Only the executable is called and the root is runnable, run it
|
|
||||||
if c.Runnable() {
|
|
||||||
err = c.execute([]string(nil))
|
|
||||||
} else {
|
|
||||||
c.Usage()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = c.findAndExecute(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now handle the case where the root is runnable and only flags are provided
|
|
||||||
if err != nil && c.Runnable() {
|
|
||||||
e := c.ParseFlags(args)
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
} else {
|
|
||||||
argWoFlags := c.Flags().Args()
|
|
||||||
if len(argWoFlags) > 0 {
|
|
||||||
c.Usage()
|
|
||||||
} else {
|
|
||||||
c.Run(c.cmd, argWoFlags)
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.Println("Error:", err.Error())
|
|
||||||
c.Printf("%v: invalid command %#q\n", c.Root().Name(), os.Args[1:])
|
|
||||||
c.Printf("Run '%v help' for usage\n", c.Root().Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commander) out() io.Writer {
|
|
||||||
if c.output == nil {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
return *c.output
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmdr *Commander) defaultUsage(c *Command) error {
|
|
||||||
err := tmpl(cmdr.out(), cmdr.UsageTemplate, c)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmdr *Commander) defaultHelp(c *Command, args []string) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
// Help called without any topic, calling on root
|
|
||||||
c.Root().Help()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd, _, e := c.Root().Find(args)
|
|
||||||
if cmd == nil || e != nil {
|
|
||||||
cmdr.Printf("Unknown help topic %#q.", args)
|
|
||||||
|
|
||||||
c.Root().Usage()
|
|
||||||
} else {
|
|
||||||
err := cmd.Help()
|
|
||||||
if err != nil {
|
|
||||||
c.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Print to out
|
|
||||||
func (c *Commander) PrintOut(i ...interface{}) {
|
|
||||||
fmt.Fprint(c.out(), i...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOutput sets the destination for usage and error messages.
|
|
||||||
// If output is nil, os.Stderr is used.
|
|
||||||
func (c *Commander) SetOutput(output io.Writer) {
|
|
||||||
c.output = &output
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commander) initTemplates() {
|
|
||||||
c.UsageTemplate = `{{ $cmd := . }}
|
|
||||||
Usage: {{if .Runnable}}
|
|
||||||
{{.UseLine}}{{if .HasFlags}} [flags]{{end}}{{end}}{{if .HasSubCommands}}
|
|
||||||
{{ .CommandPath}} [command]{{end}}
|
|
||||||
{{ if .HasSubCommands}}
|
|
||||||
Available Commands: {{range .Commands}}{{if .Runnable}}
|
|
||||||
{{.Use | printf "%-15s"}} :: {{.Short}}{{end}}{{end}}
|
|
||||||
{{end}}
|
|
||||||
{{ if .HasFlags}} Available Flags:
|
|
||||||
{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }}
|
|
||||||
Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{.CommandPath | printf "%-11s"}} :: {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}}
|
|
||||||
{{.CommandPath | printf "%-11s"}} :: {{.Short}}{{end}}{{end}}{{end}}{{end}}
|
|
||||||
{{end}}
|
|
||||||
Use "{{.Commander.Name}} help [command]" for more information about that command.
|
|
||||||
`
|
|
||||||
|
|
||||||
c.HelpTemplate = `{{.Long | trim}}
|
|
||||||
{{if .Runnable}}{{.UsageString}}{{end}}
|
|
||||||
`
|
|
||||||
}
|
|
Loading…
Reference in New Issue