Logging & Godot Downloader

This commit is contained in:
2023-07-23 02:30:27 -04:00
parent bc33b4805a
commit 649d0d87f9
11 changed files with 728 additions and 0 deletions

136
logging/github_actions.go Normal file
View File

@ -0,0 +1,136 @@
package logging
import (
"fmt"
"log"
"os"
)
// GitHubActionsLogger is a logger that logs to GitHub Actions.
type GitHubActionsLogger struct {
info *log.Logger
warn *log.Logger
err *log.Logger
debug *log.Logger
}
// NewGitHubActionsLogger creates a new GitHubActionsLogger.
func NewGitHubActionsLogger(debug bool) Logger {
var debugLogger *log.Logger
if debug {
debugLogger = log.New(os.Stdout, "::debug::", 0)
}
return &GitHubActionsLogger{
info: log.New(os.Stdout, "", 0),
warn: log.New(os.Stdout, "::warning::", 0),
err: log.New(os.Stderr, "::error::", 0),
debug: debugLogger,
}
}
// Infof logs an info message.
func (l *GitHubActionsLogger) Infof(format string, args ...interface{}) {
l.info.Printf(format, args...)
}
// Warnf logs a warning message.
func (l *GitHubActionsLogger) Warnf(format string, args ...interface{}) {
l.warn.Printf(format, args...)
}
// Errorf logs an error message.
func (l *GitHubActionsLogger) Errorf(format string, args ...interface{}) {
l.err.Printf(format, args...)
}
// Debugf logs a debug message if debug logging is enabled.
func (l *GitHubActionsLogger) Debugf(format string, args ...interface{}) {
if l.debug != nil {
l.debug.Printf(format, args...)
}
}
// NoticeMessage sends a notice message to GitHub Actions.
func (l *GitHubActionsLogger) NoticeMessage(message string, input NoticeMessageInput) {
var prefix string = "::notice"
if input.Title != nil {
prefix += " title=" + *input.Title
}
if input.Filename != nil {
prefix += " file=" + *input.Filename
}
if input.Line != nil {
prefix += " line=" + fmt.Sprint(*input.Line)
}
if input.EndLine != nil {
prefix += " endLine=" + fmt.Sprint(*input.EndLine)
}
if input.Col != nil {
prefix += " col=" + fmt.Sprint(*input.Col)
}
if input.EndCol != nil {
prefix += " endColumn=" + fmt.Sprint(*input.EndCol)
}
l.info.Printf("%s::%s", prefix, message)
}
// StartGroup groups together log messages.
func (l *GitHubActionsLogger) StartGroup(name string) {
l.info.Printf("::group::%s", name)
}
// EndGroup ends a group.
func (l *GitHubActionsLogger) EndGroup() {
l.info.Println("::endgroup::")
}
// Mask masks a value in log output.
func (l *GitHubActionsLogger) Mask(value string) {
l.info.Printf("::add-mask::%s", value)
}
// SetOutput sets an output parameter.
func (l *GitHubActionsLogger) SetOutput(name string, value string) {
outputFile := os.Getenv("GITHUB_OUTPUT")
if outputFile == "" {
l.Errorf("GITHUB_OUTPUT is not set")
return
}
f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
l.Errorf("failed to open output file: %v", err)
return
}
defer f.Close()
if _, err := f.WriteString(fmt.Sprint(name, "=", value)); err != nil {
l.Errorf("failed to write output file: %v", err)
return
}
}
// SetSummary sets a job's summary in markdown format.
func (l *GitHubActionsLogger) SetSummary(summary string) {
summaryFile := os.Getenv("GITHUB_STEP_SUMMARY")
if summaryFile == "" {
l.Errorf("GITHUB_STEP_SUMMARY is not set")
return
}
f, err := os.OpenFile(summaryFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
l.Errorf("failed to open summary file: %v", err)
return
}
defer f.Close()
if _, err := f.WriteString(summary); err != nil {
l.Errorf("failed to write summary file: %v", err)
return
}
}

202
logging/logger.go Normal file
View File

