mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-14 17:52:10 -04:00
* 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
115 lines
2.4 KiB
Go
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()
|
|
}
|