1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-15 02:02:08 -04:00
Files
DankMaterialShell/core/internal/log/filelogger.go
Particle_G 976b231b93 Add headless mode support with command-line flags (#2182)
* Add support for headless mode. Allow dankinstall run with command-line flags.

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146219

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146253

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146271

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146296

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146348

* FIx https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056146328

* Update headless mode instructions

* Add log dir config. Use DANKINSTALL_LOG env var, fallback to /var/tmp

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056737552

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056737572

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3056737592

* Add explanations for headless validating rules and log file location

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058087146 and https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058087234

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058087271

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058310408

* Enhance configuration deployment logic to support missing files and add corresponding unit tests

* Fix https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058310495

* Reworked the log channel handling logic to simplify the code and added the `drainLogChan` function to prevent blocking (https://github.com/AvengeMedia/DankMaterialShell/pull/2182#discussion_r3058609491)

* Added dependency-checking functionality to ensure installation requirements are met, and optimized the pre-installation logic for AUR packages

* feat: output log messages to stdout during installation

* Revert dependency-checking functionality due to official fix

* Revert compositor provider workaround due to upstream fix
2026-04-13 09:03:12 -04:00

115 lines
2.4 KiB
Go

package log
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"sync"
"time"
)
type FileLogger struct {
file *os.File
writer *bufio.Writer
logPath string
mu sync.Mutex
stopChan chan struct{}
doneChan chan struct{}
passwordRe *regexp.Regexp
}
func NewFileLogger() (*FileLogger, error) {
timestamp := time.Now().Unix()
// Use DANKINSTALL_LOG_DIR if set, otherwise fall back to /tmp.
logDir := os.Getenv("DANKINSTALL_LOG_DIR")
if logDir == "" {
logDir = "/tmp"
}
if err := os.MkdirAll(logDir, 0o755); err != nil {
return nil, fmt.Errorf("failed to create log directory: %w", err)
}
logPath := filepath.Join(logDir, fmt.Sprintf("dankinstall-%d.log", timestamp))
file, err := os.Create(logPath)
if err != nil {
return nil, fmt.Errorf("failed to create log file: %w", err)
}
passwordRe := regexp.MustCompile(`(?i)(password[:\s=]+)[^\s]+`)
logger := &FileLogger{
file: file,
writer: bufio.NewWriter(file),
logPath: logPath,
stopChan: make(chan struct{}),
doneChan: make(chan struct{}),
passwordRe: passwordRe,
}
header := fmt.Sprintf("=== DankInstall Log ===\nStarted: %s\n\n", time.Now().Format(time.RFC3339))
logger.writeToFile(header)
return logger, nil
}
func (l *FileLogger) GetLogPath() string {
return l.logPath
}
func (l *FileLogger) redactPassword(message string) string {
redacted := l.passwordRe.ReplaceAllString(message, "${1}[REDACTED]")
redacted = regexp.MustCompile(`echo\s+'[^']+'`).ReplaceAllString(redacted, "echo '[REDACTED]'")
return redacted
}
func (l *FileLogger) writeToFile(message string) {
l.mu.Lock()
defer l.mu.Unlock()
redacted := l.redactPassword(message)
timestamp := time.Now().Format("15:04:05.000")
fmt.Fprintf(l.writer, "[%s] %s\n", timestamp, redacted)
l.writer.Flush()
}
func (l *FileLogger) StartListening(logChan <-chan string) {
go func() {
defer close(l.doneChan)
for {
select {
case msg, ok := <-logChan:
if !ok {
return
}
l.writeToFile(msg)
case <-l.stopChan:
return
}
}
}()
}
func (l *FileLogger) Close() error {
close(l.stopChan)
<-l.doneChan
l.mu.Lock()
defer l.mu.Unlock()
footer := fmt.Sprintf("\n=== DankInstall Log End ===\nCompleted: %s\n", time.Now().Format(time.RFC3339))
l.writer.WriteString(footer) //nolint:errcheck
l.writer.Flush()
if err := l.file.Sync(); err != nil {
return err
}
return l.file.Close()
}