mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
feat: update logging style & formatting
This commit is contained in:
@@ -39,7 +39,7 @@ func (i *GroupInstaller) Validate() []ValidationError {
|
||||
func (i *GroupInstaller) Install() error {
|
||||
info := i.GetData()
|
||||
name := *info.Name
|
||||
logger.Debug("Installing group %s", name)
|
||||
logger.Debug("Installing group %s", logger.H(name))
|
||||
i.childResults = []summary.InstallResult{}
|
||||
for _, step := range *i.Data.Steps {
|
||||
installer, err := GetInstaller(i.Config, &step)
|
||||
@@ -47,11 +47,11 @@ func (i *GroupInstaller) Install() error {
|
||||
return err
|
||||
}
|
||||
if installer == nil {
|
||||
logger.Warn("Installer type %s is not supported, skipping", step.Type)
|
||||
logger.Warn("Installer type %s is not supported, skipping", logger.H(string(step.Type)))
|
||||
} else {
|
||||
result, err := RunInstaller(i.Config, installer)
|
||||
if err != nil {
|
||||
logger.Error("Failed to run installer for step %s: %v", *step.Name, err)
|
||||
logger.Error("Failed to run installer for step %s: %v", logger.H(*step.Name), err)
|
||||
return fmt.Errorf("failed to run installer for step %s: %w", *step.Name, err)
|
||||
}
|
||||
if result != nil {
|
||||
|
||||
@@ -165,10 +165,10 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) (*summary.I
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug("Checking if %s (%s) should run on %s", name, info.Type, curOS)
|
||||
logger.Debug("Checking if %s: %s should run on %s", logger.H(string(info.Type)), logger.H(name), curOS)
|
||||
env := config.Environ()
|
||||
if !installer.GetData().Platforms.GetShouldRunOnOS(curOS) {
|
||||
logger.Debug("%s should not run on %s, skipping", name, curOS)
|
||||
logger.Debug("%s should not run on %s, skipping", logger.H(name), curOS)
|
||||
result.Action = summary.ActionSkipped
|
||||
return result, nil
|
||||
}
|
||||
@@ -179,12 +179,12 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) (*summary.I
|
||||
machineAliases = *config.MachineAliases
|
||||
}
|
||||
if !installer.GetData().Machines.GetShouldRunOnMachine(machineID, machineAliases) {
|
||||
logger.Debug("%s should not run on machine %s, skipping", name, machineID)
|
||||
logger.Debug("%s should not run on machine %s, skipping", logger.H(name), machineID)
|
||||
result.Action = summary.ActionSkipped
|
||||
return result, nil
|
||||
}
|
||||
if !FilterInstaller(installer, config.Filter) {
|
||||
logger.Debug("%s is filtered, skipping", name)
|
||||
logger.Debug("%s is filtered, skipping", logger.H(name))
|
||||
result.Action = summary.ActionSkipped
|
||||
return result, nil
|
||||
}
|
||||
@@ -196,42 +196,42 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) (*summary.I
|
||||
}
|
||||
|
||||
if !enabled {
|
||||
logger.Debug("%s is disabled, skipping", name)
|
||||
logger.Debug("%s is disabled, skipping", logger.H(name))
|
||||
result.Action = summary.ActionSkipped
|
||||
return result, nil
|
||||
}
|
||||
|
||||
logger.Debug("Checking %s: %s", info.Type, name)
|
||||
logger.Debug("Checking %s: %s", logger.H(string(info.Type)), logger.H(name))
|
||||
installed, err := installer.CheckIsInstalled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if installed {
|
||||
logger.Debug("%s (%s) is already installed", name, info.Type)
|
||||
logger.Debug("%s: %s is already installed", logger.H(string(info.Type)), logger.H(name))
|
||||
|
||||
if *config.CheckUpdates {
|
||||
logger.Info("Checking updates for %s: %s", info.Type, name)
|
||||
logger.Info("Checking updates for %s: %s", logger.H(string(info.Type)), logger.H(name))
|
||||
needsUpdate, err := installer.CheckNeedsUpdate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if needsUpdate {
|
||||
logger.Info("Updating %s", name)
|
||||
logger.Info("Updating %s", logger.H(name))
|
||||
if info.PreUpdate != nil {
|
||||
logger.Debug("Running pre-update command for %s", name)
|
||||
logger.Debug("Running pre-update command for %s", logger.H(name))
|
||||
err := utils.RunCmdPassThrough(env, utils.GetOSShell(installer.GetData().EnvShell), utils.GetOSShellArgs(*info.PreUpdate)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
logger.Debug("Running update command for %s", name)
|
||||
logger.Debug("Running update command for %s", logger.H(name))
|
||||
err := installer.Update()
|
||||
if err != nil {
|
||||
logger.Error("Failed to update %s: %v", name, err)
|
||||
logger.Error("Failed to update %s: %v", logger.H(name), err)
|
||||
return nil, fmt.Errorf("failed to update %s: %w", name, err)
|
||||
}
|
||||
if info.PostUpdate != nil {
|
||||
logger.Debug("Running post-update command for %s", name)
|
||||
logger.Debug("Running post-update command for %s", logger.H(name))
|
||||
err := utils.RunCmdPassThrough(env, utils.GetOSShell(installer.GetData().EnvShell), utils.GetOSShellArgs(*info.PostUpdate)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -239,28 +239,28 @@ func RunInstaller(config *appconfig.AppConfig, installer IInstaller) (*summary.I
|
||||
}
|
||||
result.Action = summary.ActionUpgraded
|
||||
} else {
|
||||
logger.Info("%s (%s) is up-to-date", name, info.Type)
|
||||
logger.Info("%s: %s is up-to-date", logger.H(string(info.Type)), logger.H(name))
|
||||
result.Action = summary.ActionUpToDate
|
||||
}
|
||||
} else {
|
||||
result.Action = summary.ActionUpToDate
|
||||
}
|
||||
} else {
|
||||
logger.Info("Installing %s: %s", installer.GetData().Type, name)
|
||||
logger.Info("Installing %s: %s", logger.H(string(installer.GetData().Type)), logger.H(name))
|
||||
if info.PreInstall != nil {
|
||||
logger.Debug("Running pre-install command for %s (%s)", name, info.Type)
|
||||
logger.Debug("Running pre-install command for %s: %s", logger.H(string(info.Type)), logger.H(name))
|
||||
err := utils.RunCmdPassThrough(env, utils.GetOSShell(installer.GetData().EnvShell), utils.GetOSShellArgs(*info.PreInstall)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
logger.Debug("Running installer for %s (%s)", name, info.Type)
|
||||
logger.Debug("Running installer for %s: %s", logger.H(string(info.Type)), logger.H(name))
|
||||
err = installer.Install()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if info.PostInstall != nil {
|
||||
logger.Debug("Running post-install command for %s (%s)", name, info.Type)
|
||||
logger.Debug("Running post-install command for %s: %s", logger.H(string(info.Type)), logger.H(name))
|
||||
err := utils.RunCmdPassThrough(env, utils.GetOSShell(installer.GetData().EnvShell), utils.GetOSShellArgs(*info.PostInstall)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -64,20 +64,20 @@ func (i *ManifestInstaller) Install() error {
|
||||
info := i.GetData()
|
||||
name := *info.Name
|
||||
config := i.ManifestConfig
|
||||
logger.Info("Installing manifest %s", name)
|
||||
logger.Info("Installing manifest %s", logger.H(name))
|
||||
i.childResults = []summary.InstallResult{}
|
||||
for _, step := range config.Install {
|
||||
logger.Debug("Checking step %s", *step.Name)
|
||||
logger.Debug("Checking step %s", logger.H(*step.Name))
|
||||
installer, err := GetInstaller(config, &step)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if installer == nil {
|
||||
logger.Warn("Installer type %s is not supported, skipping", step.Type)
|
||||
logger.Warn("Installer type %s is not supported, skipping", logger.H(string(step.Type)))
|
||||
} else {
|
||||
result, err := RunInstaller(config, installer)
|
||||
if err != nil {
|
||||
logger.Error("Failed to run installer for step %s: %v", *step.Name, err)
|
||||
logger.Error("Failed to run installer for step %s: %v", logger.H(*step.Name), err)
|
||||
return fmt.Errorf("failed to run installer for step %s: %w", *step.Name, err)
|
||||
}
|
||||
if result != nil {
|
||||
|
||||
@@ -5,12 +5,39 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/chenasraf/sofmani/platform"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
// Highlight markers (using unlikely byte sequences)
|
||||
const (
|
||||
highlightStart = "\x00HS\x00"
|
||||
highlightEnd = "\x00HE\x00"
|
||||
)
|
||||
|
||||
// ANSI color codes
|
||||
const (
|
||||
ansiHighlight = "\033[1;96m" // Bright cyan for highlights
|
||||
ansiBlueBold = "\033[1;34m"
|
||||
ansiYellowBold = "\033[1;33m"
|
||||
ansiRedBold = "\033[1;31m"
|
||||
ansiGreenBold = "\033[1;32m"
|
||||
ansiReset = "\033[0m"
|
||||
)
|
||||
|
||||
// Highlight marks text to be displayed in white/bold in console output.
|
||||
// Use this for installer names, types, and other important identifiers.
|
||||
func Highlight(text string) string {
|
||||
return highlightStart + text + highlightEnd
|
||||
}
|
||||
|
||||
// H is a shorthand alias for Highlight.
|
||||
func H(text string) string {
|
||||
return Highlight(text)
|
||||
}
|
||||
|
||||
// Logger provides logging functionality with support for file and console output.
|
||||
type Logger struct {
|
||||
fileLogger *log.Logger // fileLogger is the logger for writing to the log file.
|
||||
@@ -115,49 +142,64 @@ func InitLogger(debug bool) *Logger {
|
||||
return logger
|
||||
}
|
||||
|
||||
// stripHighlightMarkers removes highlight markers from text (for file output).
|
||||
func stripHighlightMarkers(text string) string {
|
||||
text = strings.ReplaceAll(text, highlightStart, "")
|
||||
text = strings.ReplaceAll(text, highlightEnd, "")
|
||||
return text
|
||||
}
|
||||
|
||||
// processHighlights converts highlight markers to ANSI codes for console output.
|
||||
func processHighlights(text string, baseColorSeq string) string {
|
||||
// Replace start marker with highlight color
|
||||
text = strings.ReplaceAll(text, highlightStart, ansiHighlight)
|
||||
// Replace end marker with reset + base color (to restore the log level color)
|
||||
text = strings.ReplaceAll(text, highlightEnd, ansiReset+baseColorSeq)
|
||||
return text
|
||||
}
|
||||
|
||||
// log is an internal helper function for logging messages with a specific level and color.
|
||||
func (l *Logger) log(level string, colorizer *color.Color, format string, args ...any) {
|
||||
// Create timestamped message
|
||||
// timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||
func (l *Logger) log(level string, colorSeq string, format string, args ...any) {
|
||||
message := fmt.Sprintf("[%s] %s", level, fmt.Sprintf(format, args...))
|
||||
|
||||
// Write to file
|
||||
l.fileLogger.Println(message)
|
||||
// Write to file (strip all highlight markers - file should have no colors)
|
||||
fileMessage := stripHighlightMarkers(message)
|
||||
l.fileLogger.Println(fileMessage)
|
||||
|
||||
if level == "DEBUG" && !l.debug {
|
||||
return
|
||||
}
|
||||
|
||||
// Write to console with color
|
||||
if colorizer != nil {
|
||||
l.consoleOut.Println(colorizer.Sprint(message))
|
||||
if colorSeq != "" {
|
||||
consoleMessage := processHighlights(message, colorSeq)
|
||||
// Wrap entire message in base color and reset at end
|
||||
l.consoleOut.Println(colorSeq + consoleMessage + ansiReset)
|
||||
} else {
|
||||
l.consoleOut.Println(message)
|
||||
// No base color - just convert highlights to white
|
||||
consoleMessage := processHighlights(message, "")
|
||||
l.consoleOut.Println(consoleMessage)
|
||||
}
|
||||
}
|
||||
|
||||
// Info logs an informational message.
|
||||
func Info(format string, args ...any) {
|
||||
colorBlue := color.New(color.FgBlue).Add(color.Bold)
|
||||
logger.log(" INFO", colorBlue, format, args...)
|
||||
logger.log(" INFO", ansiBlueBold, format, args...)
|
||||
}
|
||||
|
||||
// Warn logs a warning message.
|
||||
func Warn(format string, args ...any) {
|
||||
colorYellow := color.New(color.FgYellow).Add(color.Bold)
|
||||
logger.log(" WARN", colorYellow, format, args...)
|
||||
logger.log(" WARN", ansiYellowBold, format, args...)
|
||||
}
|
||||
|
||||
// Error logs an error message.
|
||||
func Error(format string, args ...any) {
|
||||
colorRed := color.New(color.FgRed).Add(color.Bold)
|
||||
logger.log("ERROR", colorRed, format, args...)
|
||||
logger.log("ERROR", ansiRedBold, format, args...)
|
||||
}
|
||||
|
||||
// Debug logs a debug message. Only printed if debug mode is enabled.
|
||||
func Debug(format string, args ...any) {
|
||||
colorGreen := color.New(color.FgGreen).Add(color.Bold)
|
||||
logger.log("DEBUG", colorGreen, format, args...)
|
||||
logger.log("DEBUG", ansiGreenBold, format, args...)
|
||||
}
|
||||
|
||||
// Spew logs a detailed representation of a value using spew.Dump.
|
||||
|
||||
@@ -197,7 +197,7 @@ func hasChildrenWithAction(children []InstallResult, action Action) bool {
|
||||
// printResult prints a single result with the given indentation level.
|
||||
func (s *Summary) printResult(r InstallResult, indent int) {
|
||||
prefix := strings.Repeat(" ", indent)
|
||||
logger.Info("%s- %s: %s", prefix, r.Type, r.Name)
|
||||
logger.Info("%s- %s: %s", prefix, logger.H(r.Type), logger.H(r.Name))
|
||||
|
||||
for _, child := range r.Children {
|
||||
s.printResult(child, indent+1)
|
||||
|
||||
Reference in New Issue
Block a user