Skip to content

Commit

Permalink
Merge branch 'main' into imports-for-overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
aknysh authored Dec 8, 2024
2 parents aed7ff6 + bd20472 commit 5782626
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 13 deletions.
17 changes: 11 additions & 6 deletions internal/tui/templates/help_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func NewHelpFlagPrinter(out io.Writer, wrapLimit uint, flags *pflag.FlagSet) *He
if flags == nil {
panic("flag set cannot be nil")
}

if wrapLimit < minWidth {
wrapLimit = minWidth
}
Expand Down Expand Up @@ -89,6 +90,15 @@ func (p *HelpFlagPrinter) PrintHelpFlag(flag *pflag.Flag) {
}
}

availWidth := int(p.wrapLimit) - p.maxFlagLen - 4
if availWidth < minDescWidth {
if _, err := fmt.Fprintf(p.out, "%s\n", flagName); err != nil {
return
}
flagName = strings.Repeat(" ", p.maxFlagLen)
availWidth = int(p.wrapLimit) - 4
}

flagSection := fmt.Sprintf("%-*s", p.maxFlagLen, flagName)
descIndent := p.maxFlagLen + 4

Expand All @@ -97,12 +107,7 @@ func (p *HelpFlagPrinter) PrintHelpFlag(flag *pflag.Flag) {
description = fmt.Sprintf("%s (default %q)", description, flag.DefValue)
}

descWidth := int(p.wrapLimit) - descIndent
if descWidth < minDescWidth {
descWidth = minDescWidth
}

wrapped := wordwrap.WrapString(description, uint(descWidth))
wrapped := wordwrap.WrapString(description, uint(availWidth))
lines := strings.Split(wrapped, "\n")

if _, err := fmt.Fprintf(p.out, "%-*s%s\n", descIndent, flagSection, lines[0]); err != nil {
Expand Down
71 changes: 65 additions & 6 deletions internal/tui/templates/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,61 @@ package templates

import (
"fmt"
"os"
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/term"
)

// Templater handles the generation and management of command usage templates.
type Templater struct {
UsageTemplate string
}

// commandStyle defines the styles for command formatting
var (
commandNameStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("2")). // Green color for command name
Bold(true)

commandDescStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("7")) // White color for description
)

// formatCommand returns a styled string for a command and its description
func formatCommand(name string, desc string, padding int) string {
paddedName := fmt.Sprintf("%-*s", padding, name)
styledName := commandNameStyle.Render(paddedName)
styledDesc := commandDescStyle.Render(desc)
return fmt.Sprintf(" %s %s", styledName, styledDesc)
}

// formatCommands formats a slice of cobra commands with proper styling
func formatCommands(cmds []*cobra.Command) string {
var maxLen int
availableCmds := make([]*cobra.Command, 0)

// First pass: collect available commands and find max length
for _, cmd := range cmds {
if cmd.IsAvailableCommand() || cmd.Name() == "help" {
availableCmds = append(availableCmds, cmd)
if len(cmd.Name()) > maxLen {
maxLen = len(cmd.Name())
}
}
}

var lines []string
for _, cmd := range availableCmds {
lines = append(lines, formatCommand(cmd.Name(), cmd.Short, maxLen))
}

return strings.Join(lines, "\n")
}

// SetCustomUsageFunc configures a custom usage template for the provided cobra command.
// It returns an error if the command is nil.
func SetCustomUsageFunc(cmd *cobra.Command) error {
Expand All @@ -24,9 +68,26 @@ func SetCustomUsageFunc(cmd *cobra.Command) error {
}

cmd.SetUsageTemplate(t.UsageTemplate)
cobra.AddTemplateFunc("formatCommands", formatCommands)
return nil
}

// getTerminalWidth returns the width of the terminal, defaulting to 80 if it cannot be determined
func getTerminalWidth() int {
defaultWidth := 80
screenWidth := defaultWidth

// Detect terminal width and use it by default if available
if term.IsTerminal(int(os.Stdout.Fd())) {
termWidth, _, err := term.GetSize(int(os.Stdout.Fd()))
if err == nil && termWidth > 0 {
screenWidth = termWidth - 2
}
}

return screenWidth
}

// MainUsageTemplate returns the usage template for the root command and wrap cobra flag usages to the terminal width
func MainUsageTemplate() string {
return `Usage:{{if .Runnable}}
Expand All @@ -39,8 +100,8 @@ Aliases:
Examples:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Available Commands:
{{formatCommands .Commands}}{{end}}{{if .HasAvailableLocalFlags}}
Flags:
{{wrappedFlagUsages .LocalFlags | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
Expand All @@ -55,13 +116,11 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e
`
}

// Default terminal width if actual width cannot be determined
const maxWidth = 80

// WrappedFlagUsages formats the flag usage string to fit within the terminal width
func WrappedFlagUsages(f *pflag.FlagSet) string {
var builder strings.Builder
printer := NewHelpFlagPrinter(&builder, maxWidth, f)
width := getTerminalWidth()
printer := NewHelpFlagPrinter(&builder, uint(width), f)

printer.maxFlagLen = calculateMaxFlagLength(f)

Expand Down
2 changes: 1 addition & 1 deletion website/src/components/Screengrabs/atmos--help.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<span style="text-decoration:underline;font-weight:bold;filter: contrast(70%) brightness(190%);color:teal;">Flags:</span>

<span style="font-weight:bold;color:gray;">-h,</span> <span style="font-weight:bold;color:gray;">--help</span> help for atmos
<span style="font-weight:bold;color:gray;">-h,</span> <span style="font-weight:bold;color:gray;">--help</span> Help for atmos
<span style="font-weight:bold;color:gray;">--logs-file</span> string The file to write Atmos logs to. Logs can be written to any file or any standard file descriptor, including '/dev/stdout', '/dev/stderr' and '/dev/null' (default &quot;/dev/stdout&quot;)
<span style="font-weight:bold;color:gray;">--logs-level</span> string Logs level. Supported log levels are Trace, Debug, Info, Warning, Off. If the log level is set to Off, Atmos will not log any messages (default &quot;Info&quot;)
<span style="font-weight:bold;color:gray;">--redirect-stderr</span> string File descriptor to redirect 'stderr' to. Errors can be redirected to any file or any standard file descriptor (including '/dev/null'): atmos &lt;command&gt; --redirect-stderr /dev/stdout
Expand Down

0 comments on commit 5782626

Please sign in to comment.