github.com/connorvict/air@v0.0.0-20231005162537-279bf07db0d5/runner/logger.go (about)

     1  package runner
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/fatih/color"
    10  )
    11  
    12  var (
    13  	rawColor = "raw"
    14  	// TODO: support more colors
    15  	colorMap = map[string]color.Attribute{
    16  		"red":     color.FgRed,
    17  		"green":   color.FgGreen,
    18  		"yellow":  color.FgYellow,
    19  		"blue":    color.FgBlue,
    20  		"magenta": color.FgMagenta,
    21  		"cyan":    color.FgCyan,
    22  		"white":   color.FgWhite,
    23  	}
    24  )
    25  
    26  type logFunc func(string, ...interface{})
    27  
    28  type logger struct {
    29  	config  *Config
    30  	colors  map[string]string
    31  	loggers map[string]logFunc
    32  }
    33  
    34  func newLogger(cfg *Config) *logger {
    35  	if cfg == nil {
    36  		return nil
    37  	}
    38  
    39  	colors := cfg.colorInfo()
    40  	loggers := make(map[string]logFunc, len(colors))
    41  	for name, nameColor := range colors {
    42  		loggers[name] = newLogFunc(nameColor, cfg.Log)
    43  	}
    44  	loggers["default"] = defaultLogger()
    45  	return &logger{
    46  		config:  cfg,
    47  		colors:  colors,
    48  		loggers: loggers,
    49  	}
    50  }
    51  
    52  func newLogFunc(colorname string, cfg cfgLog) logFunc {
    53  	return func(msg string, v ...interface{}) {
    54  		// There are some escape sequences to format color in terminal, so cannot
    55  		// just trim new line from right.
    56  		msg = strings.ReplaceAll(msg, "\n", "")
    57  		msg = strings.TrimSpace(msg)
    58  		if len(msg) == 0 {
    59  			return
    60  		}
    61  		// TODO: filter msg by regex
    62  		msg = msg + "\n"
    63  		if cfg.AddTime {
    64  			t := time.Now().Format("15:04:05")
    65  			msg = fmt.Sprintf("[%s] %s", t, msg)
    66  		}
    67  		if colorname == rawColor {
    68  			fmt.Fprintf(os.Stdout, msg, v...)
    69  		} else {
    70  			color.New(getColor(colorname)).Fprintf(color.Output, msg, v...)
    71  		}
    72  	}
    73  }
    74  
    75  func getColor(name string) color.Attribute {
    76  	if v, ok := colorMap[name]; ok {
    77  		return v
    78  	}
    79  	return color.FgWhite
    80  }
    81  
    82  func (l *logger) main() logFunc {
    83  	return l.getLogger("main")
    84  }
    85  
    86  func (l *logger) build() logFunc {
    87  	return l.getLogger("build")
    88  }
    89  
    90  func (l *logger) runner() logFunc {
    91  	return l.getLogger("runner")
    92  }
    93  
    94  func (l *logger) watcher() logFunc {
    95  	return l.getLogger("watcher")
    96  }
    97  
    98  func rawLogger() logFunc {
    99  	return newLogFunc("raw", defaultConfig().Log)
   100  }
   101  
   102  func defaultLogger() logFunc {
   103  	return newLogFunc("white", defaultConfig().Log)
   104  }
   105  
   106  func (l *logger) getLogger(name string) logFunc {
   107  	v, ok := l.loggers[name]
   108  	if !ok {
   109  		return rawLogger()
   110  	}
   111  	return v
   112  }