@@ -5,15 +5,22 @@ import (
55 "context"
66 "errors"
77 "fmt"
8+ "html/template"
9+ "os"
810 "runtime/debug"
11+ "strings"
912 "time"
1013
1114 "github.com/AlecAivazis/survey/v2/terminal"
15+ "github.com/MakeNowJust/heredoc/v2"
16+ "github.com/kr/text"
1217 "github.com/spf13/cobra"
18+ "github.com/spf13/pflag"
1319 "github.com/superfly/flyctl/internal/flag/flagnames"
1420 "github.com/superfly/flyctl/internal/flyerr"
1521 "github.com/superfly/flyctl/internal/metrics"
1622 "github.com/superfly/flyctl/internal/task"
23+ "golang.org/x/term"
1724
1825 "github.com/superfly/flyctl/iostreams"
1926 "github.com/superfly/graphql"
@@ -56,6 +63,14 @@ func Run(ctx context.Context, io *iostreams.IOStreams, args ...string) int {
5663 cmd .SetArgs (args )
5764 cmd .SilenceErrors = true
5865
66+ // configure help templates and helpers
67+ cobra .AddTemplateFuncs (template.FuncMap {
68+ "wrapFlagUsages" : wrapFlagUsages ,
69+ "wrapText" : wrapText ,
70+ })
71+ cmd .SetUsageTemplate (usageTemplate )
72+ cmd .SetHelpTemplate (helpTemplate )
73+
5974 cs := io .ColorScheme ()
6075
6176 cmd , err = cmd .ExecuteContextC (ctx )
@@ -132,3 +147,66 @@ func printError(io *iostreams.IOStreams, cs *iostreams.ColorScheme, cmd *cobra.C
132147func NewRootCommand () * cobra.Command {
133148 return root .New ()
134149}
150+
151+ func wrapFlagUsages (cmd * pflag.FlagSet ) string {
152+ width := helpWidth ()
153+
154+ return cmd .FlagUsagesWrapped (width - 1 )
155+ }
156+
157+ func wrapText (s string ) string {
158+ width := helpWidth ()
159+
160+ return strings .TrimSpace (text .Wrap (heredoc .Doc (s ), width - 1 ))
161+ }
162+
163+ func helpWidth () int {
164+ fd := int (os .Stdout .Fd ())
165+ width := 80
166+
167+ // Get the terminal width and dynamically set
168+ termWidth , _ , err := term .GetSize (fd )
169+ if err == nil {
170+ width = termWidth
171+ }
172+
173+ return min (120 , width )
174+ }
175+
176+ // identical to the default cobra help template, but utilizes wrapText
177+ // https://github.com/spf13/cobra/blob/fd865a44e3c48afeb6a6dbddadb8a5519173e029/command.go#L580-L582
178+ const helpTemplate = `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces | wrapText}}
179+
180+ {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
181+
182+ // identical to the default cobra usage template, but utilizes wrapFlagUsages
183+ // https://github.com/spf13/cobra/blob/fd865a44e3c48afeb6a6dbddadb8a5519173e029/command.go#L539-L568
184+ const usageTemplate = `Usage:{{if .Runnable}}
185+ {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
186+ {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
187+
188+ Aliases:
189+ {{.NameAndAliases}}{{end}}{{if .HasExample}}
190+
191+ Examples:
192+ {{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
193+
194+ Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
195+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
196+
197+ {{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
198+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
199+
200+ Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
201+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
202+
203+ Flags:
204+ {{wrapFlagUsages .LocalFlags | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
205+
206+ Global Flags:
207+ {{wrapFlagUsages .InheritedFlags | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
208+
209+ Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
210+ {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
211+
212+ Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}`
0 commit comments