Skip to content

Commit

Permalink
Better help (#2733)
Browse files Browse the repository at this point in the history
* Wrap command and flag descriptions for cleaner help output

* Move help command to root, group commands

* Add deprecation warnings, hide long deprecated commands

* Wrap command and flag descriptions for cleaner help output

* Move help command to root, group commands

* Add deprecation warnings, hide long deprecated commands

* Add subcommands to root command output

* Deprecate history

* Fix wrapping for unauthenticated message

* tweak wording

* Fix broken docker secrets docs url
  • Loading branch information
michaeldwan committed Aug 30, 2023
1 parent a7afc1a commit ab31e74
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 247 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -32,6 +32,7 @@ require (
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3
github.com/jinzhu/copier v0.3.5
github.com/jpillora/backoff v1.0.0
github.com/kr/text v0.2.0
github.com/loadsmart/calver-go v0.0.0-20230323142215-56cf73a68e8a
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mattn/go-colorable v0.1.13
Expand Down
78 changes: 78 additions & 0 deletions internal/cli/cli.go
Expand Up @@ -5,15 +5,22 @@ import (
"context"
"errors"
"fmt"
"html/template"
"os"
"runtime/debug"
"strings"
"time"

"github.com/AlecAivazis/survey/v2/terminal"
"github.com/MakeNowJust/heredoc/v2"
"github.com/kr/text"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/superfly/flyctl/internal/flag/flagnames"
"github.com/superfly/flyctl/internal/flyerr"
"github.com/superfly/flyctl/internal/metrics"
"github.com/superfly/flyctl/internal/task"
"golang.org/x/term"

"github.com/superfly/flyctl/iostreams"
"github.com/superfly/graphql"
Expand Down Expand Up @@ -56,6 +63,14 @@ func Run(ctx context.Context, io *iostreams.IOStreams, args ...string) int {
cmd.SetArgs(args)
cmd.SilenceErrors = true

// configure help templates and helpers
cobra.AddTemplateFuncs(template.FuncMap{
"wrapFlagUsages": wrapFlagUsages,
"wrapText": wrapText,
})
cmd.SetUsageTemplate(usageTemplate)
cmd.SetHelpTemplate(helpTemplate)

cs := io.ColorScheme()

cmd, err = cmd.ExecuteContextC(ctx)
Expand Down Expand Up @@ -132,3 +147,66 @@ func printError(io *iostreams.IOStreams, cs *iostreams.ColorScheme, cmd *cobra.C
func NewRootCommand() *cobra.Command {
return root.New()
}

func wrapFlagUsages(cmd *pflag.FlagSet) string {
width := helpWidth()

return cmd.FlagUsagesWrapped(width - 1)
}

func wrapText(s string) string {
width := helpWidth()

return strings.TrimSpace(text.Wrap(heredoc.Doc(s), width-1))
}

func helpWidth() int {
fd := int(os.Stdout.Fd())
width := 80

// Get the terminal width and dynamically set
termWidth, _, err := term.GetSize(fd)
if err == nil {
width = termWidth
}

return min(120, width)
}

// identical to the default cobra help template, but utilizes wrapText
// https://github.com/spf13/cobra/blob/fd865a44e3c48afeb6a6dbddadb8a5519173e029/command.go#L580-L582
const helpTemplate = `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces | wrapText}}
{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`

// identical to the default cobra usage template, but utilizes wrapFlagUsages
// https://github.com/spf13/cobra/blob/fd865a44e3c48afeb6a6dbddadb8a5519173e029/command.go#L539-L568
const usageTemplate = `Usage:{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
Examples:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Flags:
{{wrapFlagUsages .LocalFlags | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
Global Flags:
{{wrapFlagUsages .InheritedFlags | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}`
3 changes: 1 addition & 2 deletions internal/command/command.go
Expand Up @@ -12,7 +12,6 @@ import (
"strconv"
"time"

"github.com/MakeNowJust/heredoc/v2"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"github.com/superfly/flyctl/api"
Expand All @@ -39,7 +38,7 @@ func New(usage, short, long string, fn Runner, p ...preparers.Preparer) *cobra.C
return &cobra.Command{
Use: usage,
Short: short,
Long: heredoc.Doc(long),
Long: long,
RunE: newRunE(fn, p...),
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/command/create/create.go
Expand Up @@ -10,7 +10,7 @@ func New() (cmd *cobra.Command) {
cmd = &cobra.Command{
Use: "create",
Hidden: true,
Deprecated: "replaced by 'apps create'",
Deprecated: "use `fly apps create` instead",
}

flag.Add(cmd,
Expand Down
2 changes: 2 additions & 0 deletions internal/command/curl/curl.go
Expand Up @@ -37,6 +37,8 @@ func New() (cmd *cobra.Command) {
cmd = command.New("curl <URL>", short, long, run,
command.RequireSession,
)
cmd.Deprecated = "`fly curl` will be removed in a future release"
cmd.Hidden = true

cmd.Args = cobra.ExactArgs(1)

Expand Down
2 changes: 2 additions & 0 deletions internal/command/destroy/destroy.go
Expand Up @@ -20,6 +20,8 @@ from the Fly platform.

destroy := command.New(usage, short, long, apps.RunDestroy,
command.RequireSession)
destroy.Hidden = true
destroy.Deprecated = "use `fly apps destroy` instead"

destroy.Args = cobra.ExactArgs(1)

Expand Down
5 changes: 5 additions & 0 deletions internal/command/dnsrecords/root.go
Expand Up @@ -24,6 +24,8 @@ func New() *cobra.Command {
long = "Manage DNS records within a domain"
)
cmd := command.New("dns-records", short, long, nil)
cmd.Deprecated = "`fly dns-records` will be removed in a future release"
cmd.Hidden = true
cmd.AddCommand(
newDNSRecordsList(),
newDNSRecordsExport(),
Expand All @@ -40,6 +42,7 @@ func newDNSRecordsList() *cobra.Command {
cmd := command.New("list <domain>", short, long, runDNSRecordsList,
command.RequireSession,
)
cmd.Deprecated = "`fly dns-records list` will be removed in a future release"
flag.Add(cmd,
flag.JSONOutput(),
)
Expand All @@ -55,6 +58,7 @@ func newDNSRecordsExport() *cobra.Command {
cmd := command.New("export <domain> [filename]", short, long, runDNSRecordsExport,
command.RequireSession,
)
cmd.Deprecated = "`fly dns-records export` will be removed in a future release"
cmd.Args = cobra.RangeArgs(1, 2)
return cmd
}
Expand All @@ -67,6 +71,7 @@ func newDNSRecordsImport() *cobra.Command {
cmd := command.New("import <domain> [filename]", short, long, runDNSRecordsImport,
command.RequireSession,
)
cmd.Deprecated = "`fly dns-records import` will be removed in a future release"
cmd.Args = cobra.RangeArgs(1, 2)
return cmd
}
Expand Down
2 changes: 2 additions & 0 deletions internal/command/domains/root.go
Expand Up @@ -28,6 +28,8 @@ Notice: this feature is deprecated and no longer supported.
You can still view existing domains, but registration is no longer possible.`
)
cmd := command.New("domains", short, long, nil)
cmd.Deprecated = "`fly domains` will be removed in a future release"
cmd.Hidden = true
cmd.AddCommand(
newDomainsList(),
newDomainsShow(),
Expand Down
166 changes: 0 additions & 166 deletions internal/command/help/help.go

This file was deleted.

2 changes: 2 additions & 0 deletions internal/command/history/history.go
Expand Up @@ -30,6 +30,8 @@ events and their results.
command.RequireSession,
command.RequireAppName,
)
cmd.Deprecated = "Use `flyctl apps releases` instead"
cmd.Hidden = true

cmd.Args = cobra.NoArgs

Expand Down
2 changes: 2 additions & 0 deletions internal/command/move/move.go
Expand Up @@ -20,6 +20,8 @@ organization the current user belongs to.

move := command.New(usage, short, long, apps.RunMove,
command.RequireSession)
move.Hidden = true
move.Deprecated = "use `fly apps move` instead"

move.Args = cobra.ExactArgs(1)

Expand Down
5 changes: 4 additions & 1 deletion internal/command/open/open.go
Expand Up @@ -8,5 +8,8 @@ import (

// TODO: deprecate
func New() *cobra.Command {
return apps.NewOpen()
cmd := apps.NewOpen()
cmd.Deprecated = "use `fly apps open` instead"
cmd.Hidden = true
return cmd
}

0 comments on commit ab31e74

Please sign in to comment.