vendor tsgo

This commit is contained in:
2026-07-09 16:50:43 -04:00
parent c06ea2e5a4
commit 98978e4930
5804 changed files with 1556156 additions and 101 deletions

View File

@@ -0,0 +1,34 @@
package logging
import (
"fmt"
"strings"
"time"
)
type LogCollector interface {
fmt.Stringer
Logger
}
type logCollector struct {
logger
builder *strings.Builder
}
func (lc *logCollector) String() string {
return lc.builder.String()
}
func NewTestLogger() LogCollector {
var builder strings.Builder
return &logCollector{
logger: logger{
writer: &builder,
prefix: func() string {
return formatTime(time.Unix(1349085672, 0))
},
},
builder: &builder,
}
}

View File

@@ -0,0 +1,135 @@
package logging
import (
"fmt"
"io"
"sync"
"time"
)
type Logger interface {
// Error logs an error message.
Error(msg ...any)
// Errorf logs a formatted error message.
Errorf(format string, args ...any)
// Warn logs a warning message.
Warn(msg ...any)
// Warnf logs a formatted warning message.
Warnf(format string, args ...any)
// Info logs an info message.
Info(msg ...any)
// Infof logs a formatted info message.
Infof(format string, args ...any)
// Log prints a line to the output writer with a header.
Log(msg ...any)
// Logf prints a formatted line to the output writer with a header.
Logf(format string, args ...any)
// Verbose returns the logger instance if verbose logging is enabled, and otherwise returns nil.
// A nil logger created with `logging.NewLogger` is safe to call methods on.
Verbose() Logger
// IsVerbose returns true if verbose logging is enabled, and false otherwise.
IsVerbose() bool
// SetVerbose sets the verbose logging flag.
SetVerbose(verbose bool)
}
var _ Logger = (*logger)(nil)
type logger struct {
mu sync.Mutex
verbose bool
writer io.Writer
prefix func() string
}
func (l *logger) Log(msg ...any) {
if l == nil {
return
}
l.mu.Lock()
defer l.mu.Unlock()
fmt.Fprintln(l.writer, l.prefix(), fmt.Sprint(msg...))
}
func (l *logger) Logf(format string, args ...any) {
if l == nil {
return
}
l.mu.Lock()
defer l.mu.Unlock()
fmt.Fprintf(l.writer, "%s %s\n", l.prefix(), fmt.Sprintf(format, args...))
}
func (l *logger) Verbose() Logger {
if l == nil {
return nil
}
l.mu.Lock()
defer l.mu.Unlock()
if !l.verbose {
return nil
}
return l
}
func (l *logger) IsVerbose() bool {
if l == nil {
return false
}
l.mu.Lock()
defer l.mu.Unlock()
return l.verbose
}
func (l *logger) SetVerbose(verbose bool) {
if l == nil {
return
}
l.mu.Lock()
defer l.mu.Unlock()
l.verbose = verbose
}
func (l *logger) Error(msg ...any) {
l.Log(msg...)
}
func (l *logger) Errorf(format string, args ...any) {
l.Logf(format, args...)
}
func (l *logger) Warn(msg ...any) {
l.Log(msg...)
}
func (l *logger) Warnf(format string, args ...any) {
l.Logf(format, args...)
}
func (l *logger) Info(msg ...any) {
l.Log(msg...)
}
func (l *logger) Infof(format string, args ...any) {
l.Logf(format, args...)
}
func NewLogger(output io.Writer) Logger {
return &logger{
writer: output,
prefix: func() string {
return formatTime(time.Now())
},
}
}
// NewNopLogger returns a no-op Logger that discards all log messages.
// It is safe to call any method on the returned Logger.
func NewNopLogger() Logger {
return (*logger)(nil)
}
func formatTime(t time.Time) string {
return fmt.Sprintf("[%s]", t.Format("15:04:05.000"))
}

View File

