From dc4d206b297bf466646063131102268bfa654e10 Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Mon, 7 Apr 2025 15:55:21 +0200 Subject: [PATCH 1/2] feat: allow multiple checkers --- Makefile | 3 +- pkg/log/pterm.go | 3 +- pkg/prompt/check/checker.go | 2 +- pkg/prompt/check/defaultcheck.go | 56 +++++++++++---------- pkg/prompt/prompt.go | 2 +- pkg/pterm/ptermwriter.go | 20 ++++++++ pkg/pterm/sloghandler.go | 85 ++++++++++++++++++++++++++++++++ pkg/shell/ptermwriter.go | 20 -------- 8 files changed, 142 insertions(+), 49 deletions(-) create mode 100644 pkg/pterm/ptermwriter.go create mode 100644 pkg/pterm/sloghandler.go delete mode 100644 pkg/shell/ptermwriter.go diff --git a/Makefile b/Makefile index 13ba42f..5139087 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,8 @@ outdated: .PHONY: test ## Run tests test: - @go test -coverprofile=coverage.out -race -json ./... | gotestfmt + @GO_TEST_TAGS=-skip go test -coverprofile=coverage.out -race ./... + #@GO_TEST_TAGS=-skip go test -coverprofile=coverage.out -race -json ./... | gotestfmt .PHONY: test.demo ## Run tests diff --git a/pkg/log/pterm.go b/pkg/log/pterm.go index 8f3df84..66588e8 100644 --- a/pkg/log/pterm.go +++ b/pkg/log/pterm.go @@ -4,6 +4,7 @@ import ( "fmt" "log/slog" + ptermx "github.com/foomo/posh/pkg/pterm" "github.com/pterm/pterm" ) @@ -167,7 +168,7 @@ func (l *PTerm) Must(err error) { } func (l *PTerm) SlogHandler() slog.Handler { - return pterm.NewSlogHandler(&pterm.DefaultLogger) + return ptermx.NewSlogHandler() } // ------------------------------------------------------------------------------------------------ diff --git a/pkg/prompt/check/checker.go b/pkg/prompt/check/checker.go index 6aad599..94a3773 100644 --- a/pkg/prompt/check/checker.go +++ b/pkg/prompt/check/checker.go @@ -6,4 +6,4 @@ import ( "github.com/foomo/posh/pkg/log" ) -type Checker func(ctx context.Context, l log.Logger) Info +type Checker func(ctx context.Context, l log.Logger) []Info diff --git a/pkg/prompt/check/defaultcheck.go b/pkg/prompt/check/defaultcheck.go index d7201e0..e2d2627 100644 --- a/pkg/prompt/check/defaultcheck.go +++ b/pkg/prompt/check/defaultcheck.go @@ -2,6 +2,9 @@ package check import ( "context" + "slices" + "strings" + "sync" "time" "github.com/foomo/posh/pkg/log" @@ -10,29 +13,32 @@ import ( ) func DefaultCheck(ctx context.Context, l log.Logger, checkers []Checker) error { + var mu sync.Mutex var wg errgroup.Group - data := make(pterm.TableData, len(checkers)) - wg.SetLimit(3) - for i, checker := range checkers { - i := i - checker := checker + var data pterm.TableData + // wg.SetLimit(3) + for _, checker := range checkers { wg.Go(func() error { cancelCtx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - info := checker(cancelCtx, l) - var color pterm.Color - switch info.Status { - case StatusFailure: - color = pterm.FgRed - case StatusSuccess: - color = pterm.FgGreen - default: - color = pterm.FgGray - } - data[i] = []string{ - info.Status.String(), - info.Name, - color.Sprint(info.Note), + infos := checker(cancelCtx, l) + mu.Lock() + defer mu.Unlock() + for _, info := range infos { + var color pterm.Color + switch info.Status { + case StatusFailure: + color = pterm.FgRed + case StatusSuccess: + color = pterm.FgGreen + default: + color = pterm.FgGray + } + data = append(data, []string{ + info.Status.String(), + info.Name, + color.Sprint(info.Note), + }) } return nil }) @@ -40,10 +46,10 @@ func DefaultCheck(ctx context.Context, l log.Logger, checkers []Checker) error { if err := wg.Wait(); err != nil { return err } - table := pterm.DefaultTable - if err := table.WithData(data).Render(); err != nil { - return err - } - pterm.Println() - return nil + + slices.SortFunc(data, func(a, b []string) int { + return strings.Compare(a[1], b[1]) + }) + + return pterm.DefaultTable.WithData(data).Render() } diff --git a/pkg/prompt/prompt.go b/pkg/prompt/prompt.go index 41a555f..07315b5 100644 --- a/pkg/prompt/prompt.go +++ b/pkg/prompt/prompt.go @@ -27,7 +27,7 @@ type ( prefix string prefixGit bool check check.Check - checkers []check.Checker + checkers check.Checkers filter goprompt.Filter readline *readline.Readline history history.History diff --git a/pkg/pterm/ptermwriter.go b/pkg/pterm/ptermwriter.go new file mode 100644 index 0000000..bb402a9 --- /dev/null +++ b/pkg/pterm/ptermwriter.go @@ -0,0 +1,20 @@ +package pterm + +import ( + "github.com/pterm/pterm" +) + +type Writer struct { + printer pterm.PrefixPrinter +} + +func NewWriter(printer pterm.PrefixPrinter) *Writer { + return &Writer{ + printer: printer, + } +} + +func (p *Writer) Write(b []byte) (int, error) { + p.printer.Println(string(b)) + return len(b), nil +} diff --git a/pkg/pterm/sloghandler.go b/pkg/pterm/sloghandler.go new file mode 100644 index 0000000..e5b83b1 --- /dev/null +++ b/pkg/pterm/sloghandler.go @@ -0,0 +1,85 @@ +package pterm + +import ( + "context" + "fmt" + "log/slog" + + "github.com/pterm/pterm" +) + +type SlogHandler struct { + attrs []slog.Attr +} + +// NewSlogHandler returns a new logging handler that can be intrgrated with log/slog. +func NewSlogHandler() *SlogHandler { + return &SlogHandler{} +} + +// Enabled returns true if the given level is enabled. +func (s *SlogHandler) Enabled(ctx context.Context, level slog.Level) bool { + switch level { + case slog.LevelDebug: + return pterm.PrintDebugMessages + default: + return true + } +} + +// Handle handles the given record. +func (s *SlogHandler) Handle(ctx context.Context, record slog.Record) error { + level := record.Level + message := record.Message + + // Convert slog Attrs to a map. + keyValsMap := make(map[string]any) + + record.Attrs(func(attr slog.Attr) bool { + keyValsMap[attr.Key] = attr.Value + return true + }) + + for _, attr := range s.attrs { + keyValsMap[attr.Key] = attr.Value + } + + args := pterm.DefaultLogger.ArgsFromMap(keyValsMap) + + // Wrapping args inside another slice to match [][]LoggerArgument + argsWrapped := [][]pterm.LoggerArgument{args} + + for _, arg := range argsWrapped { + for _, attr := range arg { + message += " " + attr.Key + ": " + fmt.Sprintf("%v", attr.Value) + } + } + + switch level { + case slog.LevelDebug: + pterm.Debug.Println(message) + case slog.LevelInfo: + pterm.Info.Println(message) + case slog.LevelWarn: + pterm.Warning.Println(message) + case slog.LevelError: + pterm.Error.Println(message) + default: + pterm.Info.Println(message) + } + + return nil +} + +// WithAttrs returns a new handler with the given attributes. +func (s *SlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + newS := *s + newS.attrs = attrs + return &newS +} + +// WithGroup is not yet supported. +func (s *SlogHandler) WithGroup(name string) slog.Handler { + // Grouping is not yet supported by pterm. + return s +} diff --git a/pkg/shell/ptermwriter.go b/pkg/shell/ptermwriter.go deleted file mode 100644 index 26b1b99..0000000 --- a/pkg/shell/ptermwriter.go +++ /dev/null @@ -1,20 +0,0 @@ -package shell - -import ( - "github.com/pterm/pterm" -) - -type PTermWriter struct { - printer pterm.PrefixPrinter -} - -func NewPTermWriter(printer pterm.PrefixPrinter) *PTermWriter { - return &PTermWriter{ - printer: printer, - } -} - -func (p *PTermWriter) Write(b []byte) (int, error) { - p.printer.Println(string(b)) - return len(b), nil -} From 21acd3af35a3d31f6a74d2b2d4fa6cb71e3e0ef9 Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Mon, 7 Apr 2025 16:03:14 +0200 Subject: [PATCH 2/2] fix: template --- embed/scaffold/init/$.posh/go.mod.gotext | 2 +- embed/scaffold/init/$.posh/internal/plugin.go.gotext | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/embed/scaffold/init/$.posh/go.mod.gotext b/embed/scaffold/init/$.posh/go.mod.gotext index ccb7d02..1cd8068 100644 --- a/embed/scaffold/init/$.posh/go.mod.gotext +++ b/embed/scaffold/init/$.posh/go.mod.gotext @@ -1,6 +1,6 @@ module {{ .module }}/posh -go 1.23.0 +go 1.24 replace ( github.com/c-bata/go-prompt v0.2.6 => github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5 diff --git a/embed/scaffold/init/$.posh/internal/plugin.go.gotext b/embed/scaffold/init/$.posh/internal/plugin.go.gotext index 6592277..b958cb5 100644 --- a/embed/scaffold/init/$.posh/internal/plugin.go.gotext +++ b/embed/scaffold/init/$.posh/internal/plugin.go.gotext @@ -110,12 +110,12 @@ func (p *Plugin) Prompt(ctx context.Context, cfg config.Prompt) error { prompt.WithAliases(cfg.Aliases), prompt.WithCommands(p.commands), prompt.WithCheckers( - func(ctx context.Context, l log.Logger) check.Info { - return check.Info{ + func(ctx context.Context, l log.Logger) []check.Info { + return []check.Info{check.Info{ Name: "example", Note: "all good", Status: check.StatusSuccess, - } + }} }, ), prompt.WithFileHistory(