Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: add a field on command to deprecate #24

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type Command struct {
// Hidden determines whether the command should be hidden from help.
Hidden bool

// Deprecated indicates whether this command is deprecated.
// If empty, the command is not deprecated.
// If set, the value is used as the deprecation message.
Deprecated string `json:"deprecated,omitempty"`

// RawArgs determines whether the command should receive unparsed arguments.
// No flags are parsed when set, and the command is responsible for parsing
// its own flags.
Expand Down Expand Up @@ -316,6 +321,13 @@ func (inv *Invocation) CurWords() (prev string, cur string) {
// allArgs is wired through the stack so that global flags can be accepted
// anywhere in the command invocation.
func (inv *Invocation) run(state *runState) error {
if inv.Command.Deprecated != "" {
fmt.Fprintf(inv.Stderr, "%s %q is deprecated!. %s\n",
prettyHeader("warning"),
inv.Command.FullName(),
inv.Command.Deprecated,
)
}
err := inv.Command.Options.ParseEnv(inv.Environ)
if err != nil {
return xerrors.Errorf("parsing env: %w", err)
Expand Down
21 changes: 21 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,27 @@ func TestCommand(t *testing.T) {
err := i.Run()
require.NoError(t, err, fio.Stdout.String())
})

t.Run("DeprecatedCommand", func(t *testing.T) {
t.Parallel()

deprecatedCmd := &serpent.Command{
Use: "deprecated-cmd",
Deprecated: "This command is deprecated and will be removed in the future.",
Handler: func(i *serpent.Invocation) error {
_, _ = i.Stdout.Write([]byte("Running deprecated command"))
return nil
},
}

i := deprecatedCmd.Invoke()
io := fakeIO(i)
err := i.Run()
require.NoError(t, err)
expectedWarning := fmt.Sprintf("WARNING: %q is deprecated!. %s\n", deprecatedCmd.Use, deprecatedCmd.Deprecated)
require.Equal(t, io.Stderr.String(), expectedWarning)
require.Contains(t, io.Stdout.String(), "Running deprecated command")
})
}

func TestCommand_DeepNest(t *testing.T) {
Expand Down
20 changes: 11 additions & 9 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,21 @@ func helpColor(s string) termenv.Color {
return helpColorProfile.Color(s)
}

// prettyHeader formats a header string with consistent styling.
// It uppercases the text, adds a colon, and applies the header color.
func prettyHeader(s string) string {
headerFg := pretty.FgColor(helpColor("#337CA0"))
s = strings.ToUpper(s)
txt := pretty.String(s, ":")
headerFg.Format(txt)
return txt.String()
}

var defaultHelpTemplate = func() *template.Template {
var (
optionFg = pretty.FgColor(
helpColor("#04A777"),
)
headerFg = pretty.FgColor(
helpColor("#337CA0"),
)
)
return template.Must(
template.New("usage").Funcs(
Expand All @@ -85,12 +92,7 @@ var defaultHelpTemplate = func() *template.Template {
optionFg.Format(txt)
return txt.String()
},
"prettyHeader": func(s string) string {
s = strings.ToUpper(s)
txt := pretty.String(s, ":")
headerFg.Format(txt)
return txt.String()
},
"prettyHeader": prettyHeader,
"typeHelper": func(opt *Option) string {
switch v := opt.Value.(type) {
case *Enum:
Expand Down
5 changes: 5 additions & 0 deletions help.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
{{"\n"}}
{{- end}}

{{- with .Deprecated }}
{{- indent (printf "DEPRECATED: %s" .) 2 | wrapTTY }}
{{"\n"}}
{{- end }}

{{ with .Aliases }}
{{" Aliases: "}} {{- joinStrings .}}
{{- end }}
Expand Down