Codebase list golang-github-alecthomas-kong / 1300b2a
options: Add kong.ShortUsageOnError() option Add kong.ShortUsageOnError() option similar to kong.UsageOnError(). Add tests for UsageOnError and ShortUsageOnError. Remove the HelpOption summary reset at the beginning of DefaultHelpPrinter: func DefaultHelpPrinter(options HelpOptions, ctx *Context) error { - if ctx.Empty() { - options.Summary = false - } ⚠️ I'm not really sure what the implications of this are, tests still seem to pass, but maybe this has unintended side effects. Julia Ogris authored 3 years ago Alec Thomas committed 3 years ago
4 changed file(s) with 137 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
8484 default:
8585 return value.Help + " " + suffix
8686 }
87 }
88
89 // DefaultShortHelpPrinter is the default HelpPrinter for short help on error.
90 func DefaultShortHelpPrinter(options HelpOptions, ctx *Context) error {
91 w := newHelpWriter(ctx, options)
92 cmd := ctx.Selected()
93 app := ctx.Model
94 if cmd == nil {
95 w.Printf("Usage: %s%s", app.Name, app.Summary())
96 w.Printf(`Run "%s --help" for more information.`, app.Name)
97 } else {
98 w.Printf("Usage: %s %s", app.Name, cmd.Summary())
99 w.Printf(`Run "%s --help" for more information.`, cmd.FullPath())
100 }
101 return w.Write(ctx.Stdout)
87102 }
88103
89104 // DefaultHelpPrinter is the default HelpPrinter.
11
22 import (
33 "bytes"
4 "fmt"
45 "strings"
56 "testing"
67
511512 require.Equal(t, expected, w.String())
512513 })
513514 }
515
516 func TestUsageOnError(t *testing.T) {
517 var cli struct {
518 Flag string `help:"A required flag." required`
519 }
520 w := &strings.Builder{}
521 p := mustNew(t, &cli,
522 kong.Writers(w, w),
523 kong.Description("Some description."),
524 kong.Exit(func(int) {}),
525 kong.UsageOnError(),
526 )
527 _, err := p.Parse([]string{})
528 p.FatalIfErrorf(err)
529
530 expected := `Usage: test --flag=STRING
531
532 Some description.
533
534 Flags:
535 -h, --help Show context-sensitive help.
536 --flag=STRING A required flag.
537
538 test: error: missing flags: --flag=STRING
539 `
540 require.Equal(t, expected, w.String())
541 }
542
543 func TestShortUsageOnError(t *testing.T) {
544 var cli struct {
545 Flag string `help:"A required flag." required`
546 }
547 w := &strings.Builder{}
548 p := mustNew(t, &cli,
549 kong.Writers(w, w),
550 kong.Description("Some description."),
551 kong.Exit(func(int) {}),
552 kong.ShortUsageOnError(),
553 )
554 _, err := p.Parse([]string{})
555 require.Error(t, err)
556 p.FatalIfErrorf(err)
557
558 expected := `Usage: test --flag=STRING
559 Run "test --help" for more information.
560
561 test: error: missing flags: --flag=STRING
562 `
563 require.Equal(t, expected, w.String())
564 }
565
566 func TestCustomShortUsageOnError(t *testing.T) {
567 var cli struct {
568 Flag string `help:"A required flag." required`
569 }
570 w := &strings.Builder{}
571 shortHelp := func(_ kong.HelpOptions, ctx *kong.Context) error {
572 fmt.Fprintln(ctx.Stdout, "🤷 wish I could help")
573 return nil
574 }
575 p := mustNew(t, &cli,
576 kong.Writers(w, w),
577 kong.Description("Some description."),
578 kong.Exit(func(int) {}),
579 kong.ShortHelp(shortHelp),
580 kong.ShortUsageOnError(),
581 )
582 _, err := p.Parse([]string{})
583 require.Error(t, err)
584 p.FatalIfErrorf(err)
585
586 expected := `🤷 wish I could help
587
588 test: error: missing flags: --flag=STRING
589 `
590 require.Equal(t, expected, w.String())
591 }
3030 return k
3131 }
3232
33 type usageOnError int
34
35 const (
36 shortUsage usageOnError = iota + 1
37 fullUsage
38 )
39
3340 // Kong is the main parser type.
3441 type Kong struct {
3542 // Grammar model.
4754 registry *Registry
4855
4956 noDefaultHelp bool
50 usageOnError bool
57 usageOnError usageOnError
5158 help HelpPrinter
59 shortHelp HelpPrinter
5260 helpFormatter HelpValueFormatter
5361 helpOptions HelpOptions
5462 helpFlag *Flag
8391
8492 if k.help == nil {
8593 k.help = DefaultHelpPrinter
94 }
95
96 if k.shortHelp == nil {
97 k.shortHelp = DefaultShortHelpPrinter
8698 }
8799
88100 model, err := build(k, grammar)
330342 msg = fmt.Sprintf(args[0].(string), args[1:]...) + ": " + err.Error()
331343 }
332344 // Maybe display usage information.
333 if err, ok := err.(*ParseError); ok && k.usageOnError {
334 options := k.helpOptions
335 _ = k.help(options, err.Context)
336 fmt.Fprintln(k.Stdout)
345 if err, ok := err.(*ParseError); ok {
346 switch k.usageOnError {
347 case fullUsage:
348 _ = k.help(k.helpOptions, err.Context)
349 fmt.Fprintln(k.Stdout)
350 case shortUsage:
351 _ = k.shortHelp(k.helpOptions, err.Context)
352 fmt.Fprintln(k.Stdout)
353 }
337354 }
338355 k.Fatalf("%s", msg)
339356 }
191191 })
192192 }
193193
194 // ShortHelp configures the short usage message.
195 //
196 // It should be used together with kong.ShortUsageOnError() to display a
197 // custom short usage message on errors.
198 func ShortHelp(shortHelp HelpPrinter) Option {
199 return OptionFunc(func(k *Kong) error {
200 k.shortHelp = shortHelp
201 return nil
202 })
203 }
204
194205 // HelpFormatter configures how the help text is formatted.
195206 func HelpFormatter(helpFormatter HelpValueFormatter) Option {
196207 return OptionFunc(func(k *Kong) error {
250261 // UsageOnError configures Kong to display context-sensitive usage if FatalIfErrorf is called with an error.
251262 func UsageOnError() Option {
252263 return OptionFunc(func(k *Kong) error {
253 k.usageOnError = true
264 k.usageOnError = fullUsage
265 return nil
266 })
267 }
268
269 // ShortUsageOnError configures Kong to display context-sensitive short
270 // usage if FatalIfErrorf is called with an error. The default short
271 // usage message can be overridden with kong.ShortHelp(...).
272 func ShortUsageOnError() Option {
273 return OptionFunc(func(k *Kong) error {
274 k.usageOnError = shortUsage
254275 return nil
255276 })
256277 }