package main import ( "fmt" "io/ioutil" "log" "sort" "strings" "time" ) type backup struct { Name string Time time.Time } var ( keep_yearly = 1 keep_monthly = 6 keep_weekly = 4 keep_daily = 14 patterns = map[string]string{ "daily": "2006-01-02", "weekly": "", // See special case in keepers() "monthly": "2006-01", "yearly": "2006", } ) func enumerate_backups() []backup { var backups []backup files, err := ioutil.ReadDir("./test/data") if err != nil { log.Fatal(err) } for _, file := range files { name := file.Name() time, err := time.Parse(time.RFC3339, strings.Split(name, "@")[1]) if err != nil { log.Fatalf("Failed to parse timestamp in %s\n", name) continue } backups = append(backups, backup{name, time}) } return backups } func keepers(backups []backup, rule string, keepCnt int) []backup { var keep []backup var last string for _, backup := range backups { var period string // Special case because there is no support for "week number" in Time.Format if rule == "weekly" { year, week := backup.Time.Local().ISOWeek() period = fmt.Sprintf("%d-%d", year, week) } else { period = backup.Time.Local().Format(patterns[rule]) } // fmt.Printf("rule: %s, pattern: %s, t: %s, format: %s\n", rule, patterns[rule], backup.Time.Local(), period) if period != last { last = period keep = append(keep, backup) if len(keep) == keepCnt { break } } } return keep } func main() { backups := enumerate_backups() sort.Slice(backups, func(i, j int) bool { return backups[i].Time.After(backups[j].Time) }) fmt.Println("============== DAILY ==============") for _, kept := range keepers(backups, "daily", keep_daily) { fmt.Printf("%s\n", kept.Name) } fmt.Println("============== WEEKLY ==============") for _, kept := range keepers(backups, "weekly", keep_weekly) { fmt.Printf("%s\n", kept.Name) } fmt.Println("============== MONTHLY ==============") for _, kept := range keepers(backups, "monthly", keep_monthly) { fmt.Printf("%s\n", kept.Name) } fmt.Println("============== YEARLY ==============") for _, kept := range keepers(backups, "yearly", keep_yearly) { fmt.Printf("%s\n", kept.Name) } }