From fce7fd3cfbef863abc4ab507395b681f510f03d4 Mon Sep 17 00:00:00 2001 From: Mauro Trulli Date: Thu, 19 Feb 2026 13:04:56 +0100 Subject: [PATCH] fix(logging): align default paths and refactor logging setup --- cmd/picoclaw/main.go | 42 ++++++++++++++++++---------- cmd/picoclaw/main_test.go | 59 +++++++++++++++++++++++++++++++++++++++ pkg/config/config.go | 2 +- 3 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 cmd/picoclaw/main_test.go diff --git a/cmd/picoclaw/main.go b/cmd/picoclaw/main.go index bef1b97e4..c611da51a 100644 --- a/cmd/picoclaw/main.go +++ b/cmd/picoclaw/main.go @@ -1432,25 +1432,37 @@ func skillsShowCmd(loader *skills.SkillsLoader, skillName string) { fmt.Println(content) } -func setupLogging(cfg *config.Config) { - if strings.ToLower(cfg.Logging.Level) == "debug" { - logger.SetLevel(logger.DEBUG) - } else if strings.ToLower(cfg.Logging.Level) == "warn" { - logger.SetLevel(logger.WARN) - } else if strings.ToLower(cfg.Logging.Level) == "error" { - logger.SetLevel(logger.ERROR) - } else { - logger.SetLevel(logger.INFO) +func parseLogLevel(level string) logger.LogLevel { + switch strings.ToLower(level) { + case "debug": + return logger.DEBUG + case "warn": + return logger.WARN + case "error": + return logger.ERROR + default: + return logger.INFO } +} + +func expandPath(p string) string { + if p == "~" || strings.HasPrefix(p, "~/") { + if home, err := os.UserHomeDir(); err == nil { + return filepath.Join(home, p[1:]) + } + } + return p +} + +func setupLogging(cfg *config.Config) { + logger.SetLevel(parseLogLevel(cfg.Logging.Level)) if cfg.Logging.EnableFile && cfg.Logging.FilePath != "" { - logPath := cfg.Logging.FilePath - if strings.HasPrefix(logPath, "~") { - home, _ := os.UserHomeDir() - logPath = filepath.Join(home, logPath[1:]) - } + logPath := expandPath(cfg.Logging.FilePath) - os.MkdirAll(filepath.Dir(logPath), 0755) + if err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil { + fmt.Printf("Warning: unable to create log directory: %v\n", err) + } if err := logger.EnableFileLogging(logPath); err != nil { fmt.Printf("Warning: unable to create log file: %v\n", err) diff --git a/cmd/picoclaw/main_test.go b/cmd/picoclaw/main_test.go new file mode 100644 index 000000000..aca24c314 --- /dev/null +++ b/cmd/picoclaw/main_test.go @@ -0,0 +1,59 @@ +package main + +import ( + "os" + "path/filepath" + "testing" + + "github.com/sipeed/picoclaw/pkg/logger" +) + +func TestParseLogLevel(t *testing.T) { + tests := []struct { + input string + expected logger.LogLevel + }{ + {"debug", logger.DEBUG}, + {"DEBUG", logger.DEBUG}, + {"warn", logger.WARN}, + {"error", logger.ERROR}, + {"info", logger.INFO}, + {"unknown", logger.INFO}, // Default fallback + {"", logger.INFO}, // Empty string fallback + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + if got := parseLogLevel(tt.input); got != tt.expected { + t.Errorf("parseLogLevel(%q) = %v, want %v", tt.input, got, tt.expected) + } + }) + } +} + +func TestExpandPath(t *testing.T) { + home, err := os.UserHomeDir() + if err != nil { + t.Skip("Skipping test: unable to get user home directory") + } + + tests := []struct { + name string + input string + expected string + }{ + {"Home directory root", "~", home}, + {"Home directory subpath", "~/logs/audit.log", filepath.Join(home, "/logs/audit.log")}, + {"Absolute path", "/var/log/app.log", "/var/log/app.log"}, + {"Relative path", "./logs/app.log", "./logs/app.log"}, + {"Other user home (should not expand)", "~user/logs.txt", "~user/logs.txt"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := expandPath(tt.input); got != tt.expected { + t.Errorf("expandPath(%q) = %q, want %q", tt.input, got, tt.expected) + } + }) + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go index ce785cd88..533729474 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -365,7 +365,7 @@ func DefaultConfig() *Config { }, Logging: LoggingConfig{ EnableFile: false, - FilePath: "~/.picoclaw/workspace/picoclaw_audit.log", + FilePath: "picoclaw_audit.log", Level: "info", }, }