@@ -0,0 +1,163 @@
package logging
import (
"fmt"
"strings"
"sync"
"sync/atomic"
"time"
)
var seq atomic.Uint64
type logEntry struct {
seq uint64
time time.Time
message string
child *LogTree
}
func newLogEntry(child *LogTree, message string) *logEntry {
return &logEntry{
seq: seq.Add(1),
time: time.Now(),
message: message,
child: child,
}
}
var _ LogCollector = (*LogTree)(nil)
type LogTree struct {
name string
mu sync.Mutex
logs []*logEntry
root *LogTree
level int
verbose bool
// Only set on root
count atomic.Int32
stringLength atomic.Int32
}
func NewLogTree(name string) *LogTree {
lc := &LogTree{
name: name,
}
lc.root = lc
return lc
}
func (c *LogTree) add(log *logEntry) {
// indent + header + message + newline
c.root.stringLength.Add(int32(c.level + 15 + len(log.message) + 1))
c.root.count.Add(1)
c.mu.Lock()
defer c.mu.Unlock()
c.logs = append(c.logs, log)
}
func (c *LogTree) Log(message ...any) {
if c == nil {
return
}
log := newLogEntry(nil, fmt.Sprint(message...))
c.add(log)
}
func (c *LogTree) Logf(format string, args ...any) {
if c == nil {
return
}
log := newLogEntry(nil, fmt.Sprintf(format, args...))
c.add(log)
}
func (c *LogTree) IsVerbose() bool {
return c.verbose
}
func (c *LogTree) SetVerbose(verbose bool) {
if c == nil {
return
}
c.verbose = verbose
}
func (c *LogTree) Verbose() Logger {
if c == nil || !c.verbose {
return nil
}
return c
}
func (c *LogTree) Error(msg ...any) {
c.Log(msg...)
}
func (c *LogTree) Errorf(format string, args ...any) {
c.Logf(format, args...)
}
func (c *LogTree) Warn(msg ...any) {
c.Log(msg...)
}
func (c *LogTree) Warnf(format string, args ...any) {
c.Logf(format, args...)
}
func (c *LogTree) Info(msg ...any) {
c.Log(msg...)
}
func (c *LogTree) Infof(format string, args ...any) {
c.Logf(format, args...)
}
func (c *LogTree) Embed(logs *LogTree) {
if c == nil {
return
}
count := logs.count.Load()
c.root.stringLength.Add(logs.stringLength.Load() + count*int32(c.level))
c.root.count.Add(count)
log := newLogEntry(logs, logs.name)
c.add(log)
}
func (c *LogTree) Fork(message string) *LogTree {
if c == nil {
return nil
}
child := &LogTree{level: c.level + 1, root: c.root, verbose: c.verbose}
log := newLogEntry(child, message)
c.add(log)
return child
}
func (c *LogTree) String() string {
if c.root != c {
panic("can only call String on root LogTree")
}
var builder strings.Builder
header := fmt.Sprintf("======== %s ========\n", c.name)
builder.Grow(int(c.stringLength.Load()) + len(header))
builder.WriteString(header)
c.writeLogsRecursive(&builder, "")
return builder.String()
}
func (c *LogTree) writeLogsRecursive(builder *strings.Builder, indent string) {
for _, log := range c.logs {
builder.WriteString(indent)
builder.WriteString(formatTime(log.time))
builder.WriteString(" ")
builder.WriteString(log.message)
builder.WriteString("\n")
if log.child != nil {
log.child.writeLogsRecursive(builder, indent+"\t")
}
}
}

View File

@@ -0,0 +1,19 @@
package logging
import (
"testing"
)
// Verify LogTree implements the expected interface
type testLogger interface {
Log(msg ...any)
}
func TestLogTreeImplementsLogger(t *testing.T) {
t.Parallel()
var _ testLogger = &LogTree{}
}
func TestLogTree(t *testing.T) {
t.Parallel()
}