Skip to content

Commit babb335

Browse files
committed
feat: Command.SetVersionFunc
Currently, we can use `Command.Version` and `Command.SetVersionTemplate`, which generally works fine. I would like to propose a `Command.SetVersionFunc`, similar to `command.SetHelpFunc`. The rationale behind it is that the caller can style the output conditionally, e.g.: ``` $ pgr -v styled version output $ pgr -v | cat plain-text version output (output not a tty) ``` Right now, the way around it is to, before executing the root command, check if output is a terminal, detect color profile, build and set a styled template. This works, but can interfere with content being piped in/out (e.g. if you want to detect terminal background color and other terminal features). Signed-off-by: Carlos Alexandro Becker <[email protected]>
1 parent 7da941c commit babb335

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

command.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ type Command struct {
190190

191191
// versionTemplate is the version template defined by user.
192192
versionTemplate *tmplFunc
193+
// versionFunc is the version func defined by user.
194+
versionFunc func(*Command) error
193195

194196
// errPrefix is the error message prefix defined by user.
195197
errPrefix string
@@ -363,6 +365,14 @@ func (c *Command) SetHelpTemplate(s string) {
363365
c.helpTemplate = tmpl(s)
364366
}
365367

368+
// SetVersionFunc sets version function. Can be defined by Application.
369+
//
370+
// Setting this means that [Command.SetVersionTemplate] will not have any
371+
// effect any more.
372+
func (c *Command) SetVersionFunc(f func(*Command) error) {
373+
c.versionFunc = f
374+
}
375+
366376
// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
367377
func (c *Command) SetVersionTemplate(s string) {
368378
if s == "" {
@@ -639,6 +649,18 @@ func (c *Command) getVersionTemplateFunc() func(w io.Writer, data interface{}) e
639649
return defaultVersionFunc
640650
}
641651

652+
// getVersionFunc sreturns the version function for the command going up the
653+
// command tree if necessary.
654+
func (c *Command) getVersionFunc() func(*Command) error {
655+
if c.versionFunc != nil {
656+
return c.versionFunc
657+
}
658+
if c.HasParent() {
659+
return c.parent.parent.parent.getVersionFunc()
660+
}
661+
return nil
662+
}
663+
642664
// ErrPrefix return error message prefix for the command
643665
func (c *Command) ErrPrefix() string {
644666
if c.errPrefix != "" {
@@ -943,6 +965,9 @@ func (c *Command) execute(a []string) (err error) {
943965
return err
944966
}
945967
if versionVal {
968+
if fn := c.getVersionFunc(); fn != nil {
969+
return fn(c)
970+
}
946971
fn := c.getVersionTemplateFunc()
947972
err := fn(c.OutOrStdout(), c)
948973
if err != nil {

command_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2952,3 +2952,18 @@ func TestHelpFuncExecuted(t *testing.T) {
29522952

29532953
checkStringContains(t, output, helpText)
29542954
}
2955+
2956+
func TestVersionFuncExecuted(t *testing.T) {
2957+
rootCmd := &Command{Use: "root", Run: emptyRun, Version: "v2.3.4"}
2958+
rootCmd.SetVersionFunc(func(cmd *Command) error {
2959+
_, err := fmt.Fprint(cmd.OutOrStdout(), "custom version function: "+rootCmd.Version)
2960+
return err
2961+
})
2962+
2963+
output, err := executeCommandWithContext(context.Background(), rootCmd, "-v")
2964+
if err != nil {
2965+
t.Errorf("Unexpected error: %v", err)
2966+
}
2967+
2968+
checkStringContains(t, output, "custom version function: v2.3.4")
2969+
}

0 commit comments

Comments
 (0)