From 2b373223e4fd41bdd32f0f0ba1d34be6f0fec5b3 Mon Sep 17 00:00:00 2001 From: "m.kindritskiy" Date: Mon, 23 Mar 2026 10:26:09 +0200 Subject: [PATCH] Centralize lets log prefix --- docs/docs/changelog.md | 1 + internal/cli/cli.go | 22 ++++++++++----------- internal/config/config/command.go | 2 +- internal/config/find.go | 3 +-- internal/logging/formatter.go | 24 +++++++++++++++++------ internal/logging/log.go | 21 ++++++++++++-------- internal/logging/log_test.go | 32 +++++++++++++++++++++++++++++-- internal/upgrade/notifier.go | 6 +++--- 8 files changed, 78 insertions(+), 33 deletions(-) diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index f3a62284..bdea6dd7 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -16,6 +16,7 @@ title: Changelog * `[Refactoring]` Move CLI startup flow from `cmd/lets/main.go` into `internal/cli/cli.go`, keeping `main.go` as a thin launcher. * `[Added]` Add `lets self doc` command to open the online documentation in a browser. * `[Added]` Show background update notifications for interactive sessions, with Homebrew-aware guidance and `LETS_CHECK_UPDATE` opt-out. +* `[Changed]` Centralize the `lets:` log prefix in the formatter and render debug messages in blue. ## [0.0.59](https://github.com/lets-cli/lets/releases/tag/v0.0.59) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 711e515a..29079f5f 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -47,19 +47,19 @@ func Main(version string, buildDate string) int { command, args, err := rootCmd.Traverse(os.Args[1:]) if err != nil { - log.Errorf("lets: traverse commands error: %s", err) + log.Errorf("traverse commands error: %s", err) return getExitCode(err, 1) } rootFlags, err := parseRootFlags(args) if err != nil { - log.Errorf("lets: parse flags error: %s", err) + log.Errorf("parse flags error: %s", err) return 1 } if rootFlags.version { if err := cmd.PrintVersionMessage(rootCmd); err != nil { - log.Errorf("lets: print version error: %s", err) + log.Errorf("print version error: %s", err) return 1 } @@ -79,7 +79,7 @@ func Main(version string, buildDate string) int { cfg, err := config.Load(rootFlags.config, configDir, version) if err != nil { if failOnConfigError(rootCmd, command, rootFlags) { - log.Errorf("lets: config error: %s", err) + log.Errorf("config error: %s", err) return 1 } } @@ -96,7 +96,7 @@ func Main(version string, buildDate string) int { } if err != nil { - log.Errorf("lets: can not create lets.yaml: %s", err) + log.Errorf("can not create lets.yaml: %s", err) return 1 } @@ -110,7 +110,7 @@ func Main(version string, buildDate string) int { } if err != nil { - log.Errorf("lets: can not self-upgrade binary: %s", err) + log.Errorf("can not self-upgrade binary: %s", err) return 1 } @@ -121,7 +121,7 @@ func Main(version string, buildDate string) int { if showUsage { if err := cmd.PrintRootHelpMessage(rootCmd); err != nil { - log.Errorf("lets: print help error: %s", err) + log.Errorf("print help error: %s", err) return 1 } @@ -137,7 +137,7 @@ func Main(version string, buildDate string) int { executor.PrintDependencyTree(depErr, os.Stderr) } - log.Errorf("lets: %s", err.Error()) + log.Errorf("%s", err.Error()) return getExitCode(err, 1) } @@ -161,7 +161,7 @@ func getContext() context.Context { go func() { sig := <-ch - log.Printf("lets: signal received: %s", sig) + log.Printf("signal received: %s", sig) cancel() }() @@ -211,7 +211,7 @@ func maybeStartUpdateCheck( return nil, func() {} } - log.Debugf("lets: start update check") + log.Debugf("start update check") notifier, err := upgrade.NewUpdateNotifier(registry.NewGithubRegistry()) if err != nil { @@ -227,7 +227,7 @@ func maybeStartUpdateCheck( upgrade.LogUpdateCheckError(err) } - log.Debugf("lets: update check done") + log.Debugf("update check done") ch <- updateCheckResult{ notifier: notifier, diff --git a/internal/config/config/command.go b/internal/config/config/command.go index da15fb59..67d27bb6 100644 --- a/internal/config/config/command.go +++ b/internal/config/config/command.go @@ -162,7 +162,7 @@ func (c *Command) GetEnv(cfg Config, builtinEnv map[string]string) (map[string]s envFileEnv, err := envFiles.Load(cfg, filenameEnv) if err != nil { - return nil, fmt.Errorf("lets: failed to resolve env_file for command '%s': %w", c.Name, err) + return nil, fmt.Errorf("failed to resolve env_file for command '%s': %w", c.Name, err) } resolvedEnv := envs.Dump() diff --git a/internal/config/find.go b/internal/config/find.go index e0fcf260..973626ff 100644 --- a/internal/config/find.go +++ b/internal/config/find.go @@ -4,7 +4,6 @@ import ( "fmt" "path/filepath" - "github.com/fatih/color" "github.com/lets-cli/lets/internal/config/path" "github.com/lets-cli/lets/internal/util" "github.com/lets-cli/lets/internal/workdir" @@ -39,7 +38,7 @@ func FindConfig(configName string, configDir string) (PathInfo, error) { return PathInfo{}, err } - log.Debugf("%s", color.BlueString("lets: found %s config file in %s directory", configName, workDir)) + log.Debugf("found %s config file in %s directory", configName, workDir) configAbsPath := "" diff --git a/internal/logging/formatter.go b/internal/logging/formatter.go index 01d44ea3..f9a1e898 100644 --- a/internal/logging/formatter.go +++ b/internal/logging/formatter.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/fatih/color" log "github.com/sirupsen/logrus" ) @@ -20,13 +21,28 @@ type Formatter struct{} // Format implements the log.Formatter interface. func (f *Formatter) Format(entry *log.Entry) ([]byte, error) { buff := &bytes.Buffer{} - buff.WriteString(writeData(entry.Data)) - buff.WriteString(entry.Message) + parts := []string{color.BlueString("lets:")} + + if data := writeData(entry.Data); data != "" { + parts = append(parts, data) + } + + parts = append(parts, formatMessage(entry)) + + buff.WriteString(strings.Join(parts, " ")) buff.WriteString("\n") return buff.Bytes(), nil } +func formatMessage(entry *log.Entry) string { + if entry.Level == log.DebugLevel { + return color.BlueString(entry.Message) + } + + return entry.Message +} + func writeData(fields log.Fields) string { var buff []string @@ -39,9 +55,5 @@ func writeData(fields log.Fields) string { } } - if len(buff) > 0 { - buff = append(buff, "") - } - return strings.Join(buff, " ") } diff --git a/internal/logging/log.go b/internal/logging/log.go index 4f17f17e..31ce660e 100644 --- a/internal/logging/log.go +++ b/internal/logging/log.go @@ -41,21 +41,20 @@ func InitLogging( // ExecLogger is used in Executor. // If adds command chain in message like this: -// lets: [foo=>bar] message. +// [foo=>bar] message. type ExecLogger struct { log *log.Logger // command name name string - // lets: [a=>b] + // [a=>b] prefix string cache map[string]*ExecLogger } func NewExecLogger() *ExecLogger { return &ExecLogger{ - log: log.StandardLogger(), - prefix: color.BlueString("lets:"), - cache: make(map[string]*ExecLogger), + log: log.StandardLogger(), + cache: make(map[string]*ExecLogger), } } @@ -71,7 +70,7 @@ func (l *ExecLogger) Child(name string) *ExecLogger { l.cache[name] = &ExecLogger{ log: l.log, name: name, - prefix: color.BlueString("lets: %s", color.GreenString("[%s]", name)), + prefix: color.GreenString("[%s]", name), cache: make(map[string]*ExecLogger), } @@ -79,11 +78,17 @@ func (l *ExecLogger) Child(name string) *ExecLogger { } func (l *ExecLogger) Info(format string, a ...any) { - format = fmt.Sprintf("%s %s", l.prefix, color.BlueString(format)) + if l.prefix != "" { + format = fmt.Sprintf("%s %s", l.prefix, format) + } + l.log.Logf(log.InfoLevel, format, a...) } func (l *ExecLogger) Debug(format string, a ...any) { - format = fmt.Sprintf("%s %s", l.prefix, color.BlueString(format)) + if l.prefix != "" { + format = fmt.Sprintf("%s %s", l.prefix, format) + } + l.log.Logf(log.DebugLevel, format, a...) } diff --git a/internal/logging/log_test.go b/internal/logging/log_test.go index 8152d6be..a7bd23cb 100644 --- a/internal/logging/log_test.go +++ b/internal/logging/log_test.go @@ -4,6 +4,7 @@ import ( "bytes" "testing" + "github.com/fatih/color" log "github.com/sirupsen/logrus" ) @@ -16,18 +17,45 @@ func TestLoggingToStd(t *testing.T) { var errBuff bytes.Buffer + prevNoColor := color.NoColor + color.NoColor = true + defer func() { + color.NoColor = prevNoColor + }() + InitLogging(&stdBuff, &errBuff) log.Info(stdOutMsg) log.Error(stdErrMsg) // coz log adds line break for output - if stdBuff.String() != stdOutMsg+"\n" { + if stdBuff.String() != "lets: "+stdOutMsg+"\n" { t.Errorf("stdBuff != stdOutMsg plz check your init stdWriter") } - if errBuff.String() != stdErrMsg+"\n" { + if errBuff.String() != "lets: "+stdErrMsg+"\n" { t.Errorf("errBuff != stdErrMsg plz check your init errWriter") } }) } + +func TestFormatterColorsDebugMessages(t *testing.T) { + prevNoColor := color.NoColor + color.NoColor = false + defer func() { + color.NoColor = prevNoColor + }() + + line, err := (&Formatter{}).Format(&log.Entry{ + Level: log.DebugLevel, + Message: "debug message", + }) + if err != nil { + t.Fatalf("Format() error = %v", err) + } + + expected := color.BlueString("lets:") + " " + color.BlueString("debug message") + "\n" + if string(line) != expected { + t.Fatalf("unexpected debug line: %q", string(line)) + } +} diff --git a/internal/upgrade/notifier.go b/internal/upgrade/notifier.go index 8472b4d1..842c59bc 100644 --- a/internal/upgrade/notifier.go +++ b/internal/upgrade/notifier.go @@ -31,7 +31,7 @@ type UpdateNotice struct { func (n *UpdateNotice) Message() string { return fmt.Sprintf( "\n%s: %s -> %s\n%s", - color.YellowString("lets: new version been released"), + color.YellowString("new version been released"), color.RedString(n.CurrentVersion), color.GreenString(n.LatestVersion), color.YellowString("Run '%s' or see https://lets-cli.org/docs/installation", n.command), @@ -93,7 +93,7 @@ func (n *UpdateNotifier) Check(ctx context.Context, currentVersion string) (*Upd now := n.now() if now.Sub(state.CheckedAt) < updateCheckInterval { - log.Debugf("lets: skip update check: next check at %s", state.CheckedAt.Add(updateCheckInterval)) + log.Debugf("skip update check: next check at %s", state.CheckedAt.Add(updateCheckInterval)) return n.noticeFromState(state, currentVersion, current, now), nil } @@ -251,5 +251,5 @@ func LogUpdateCheckError(err error) { return } - log.Debugf("lets: update notifier error: %s", err) + log.Debugf("update notifier error: %s", err) }