feat: add --log-file/-l flag

This commit is contained in:
2025-12-06 00:06:53 +02:00
parent 44981157e7
commit 995abdbbf8
4 changed files with 74 additions and 13 deletions

View File

@@ -42,6 +42,10 @@ type AppCliConfig struct {
CheckUpdates *bool
// Filter is a list of installer names to filter by.
Filter []string
// LogFile is the path to the log file.
LogFile *string
// ShowLogFile indicates that only the log file path should be shown.
ShowLogFile bool
}
// AppConfigDefaults provides default configurations for installer types.
@@ -198,6 +202,8 @@ func ParseCliConfig() *AppCliConfig {
Debug: nil,
CheckUpdates: nil,
Filter: []string{},
LogFile: nil,
ShowLogFile: false,
}
file := FindConfigFile()
for len(args) > 0 {
@@ -215,6 +221,15 @@ func ParseCliConfig() *AppCliConfig {
config.Filter = append(config.Filter, args[1])
args = args[1:]
}
case "-l", "--log-file":
if len(args) > 1 && !strings.HasPrefix(args[1], "-") {
logFile := args[1]
config.LogFile = &logFile
args = args[1:]
} else {
// No value provided, just show log file path
config.ShowLogFile = true
}
case "-h", "--help":
printHelp()
os.Exit(0)
@@ -233,6 +248,10 @@ func ParseCliConfig() *AppCliConfig {
}
args = args[1:]
}
// If only showing log file, don't require config file
if config.ShowLogFile {
return config
}
if file == "" {
fmt.Fprintln(os.Stderr, "No config file found")
os.Exit(1)
@@ -249,8 +268,9 @@ func printHelp() {
fmt.Println(" -D, --no-debug Disable debug mode")
fmt.Println(" -u, --update Enable update checks")
fmt.Println(" -U, --no-update Disable update checks")
fmt.Println(" -h, --help Show this help message")
fmt.Println(" -f, --filter Filter by installer name (can be used multiple times)")
fmt.Println(" -l, --log-file Set log file path, or show current path if no value given")
fmt.Println(" -h, --help Show this help message")
fmt.Println(" -v, --version Show version")
fmt.Println("")
fmt.Println("For online documentation, see https://github.com/chenasraf/sofmani/tree/master/docs")

View File

@@ -8,6 +8,11 @@ import (
// It parses command-line arguments and then parses the configuration file.
func LoadConfig() (*appconfig.AppConfig, error) {
overrides := appconfig.ParseCliConfig()
return loadConfigFromCli(overrides)
}
// loadConfigFromCli loads the application configuration from pre-parsed CLI config.
func loadConfigFromCli(overrides *appconfig.AppCliConfig) (*appconfig.AppConfig, error) {
cfg, err := appconfig.ParseConfig(overrides)
if err != nil {
return nil, err

View File

@@ -13,13 +13,15 @@ import (
// 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.
consoleOut *log.Logger // consoleOut is the logger for writing to the console.
logFile *os.File // logFile is the opened log file.
debug bool // debug indicates whether debug logging is enabled.
fileLogger *log.Logger // fileLogger is the logger for writing to the log file.
consoleOut *log.Logger // consoleOut is the logger for writing to the console.
logFile *os.File // logFile is the opened log file.
logFilePath string // logFilePath is the path to the log file.
debug bool // debug indicates whether debug logging is enabled.
}
var logger *Logger // logger is the global logger instance.
var logger *Logger // logger is the global logger instance.
var customLogFile *string // customLogFile holds the custom log file path if set.
// GetLogDir returns the appropriate log directory based on the operating system.
func GetLogDir() string {
@@ -41,11 +43,29 @@ func GetLogDir() string {
return logDir
}
// GetDefaultLogFile returns the default log file path.
func GetDefaultLogFile() string {
return filepath.Join(GetLogDir(), "sofmani.log")
}
// GetLogFile returns the current log file path (custom or default).
func GetLogFile() string {
if customLogFile != nil {
return *customLogFile
}
return GetDefaultLogFile()
}
// SetLogFile sets a custom log file path.
func SetLogFile(path string) {
customLogFile = &path
}
// InitLogger initializes the global logger with the specified debug mode.
// It creates the log directory and file if they don't exist.
func InitLogger(debug bool) *Logger {
logDir := GetLogDir()
filePath := filepath.Join(logDir, "sofmani.log")
filePath := GetLogFile()
logDir := filepath.Dir(filePath)
if _, err := os.Stat(logDir); os.IsNotExist(err) {
err := os.MkdirAll(logDir, 0755)
if err != nil {
@@ -65,10 +85,11 @@ func InitLogger(debug bool) *Logger {
// Initialize the logger
logger = &Logger{
fileLogger: fileLogger,
consoleOut: consoleOut,
logFile: logFile,
debug: debug,
fileLogger: fileLogger,
consoleOut: consoleOut,
logFile: logFile,
logFilePath: filePath,
debug: debug,
}
return logger

17
main.go
View File

@@ -17,7 +17,22 @@ var appVersion []byte // appVersion is embedded from version.txt and contains th
// main is the entry point of the application.
func main() {
appconfig.SetVersion(strings.TrimSpace(string(appVersion)))
cfg, err := LoadConfig()
// Parse CLI config first to check for --log-file flag
cliConfig := appconfig.ParseCliConfig()
// Handle --log-file without value: show log file path and exit
if cliConfig.ShowLogFile {
fmt.Println(logger.GetLogFile())
return
}
// Set custom log file if provided
if cliConfig.LogFile != nil {
logger.SetLogFile(*cliConfig.LogFile)
}
cfg, err := loadConfigFromCli(cliConfig)
if err != nil {
fmt.Println(fmt.Errorf("error loading config: %v", err))
return