Skip to content

Commit b6470ab

Browse files
committed
feat: add a field on command to deprecate
1 parent 09f1207 commit b6470ab

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

Diff for: command.go

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ type Command struct {
4343
// Hidden determines whether the command should be hidden from help.
4444
Hidden bool
4545

46+
// Deprecated indicates whether this command is deprecated.
47+
// If empty, the command is not deprecated.
48+
// If set, the value is used as the deprecation message.
49+
Deprecated string `json:"deprecated,omitempty"`
50+
4651
// RawArgs determines whether the command should receive unparsed arguments.
4752
// No flags are parsed when set, and the command is responsible for parsing
4853
// its own flags.
@@ -316,6 +321,13 @@ func (inv *Invocation) CurWords() (prev string, cur string) {
316321
// allArgs is wired through the stack so that global flags can be accepted
317322
// anywhere in the command invocation.
318323
func (inv *Invocation) run(state *runState) error {
324+
if inv.Command.Deprecated != "" {
325+
fmt.Fprintf(inv.Stderr, "%s %q is deprecated!. %s\n",
326+
prettyHeader("warning"),
327+
inv.Command.FullName(),
328+
inv.Command.Deprecated,
329+
)
330+
}
319331
err := inv.Command.Options.ParseEnv(inv.Environ)
320332
if err != nil {
321333
return xerrors.Errorf("parsing env: %w", err)

Diff for: command_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,27 @@ func TestCommand(t *testing.T) {
376376
err := i.Run()
377377
require.NoError(t, err, fio.Stdout.String())
378378
})
379+
380+
t.Run("DeprecatedCommand", func(t *testing.T) {
381+
t.Parallel()
382+
383+
deprecatedCmd := &serpent.Command{
384+
Use: "deprecated-cmd",
385+
Deprecated: "This command is deprecated and will be removed in the future.",
386+
Handler: func(i *serpent.Invocation) error {
387+
_, _ = i.Stdout.Write([]byte("Running deprecated command"))
388+
return nil
389+
},
390+
}
391+
392+
i := deprecatedCmd.Invoke()
393+
io := fakeIO(i)
394+
err := i.Run()
395+
require.NoError(t, err)
396+
expectedWarning := fmt.Sprintf("WARNING: %q is deprecated!. %s\n", deprecatedCmd.Use, deprecatedCmd.Deprecated)
397+
require.Equal(t, io.Stderr.String(), expectedWarning)
398+
require.Contains(t, io.Stdout.String(), "Running deprecated command")
399+
})
379400
}
380401

381402
func TestCommand_DeepNest(t *testing.T) {

Diff for: help.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,21 @@ func helpColor(s string) termenv.Color {
6262
return helpColorProfile.Color(s)
6363
}
6464

65+
// prettyHeader formats a header string with consistent styling.
66+
// It uppercases the text, adds a colon, and applies the header color.
67+
func prettyHeader(s string) string {
68+
headerFg := pretty.FgColor(helpColor("#337CA0"))
69+
s = strings.ToUpper(s)
70+
txt := pretty.String(s, ":")
71+
headerFg.Format(txt)
72+
return txt.String()
73+
}
74+
6575
var defaultHelpTemplate = func() *template.Template {
6676
var (
6777
optionFg = pretty.FgColor(
6878
helpColor("#04A777"),
6979
)
70-
headerFg = pretty.FgColor(
71-
helpColor("#337CA0"),
72-
)
7380
)
7481
return template.Must(
7582
template.New("usage").Funcs(
@@ -85,12 +92,7 @@ var defaultHelpTemplate = func() *template.Template {
8592
optionFg.Format(txt)
8693
return txt.String()
8794
},
88-
"prettyHeader": func(s string) string {
89-
s = strings.ToUpper(s)
90-
txt := pretty.String(s, ":")
91-
headerFg.Format(txt)
92-
return txt.String()
93-
},
95+
"prettyHeader": prettyHeader,
9496
"typeHelper": func(opt *Option) string {
9597
switch v := opt.Value.(type) {
9698
case *Enum:

Diff for: help.tpl

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
{{"\n"}}
99
{{- end}}
1010

11+
{{- with .Deprecated }}
12+
{{- indent (printf "DEPRECATED: %s" .) 2 | wrapTTY }}
13+
{{"\n"}}
14+
{{- end }}
15+
1116
{{ with .Aliases }}
1217
{{" Aliases: "}} {{- joinStrings .}}
1318
{{- end }}

0 commit comments

Comments
 (0)