internal/verbose.go (view raw)
1package bible
2
3import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strings"
8
9 "github.com/charmbracelet/lipgloss"
10)
11
12// VerboseLogger handles verbose output with lipgloss styling
13type VerboseLogger struct {
14 enabled bool
15 styles *VerboseStyles
16}
17
18// VerboseStyles defines styles for verbose output
19type VerboseStyles struct {
20 Info lipgloss.Style
21 Warning lipgloss.Style
22 Success lipgloss.Style
23 Path lipgloss.Style
24 Label lipgloss.Style
25 Value lipgloss.Style
26}
27
28// NewVerboseLogger creates a new verbose logger
29func NewVerboseLogger(enabled bool) *VerboseLogger {
30 return &VerboseLogger{
31 enabled: enabled,
32 styles: createVerboseStyles(),
33 }
34}
35
36// createVerboseStyles creates and returns the verbose output styles
37func createVerboseStyles() *VerboseStyles {
38 return &VerboseStyles{
39 Info: lipgloss.NewStyle().Foreground(lipgloss.Color("4")),
40 Warning: lipgloss.NewStyle().Foreground(lipgloss.Color("3")),
41 Success: lipgloss.NewStyle().Foreground(lipgloss.Color("2")),
42 Path: lipgloss.NewStyle().Foreground(lipgloss.Color("12")),
43 Label: lipgloss.NewStyle().Foreground(lipgloss.Color("8")),
44 Value: lipgloss.NewStyle().Foreground(lipgloss.Color("13")),
45 }
46}
47
48// Info prints an informational message
49func (vl *VerboseLogger) Info(format string, args ...any) {
50 if !vl.enabled {
51 return
52 }
53 message := fmt.Sprintf(format, args...)
54 styled := vl.styles.Info.Render("INFO: ") + message
55 fmt.Fprintln(os.Stderr, styled)
56}
57
58// Warning prints a warning message
59func (vl *VerboseLogger) Warning(format string, args ...any) {
60 if !vl.enabled {
61 return
62 }
63 message := fmt.Sprintf(format, args...)
64 styled := vl.styles.Warning.Render("WARN: ") + message
65 fmt.Fprintln(os.Stderr, styled)
66}
67
68// Success prints a success message
69func (vl *VerboseLogger) Success(format string, args ...any) {
70 if !vl.enabled {
71 return
72 }
73 message := fmt.Sprintf(format, args...)
74 styled := vl.styles.Success.Render("SUCCESS: ") + message
75 fmt.Fprintln(os.Stderr, styled)
76}
77
78// Path prints a file path with styling
79func (vl *VerboseLogger) Path(path string) {
80 if !vl.enabled {
81 return
82 }
83 // Make path absolute for clarity
84 absPath, err := filepath.Abs(path)
85 if err != nil {
86 absPath = path
87 }
88 styled := vl.styles.Label.Render("Path: ") + vl.styles.Path.Render(absPath)
89 fmt.Fprintln(os.Stderr, styled)
90}
91
92// Config prints configuration information
93func (vl *VerboseLogger) Config(format string, args ...any) {
94 if !vl.enabled {
95 return
96 }
97 message := fmt.Sprintf(format, args...)
98 styled := vl.styles.Label.Render("Config: ") + message
99 fmt.Fprintln(os.Stderr, styled)
100}
101
102// Value prints a key-value pair
103func (vl *VerboseLogger) Value(key string, value any) {
104 if !vl.enabled {
105 return
106 }
107 styled := vl.styles.Label.Render(key+": ") + vl.styles.Value.Render(fmt.Sprintf("%v", value))
108 fmt.Fprintln(os.Stderr, styled)
109}
110
111// Section prints a section header
112func (vl *VerboseLogger) Section(title string) {
113 if !vl.enabled {
114 return
115 }
116 styled := vl.styles.Info.Render("=== " + title + " ===")
117 fmt.Fprintln(os.Stderr, styled)
118}
119
120// WithFields creates a formatted message with key-value pairs
121func (vl *VerboseLogger) WithFields(fields map[string]any, message string) {
122 if !vl.enabled {
123 return
124 }
125
126 var parts []string
127 for key, value := range fields {
128 parts = append(parts, fmt.Sprintf("%s=%v", key, value))
129 }
130
131 fieldsStr := strings.Join(parts, " ")
132 styled := vl.styles.Label.Render("Fields: ") + message
133 if fieldsStr != "" {
134 styled += " " + vl.styles.Info.Render("["+fieldsStr+"]")
135 }
136 fmt.Fprintln(os.Stderr, styled)
137}