@ -0,0 +1,202 @@
package logging
import (
"fmt"
"log"
"os"
"strings"
)
// Logger is an interface for logging.
type Logger interface {
Infof(format string, args ...interface{})
Warnf(format string, args ...interface{})
Errorf(format string, args ...interface{})
Debugf(format string, args ...interface{})
Mask(value string)
StartGroup(name string)
EndGroup()
NoticeMessage(message string, input NoticeMessageInput)
SetOutput(name string, value string)
SetSummary(summary string)
}
// DefaultLogger is a logger that logs to the console.
type DefaultLogger struct {
info *log.Logger
warn *log.Logger
err *log.Logger
debug *log.Logger
outputsFile string
summaryFile string
groups []string
masks []string
}
// NoticeMessageInput holds optional parameters for a notice message.
type NoticeMessageInput struct {
Title *string
Filename *string
Line *int
EndLine *int
Col *int
EndCol *int
}
// LoggerOptions holds options for creating a new logger.
type LoggerOptions struct {
OutputsFile string
SummaryFile string
Debug bool
}
// NewLogger creates a new default logger.
func NewLogger(options *LoggerOptions) Logger {
var debugLogger *log.Logger
if options.Debug {
debugLogger = log.New(os.Stdout, "DEBUG ", log.LstdFlags)
}
return &DefaultLogger{
info: log.New(os.Stdout, "INFO ", log.LstdFlags),
warn: log.New(os.Stdout, "WARNING ", log.LstdFlags),
err: log.New(os.Stderr, "ERROR ", log.LstdFlags),
debug: debugLogger,
groups: []string{},
masks: []string{},
outputsFile: options.OutputsFile,
summaryFile: options.SummaryFile,
}
}
// formatMessage wraps the message with the current group and removes any masked values.
func (l *DefaultLogger) formatMessage(message string) string {
message = l.removeMasks(message)
message = l.addGroups(message)
return message
}
// removeMasks removes any masked values from the message.
func (l *DefaultLogger) removeMasks(message string) string {
for _, mask := range l.masks {
message = strings.ReplaceAll(message, mask, "********")
}
return message
}
// addGroups adds the current group to the message.
func (l *DefaultLogger) addGroups(message string) string {
for _, group := range l.groups {
message = fmt.Sprint(group, " - ", message)
}
return message
}
// Infof logs an info message.
func (l *DefaultLogger) Infof(format string, args ...interface{}) {
l.info.Printf(l.formatMessage(format), args...)
}
// Warnf logs a warning message.
func (l *DefaultLogger) Warnf(format string, args ...interface{}) {
l.warn.Printf(l.formatMessage(format), args...)
}
// Errorf logs an error message.
func (l *DefaultLogger) Errorf(format string, args ...interface{}) {
l.err.Printf(l.formatMessage(format), args...)
}
// Debugf logs a debug message if debug logging is enabled.
func (l *DefaultLogger) Debugf(format string, args ...interface{}) {
if l.debug != nil {
l.debug.Printf(l.formatMessage(format), args...)
}
}
// NoticeMessage sends a notice about a line.
func (l *DefaultLogger) NoticeMessage(message string, input NoticeMessageInput) {
var prefix string = ""
if input.Title != nil {
prefix += " title=" + *input.Title
}
if input.Filename != nil {
prefix += " file=" + *input.Filename
}
if input.Line != nil {
prefix += " line=" + fmt.Sprint(*input.Line)
}
if input.EndLine != nil {
prefix += " endLine=" + fmt.Sprint(*input.EndLine)
}
if input.Col != nil {
prefix += " col=" + fmt.Sprint(*input.Col)
}
if input.EndCol != nil {
prefix += " endColumn=" + fmt.Sprint(*input.EndCol)
}
l.info.Printf(l.formatMessage(fmt.Sprintf("%s %s", prefix, message)))
}
// Mask hides a value in the log output.
func (l *DefaultLogger) Mask(value string) {
l.masks = append(l.masks, value)
}
// StartGroup groups together log messages.
func (l *DefaultLogger) StartGroup(name string) {
l.groups = append(l.groups, name)
}
// EndGroup ends a group.
func (l *DefaultLogger) EndGroup() {
if len(l.groups) > 0 {
l.groups = l.groups[:len(l.groups)-1]
}
}
// SetOutput outputs a key-value pair to the outputs file.
func (l *DefaultLogger) SetOutput(name string, value string) {
if l.outputsFile == "" {
return
}
f, err := os.OpenFile(l.outputsFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
l.Errorf("failed to open outputs file: %s", err)
return
}
defer f.Close()
if _, err := f.WriteString(fmt.Sprintf("%s=%s", name, value)); err != nil {
l.Errorf("failed to write to outputs file: %s", err)
return
}
}
// SetSummary outputs a markdown-formatted summary to the summary file.
func (l *DefaultLogger) SetSummary(summary string) {
if l.summaryFile == "" {
return
}
f, err := os.OpenFile(l.summaryFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
l.Errorf("failed to open summary file: %s", err)
return
}
defer f.Close()
if _, err := f.WriteString(summary); err != nil {
l.Errorf("failed to write to summary file: %s", err)
return
}
}