cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
29
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 94 lines 2.2 kB view raw
1// package shared contains constants used across the codebase 2package shared 3 4import ( 5 "errors" 6 "fmt" 7 "io" 8 "os" 9 "path/filepath" 10 "time" 11 12 "github.com/charmbracelet/log" 13) 14 15var ( 16 ErrConfig error = fmt.Errorf("configuration error") 17) 18 19func ConfigError(m string, err error) error { 20 return errors.Join(ErrConfig, fmt.Errorf("%s: %w", m, err)) 21} 22 23func IsConfigError(err error) bool { 24 return errors.Is(err, ErrConfig) 25} 26 27// CompoundWriter writes every payload to two sinks: 28// 1. a primary sink (typically [os.Stdout] or [os.Stderr]) 29// 2. a secondary sink (typically [*os.File]) 30// 31// It satisfies io.Writer. 32type CompoundWriter struct { 33 primary io.Writer 34 secondary io.Writer 35} 36 37// New creates a new [CompoundWriter] 38func New(primary io.Writer, secondary io.Writer) *CompoundWriter { 39 return &CompoundWriter{ 40 primary: primary, 41 secondary: secondary, 42 } 43} 44 45func LogWithStdErr(w io.WriteCloser) *CompoundWriter { 46 return New(os.Stderr, w) 47} 48 49func LogWithStdOut(w io.WriteCloser) *CompoundWriter { 50 return New(os.Stdout, w) 51} 52 53// Write writes p to both instances of [io.Writer] 54func (cw *CompoundWriter) Write(p []byte) (int, error) { 55 var err error 56 var n1, n2 int 57 58 if n1, err = cw.primary.Write(p); err != nil { 59 return n1, err 60 } 61 if n2, err = cw.secondary.Write(p); err != nil { 62 return n2, err 63 } 64 return len(p), nil 65} 66 67func FallbackLogger() *log.Logger { 68 return log.NewWithOptions(os.Stderr, log.Options{ 69 Prefix: "[DEBUG]", 70 ReportTimestamp: true, 71 ReportCaller: true, 72 TimeFormat: time.Kitchen, 73 Level: log.DebugLevel, 74 }) 75} 76 77// NewDebugLoggerWithFile creates a new debug logger that writes to both stderr and a log file 78func NewDebugLoggerWithFile(configDir string) *log.Logger { 79 logger := FallbackLogger() 80 logsDir := filepath.Join(configDir, "logs") 81 if err := os.MkdirAll(logsDir, 0755); err != nil { 82 return logger 83 } 84 85 logFile := filepath.Join(logsDir, fmt.Sprintf("publication_%s.log", time.Now().Format("2006-01-02"))) 86 file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) 87 if err != nil { 88 return logger 89 } 90 91 w := LogWithStdErr(file) 92 logger.SetOutput(w) 93 return logger 94}