package database import ( "os" "path/filepath" "slices" "strings" "time" ) type backupFile struct { path string modified time.Time } func newBackupTarget(directory string, now time.Time, extension string) (string, error) { if err := os.MkdirAll(directory, os.ModePerm); err != nil { return "", err } target := filepath.Join(directory, backupFilePrefix+now.UTC().Format(backupTimeLayout)+extension) if _, err := os.Stat(target); err == nil { return "", errBackupExists } return target, nil } func pruneBackups(directory string, extension string) error { entries, err := os.ReadDir(directory) if err != nil { return err } files := make([]backupFile, 0, len(entries)) for _, entry := range entries { if entry.IsDir() || !strings.HasSuffix(entry.Name(), extension) { continue } info, err := entry.Info() if err != nil { return err } files = append(files, backupFile{path: filepath.Join(directory, entry.Name()), modified: info.ModTime()}) } slices.SortFunc(files, func(a, b backupFile) int { if byTime := b.modified.Compare(a.modified); byTime != 0 { return byTime } return strings.Compare(b.path, a.path) }) for _, stale := range files[min(backupsToKeep, len(files)):] { if err := os.Remove(stale.path); err != nil { return err } } return nil }