Skip to content

Commit

Permalink
Add default usage
Browse files Browse the repository at this point in the history
  • Loading branch information
cristaloleg committed Oct 27, 2021
1 parent 0db01dc commit 1e225ba
Showing 1 changed file with 35 additions and 3 deletions.
38 changes: 35 additions & 3 deletions acmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"sort"
"text/tabwriter"
)

// Runner of the sub-commands.
Expand All @@ -33,9 +34,12 @@ type Command struct {

// Config for the runner.
type Config struct {
// AppName is an optional nal for the app, if empty os.Args[0] will be used.
// AppName is an optional name for the app, if empty os.Args[0] will be used.
AppName string

// AppDescription is an optional description. default is empty.
AppDescription string

// Version of the application.
Version string

Expand All @@ -46,7 +50,7 @@ type Config struct {
Args []string

// Usage of the application, if nil default will be used,
Usage func(name string, cmds []Command)
Usage func(cfg Config, cmds []Command)
}

// RunnerOf creates a Runner.
Expand Down Expand Up @@ -74,6 +78,10 @@ func (r *Runner) init() error {
r.ctx, _ = signal.NotifyContext(context.Background(), os.Interrupt)
}

if r.cfg.Usage == nil {
r.cfg.Usage = defaultUsage
}

names := make(map[string]struct{})
for _, cmd := range r.cmds {
switch {
Expand Down Expand Up @@ -110,7 +118,7 @@ func (r *Runner) run() error {
cmd, params := r.args[0], r.args[1:]
switch {
case cmd == "help":
r.cfg.Usage(r.cfg.AppName, r.cmds)
r.cfg.Usage(r.cfg, r.cmds)
return nil
case cmd == "version":
fmt.Printf("%s version: %s\n", r.cfg.AppName, r.cfg.Version)
Expand All @@ -124,3 +132,27 @@ func (r *Runner) run() error {
}
return fmt.Errorf("no such command %q", cmd)
}

var defaultUsage = func(cfg Config, cmds []Command) {
if cfg.AppDescription != "" {
fmt.Fprintf(os.Stderr, "%s\n\n", cfg.AppDescription)
}

fmt.Fprintf(os.Stderr, "Usage:\n\n %s <command> [arguments]\n\nThe commands are:\n\n", cfg.AppName)
printCommands(cmds)

if cfg.Version != "" {
fmt.Fprintf(os.Stderr, "Version: %s\n\n", cfg.Version)
}
}

// printCommands in a table form (Name and Description)
func printCommands(cmds []Command) {
minwidth, tabwidth, padding, padchar, flags := 0, 0, 11, byte(' '), uint(0)
tw := tabwriter.NewWriter(os.Stderr, minwidth, tabwidth, padding, padchar, flags)
for _, cmd := range cmds {
fmt.Fprintf(tw, " %s\t%s\n", cmd.Name, cmd.Description)
}
fmt.Fprint(tw, "\n")
tw.Flush()
}

0 comments on commit 1e225ba

Please sign in to comment.