frame out cli tool

This commit is contained in:
2026-01-17 17:06:32 -05:00
parent 7661bff6f1
commit edc86feccd
14 changed files with 800 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
package util
const (
FLAG_CONFIG_FILE = "config"
FLAG_CONFIG_FILE_P = "f"
FLAG_PRETTY = "pretty"
FLAG_PRETTY_P = "p"
FLAG_COLOR = "color"
FLAG_COLOR_P = "c"
)

View File

@@ -0,0 +1,43 @@
package util
import (
"context"
"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/cmd/internal/config"
"github.com/rs/zerolog"
)
type CmdContextVal uint8
const (
CTX_CONFIG CmdContextVal = iota
CTX_LOGGER
)
func ContextWithConfig(baseCtx context.Context, config *config.ClientsConfig) context.Context {
return context.WithValue(baseCtx, CTX_CONFIG, config)
}
func ConfigFromContext(ctx context.Context) *config.ClientsConfig {
val := ctx.Value(CTX_CONFIG)
conf, ok := val.(*config.ClientsConfig)
if !ok {
return nil
}
return conf
}
func ContextWithLogger(baseCtx context.Context, logger *zerolog.Logger) context.Context {
return context.WithValue(baseCtx, CTX_LOGGER, logger)
}
func LoggerFromContext(ctx context.Context) *zerolog.Logger {
val := ctx.Value(CTX_LOGGER)
logger, ok := val.(*zerolog.Logger)
if !ok {
return nil
}
return logger
}

101
cmd/internal/util/output.go Normal file
View File

@@ -0,0 +1,101 @@
package util
import (
"io"
"regexp"
"github.com/fatih/color"
yaml "github.com/oasdiff/yaml3"
)
// YAMLOutput writes data as YAML to the given writer.
// If pretty is true, output is indented with 2 spaces.
// If colorize is true, YAML syntax is colorized.
func YAMLOutput(w io.Writer, data any, pretty, colorize bool) error {
encoder := yaml.NewEncoder(w)
defer encoder.Close()
if pretty {
encoder.SetIndent(2)
}
if !colorize {
return encoder.Encode(data)
}
// For colored output, encode to bytes first, then colorize
var buf []byte
bufWriter := &byteWriter{buf: &buf}
bufEncoder := yaml.NewEncoder(bufWriter)
if pretty {
bufEncoder.SetIndent(2)
}
if err := bufEncoder.Encode(data); err != nil {
return err
}
bufEncoder.Close()
colorized := colorizeYAML(string(buf))
_, err := w.Write([]byte(colorized))
return err
}
type byteWriter struct {
buf *[]byte
}
func (b *byteWriter) Write(p []byte) (n int, err error) {
*b.buf = append(*b.buf, p...)
return len(p), nil
}
// colorizeYAML applies ANSI colors to YAML output.
func colorizeYAML(input string) string {
// Color definitions - wrap to match ReplaceAllStringFunc signature
keyColor := func(s string) string { return color.New(color.FgCyan).Sprint(s) }
stringColor := func(s string) string { return color.New(color.FgGreen).Sprint(s) }
numberColor := func(s string) string { return color.New(color.FgYellow).Sprint(s) }
boolColor := func(s string) string { return color.New(color.FgMagenta).Sprint(s) }
nullColor := func(s string) string { return color.New(color.FgRed).Sprint(s) }
// Patterns for YAML elements
keyPattern := regexp.MustCompile(`(?m)^(\s*)([a-zA-Z_][a-zA-Z0-9_-]*)(:)`)
stringPattern := regexp.MustCompile(`:\s*"([^"]*)"`)
quotedStringPattern := regexp.MustCompile(`:\s*'([^']*)'`)
numberPattern := regexp.MustCompile(`:\s*(-?\d+\.?\d*)\s*$`)
boolPattern := regexp.MustCompile(`:\s*(true|false)\s*$`)
nullPattern := regexp.MustCompile(`:\s*(null|~)\s*$`)
result := input
// Apply colors in order (specific patterns first)
result = nullPattern.ReplaceAllStringFunc(result, func(s string) string {
return regexp.MustCompile(`(null|~)`).ReplaceAllStringFunc(s, nullColor)
})
result = boolPattern.ReplaceAllStringFunc(result, func(s string) string {
return regexp.MustCompile(`(true|false)`).ReplaceAllStringFunc(s, boolColor)
})
result = numberPattern.ReplaceAllStringFunc(result, func(s string) string {
return regexp.MustCompile(`(-?\d+\.?\d*)\s*$`).ReplaceAllStringFunc(s, numberColor)
})
result = stringPattern.ReplaceAllStringFunc(result, func(s string) string {
return regexp.MustCompile(`"([^"]*)"`).ReplaceAllStringFunc(s, stringColor)
})
result = quotedStringPattern.ReplaceAllStringFunc(result, func(s string) string {
return regexp.MustCompile(`'([^']*)'`).ReplaceAllStringFunc(s, stringColor)
})
result = keyPattern.ReplaceAllStringFunc(result, func(s string) string {
matches := keyPattern.FindStringSubmatch(s)
if len(matches) >= 4 {
return matches[1] + keyColor(matches[2]) + matches[3]
}
return s
})
return result
}