Support detailed help.
Any command/arg implementing the HelpProvider interface will be used to provide arbitrarily detailed help.
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var helpProviderType = reflect.TypeOf((*HelpProvider)(nil)).Elem()
|
||||||
|
|
||||||
func build(k *Kong, ast interface{}) (app *Application, err error) {
|
func build(k *Kong, ast interface{}) (app *Application, err error) {
|
||||||
defer catch(&err)
|
defer catch(&err)
|
||||||
v := reflect.ValueOf(ast)
|
v := reflect.ValueOf(ast)
|
||||||
@@ -107,6 +109,10 @@ func buildChild(k *Kong, node *Node, typ NodeType, v reflect.Value, ft reflect.S
|
|||||||
child.Help = tag.Help
|
child.Help = tag.Help
|
||||||
child.Hidden = tag.Hidden
|
child.Hidden = tag.Hidden
|
||||||
|
|
||||||
|
if fv.Type().Implements(helpProviderType) {
|
||||||
|
child.Detail = fv.Interface().(HelpProvider).Help()
|
||||||
|
}
|
||||||
|
|
||||||
// A branching argument. This is a bit hairy, as we let buildNode() do the parsing, then check that
|
// A branching argument. This is a bit hairy, as we let buildNode() do the parsing, then check that
|
||||||
// a positional argument is provided to the child, and move it to the branching argument field.
|
// a positional argument is provided to the child, and move it to the branching argument field.
|
||||||
if tag.Arg {
|
if tag.Arg {
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ type HelpOptions struct {
|
|||||||
Compact bool
|
Compact bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HelpProvider can be implemented by commands/args to provide detailed help.
|
||||||
|
type HelpProvider interface {
|
||||||
|
// This string is formatted by go/doc and thus has the same formatting rules.
|
||||||
|
Help() string
|
||||||
|
}
|
||||||
|
|
||||||
// HelpPrinter is used to print context-sensitive help.
|
// HelpPrinter is used to print context-sensitive help.
|
||||||
type HelpPrinter func(options HelpOptions, ctx *Context) error
|
type HelpPrinter func(options HelpOptions, ctx *Context) error
|
||||||
|
|
||||||
@@ -77,6 +83,10 @@ func printNodeDetail(w *helpWriter, node *Node) {
|
|||||||
if w.Summary {
|
if w.Summary {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if node.Detail != "" {
|
||||||
|
w.Print("")
|
||||||
|
w.Wrap(node.Detail)
|
||||||
|
}
|
||||||
if len(node.Positional) > 0 {
|
if len(node.Positional) > 0 {
|
||||||
w.Print("")
|
w.Print("")
|
||||||
w.Print("Arguments:")
|
w.Print("Arguments:")
|
||||||
|
|||||||
+13
-4
@@ -9,6 +9,16 @@ import (
|
|||||||
"github.com/alecthomas/kong"
|
"github.com/alecthomas/kong"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// nolint: govet
|
||||||
|
type threeArg struct {
|
||||||
|
RequiredThree bool `required`
|
||||||
|
Three string `arg`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (threeArg) Help() string {
|
||||||
|
return `Detailed help provided through the HelpProvider interface.`
|
||||||
|
}
|
||||||
|
|
||||||
func TestHelp(t *testing.T) {
|
func TestHelp(t *testing.T) {
|
||||||
// nolint: govet
|
// nolint: govet
|
||||||
var cli struct {
|
var cli struct {
|
||||||
@@ -26,10 +36,7 @@ func TestHelp(t *testing.T) {
|
|||||||
Flag string `help:"Nested flag under two."`
|
Flag string `help:"Nested flag under two."`
|
||||||
RequiredTwo bool `required`
|
RequiredTwo bool `required`
|
||||||
|
|
||||||
Three struct {
|
Three threeArg `arg help:"Sub-sub-arg."`
|
||||||
RequiredThree bool `required`
|
|
||||||
Three string `arg`
|
|
||||||
} `arg help:"Sub-sub-arg."`
|
|
||||||
|
|
||||||
Four struct {
|
Four struct {
|
||||||
} `cmd help:"Sub-sub-command."`
|
} `cmd help:"Sub-sub-command."`
|
||||||
@@ -95,6 +102,8 @@ Run "test-app <command> --help" for more information on a command.
|
|||||||
|
|
||||||
Sub-sub-arg.
|
Sub-sub-arg.
|
||||||
|
|
||||||
|
Detailed help provided through the HelpProvider interface.
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
--help Show context-sensitive help.
|
--help Show context-sensitive help.
|
||||||
--string=STRING A string flag.
|
--string=STRING A string flag.
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ type Node struct {
|
|||||||
Type NodeType
|
Type NodeType
|
||||||
Parent *Node
|
Parent *Node
|
||||||
Name string
|
Name string
|
||||||
Help string
|
Help string // Short help displayed in summaries.
|
||||||
|
Detail string // Detailed help displayed when describing command/arg alone.
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Flags []*Flag
|
Flags []*Flag
|
||||||
Positional []*Positional
|
Positional []*Positional
|
||||||
|
|||||||
Reference in New Issue
Block a user