You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
obsidian-pipeline/gloss/cobra.go

125 lines
3.2 KiB
Go

package gloss
import (
"bytes"
"fmt"
"io"
"reflect"
"strconv"
"strings"
"text/template"
"unicode"
"github.com/charmbracelet/lipgloss"
"github.com/spf13/cobra"
)
func CharmUsage(c *cobra.Command) error {
var b bytes.Buffer
err := tmpl(&b, c.UsageTemplate(), c)
if err != nil {
c.PrintErrln(err)
return err
}
pretty(c.ErrOrStderr(), b.String())
return nil
}
func CharmHelp(c *cobra.Command, a []string) {
var b bytes.Buffer
// The help should be sent to stdout
// See https://github.com/spf13/cobra/issues/1002
err := tmpl(&b, c.HelpTemplate(), c)
if err != nil {
c.PrintErrln(err)
}
pretty(c.ErrOrStderr(), b.String())
}
var BaseStyle = lipgloss.NewStyle().Bold(true).Width(80)
func pretty(w io.Writer, s string) {
fmt.Fprintf(w, "%s\n", BaseStyle.Render(s))
}
var templateFuncs = template.FuncMap{
"trim": strings.TrimSpace,
"trimRightSpace": trimRightSpace,
"trimTrailingWhitespaces": trimRightSpace,
"appendIfNotPresent": appendIfNotPresent,
"rpad": rpad,
"gt": Gt,
"eq": Eq,
}
func Gt(a interface{}, b interface{}) bool {
var left, right int64
av := reflect.ValueOf(a)
switch av.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
left = int64(av.Len())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
left = av.Int()
case reflect.String:
left, _ = strconv.ParseInt(av.String(), 10, 64)
}
bv := reflect.ValueOf(b)
switch bv.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
right = int64(bv.Len())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
right = bv.Int()
case reflect.String:
right, _ = strconv.ParseInt(bv.String(), 10, 64)
}
return left > right
}
// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
func Eq(a interface{}, b interface{}) bool {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
switch av.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
panic("Eq called on unsupported type")
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return av.Int() == bv.Int()
case reflect.String:
return av.String() == bv.String()
}
return false
}
func trimRightSpace(s string) string {
return strings.TrimRightFunc(s, unicode.IsSpace)
}
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
func appendIfNotPresent(s, stringToAppend string) string {
if strings.Contains(s, stringToAppend) {
return s
}
return s + " " + stringToAppend
}
// rpad adds padding to the right of a string.
func rpad(s string, padding int) string {
formattedString := fmt.Sprintf("%%-%ds", padding)
return fmt.Sprintf(formattedString, s)
}
// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) error {
t := template.New("top")
t.Funcs(templateFuncs)
template.Must(t.Parse(text))
return t.Execute(w, data)
}