From 10d4657d5df6afa2dd9907712cdc09aeb53c7207 Mon Sep 17 00:00:00 2001 From: Steve Russo Date: Sun, 19 May 2024 19:03:56 -0400 Subject: [PATCH] refactor: build opt,arg,subcmd usage strings in code instead of in template --- generate.go | 121 +++++++++++++++++++++------------------- tmpls/usagefunc.go.tmpl | 15 ++--- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/generate.go b/generate.go index f82391d..29f116e 100644 --- a/generate.go +++ b/generate.go @@ -160,8 +160,71 @@ func (g *generator) genCommandCode(c *command) error { return nil } +type usgTmplData struct { + OptUsgs []string + ArgUsgs []string + SubcmdUsgs []string + + *command +} + func (g *generator) genCmdUsageFunc(c *command) error { - err := g.usgFnTmpl.Execute(&g.buf, c) + optUsgs := make([]string, len(c.Opts)) + { + var optNameColWidth int + for _, o := range c.Opts { + if l := len(o.usgNameAndArg()); l > optNameColWidth { + optNameColWidth = l + } + } + for i, o := range c.Opts { + paddedNameAndArg := fmt.Sprintf(" %-*s ", optNameColWidth, o.usgNameAndArg()) + desc := o.data.Blurb + if v, ok := o.data.getConfig("env"); ok { + desc += " [$" + v + "]" + } + optUsgs[i] = paddedNameAndArg + wrapBlurb(desc, len(paddedNameAndArg), maxUsgLineLen) + } + } + + argUsgs := make([]string, len(c.Args)) + { + var argNameColWidth int + for _, a := range c.Args { + if l := len(a.UsgName()); l > argNameColWidth { + argNameColWidth = l + } + } + for i, a := range c.Args { + paddedName := fmt.Sprintf(" %-*s ", argNameColWidth, a.UsgName()) + desc := a.data.Blurb + if v, ok := a.data.getConfig("env"); ok { + desc += " [$" + v + "]" + } + argUsgs[i] = paddedName + wrapBlurb(desc, len(paddedName), maxUsgLineLen) + } + } + + subcmdUsgs := make([]string, len(c.Subcmds)) + { + var subcmdNameColWidth int + for _, sc := range c.Subcmds { + if l := len(sc.UsgName()); l > subcmdNameColWidth { + subcmdNameColWidth = l + } + } + for i, sc := range c.Subcmds { + paddedName := fmt.Sprintf(" %-*s ", subcmdNameColWidth, sc.UsgName()) + subcmdUsgs[i] = paddedName + wrapBlurb(sc.Data.Blurb, len(paddedName), maxUsgLineLen) + } + } + + err := g.usgFnTmpl.Execute(&g.buf, usgTmplData{ + OptUsgs: optUsgs, + ArgUsgs: argUsgs, + SubcmdUsgs: subcmdUsgs, + command: c, + }) if err != nil { return err } @@ -232,36 +295,6 @@ func (c *command) Overview() string { return s.String() } -func (c *command) OptNameColWidth() int { - w := 0 - for _, o := range c.Opts { - if l := len(o.usgNameAndArg()); l > w { - w = l - } - } - return w -} - -func (c *command) ArgNameColWidth() int { - w := 0 - for _, a := range c.Args { - if l := len(a.UsgName()); l > w { - w = l - } - } - return w -} - -func (c *command) SubcmdNameColWidth() int { - w := 0 - for _, sc := range c.Subcmds { - if l := len(sc.UsgName()); l > w { - w = l - } - } - return w -} - func (o *option) EnvVar() string { name, _ := o.data.getConfig("env") return name @@ -288,26 +321,6 @@ func (a *argument) IsRequired() bool { return ok } -// Usg returns an argument's usage message text given how wide the name column should be. -func (a *argument) Usg(nameWidth int) string { - paddedName := fmt.Sprintf(" %-*s ", nameWidth, a.UsgName()) - desc := a.data.Blurb - if v, ok := a.data.getConfig("env"); ok { - desc += " [$" + v + "]" - } - return paddedName + wrapBlurb(desc, len(paddedName), maxUsgLineLen) -} - -// Usg returns an option's usage message text given how wide the name column should be. -func (o *option) Usg(nameWidth int) string { - paddedNameAndArg := fmt.Sprintf(" %-*s ", nameWidth, o.usgNameAndArg()) - desc := o.data.Blurb - if v, ok := o.data.getConfig("env"); ok { - desc += " [$" + v + "]" - } - return paddedNameAndArg + wrapBlurb(desc, len(paddedNameAndArg), maxUsgLineLen) -} - func (o *option) usgNameAndArg() string { s := "-" + o.Name if an := o.usgArgName(); an != "" { @@ -329,12 +342,6 @@ func (o *option) usgArgName() string { return "" } -// Usg returns a command's usage message text given how wide the name column should be. -func (c *command) Usg(nameWidth int) string { - paddedName := fmt.Sprintf(" %-*s ", nameWidth, c.UsgName()) - return paddedName + wrapBlurb(c.Data.Blurb, len(paddedName), maxUsgLineLen) -} - // HasEnvArgOrOptSomewhere returns true if this command or one of its subcommands contains // an option or an argument that uses an environment variable config. func (c *command) HasEnvArgOrOptSomewhere() bool { diff --git a/tmpls/usagefunc.go.tmpl b/tmpls/usagefunc.go.tmpl index ebf1af0..5e5d0c2 100644 --- a/tmpls/usagefunc.go.tmpl +++ b/tmpls/usagefunc.go.tmpl @@ -9,26 +9,23 @@ overview: usage:{{ range .UsageLines }} {{ . }}{{ end }} -{{- with .Opts }} - {{- $nameWidth := $.OptNameColWidth }} +{{- with .OptUsgs }} options:{{ range . }} -{{ .Usg $nameWidth }}{{ end -}} +{{ . }}{{ end -}} {{ end -}} -{{- with .Args }} - {{- $nameWidth := $.ArgNameColWidth }} +{{- with .ArgUsgs }} arguments:{{ range . }} -{{ .Usg $nameWidth -}} +{{ . -}} {{ end -}} {{ end -}} -{{ with .Subcmds }} -{{- $w := $.SubcmdNameColWidth }} +{{ with .SubcmdUsgs }} subcommands:{{ range . }} -{{ .Usg $w -}} +{{ . -}} {{ end -}} {{- if $.IsRoot }}