diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 1537954..e2474a5 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -2,35 +2,50 @@ package utils import ( "path" + "path/filepath" "sort" + "time" "github.com/sirupsen/logrus" "github.com/stenic/go-rotate-backups/internal/drivers" ) type Utils struct { - Driver drivers.Driver + Driver drivers.Driver + DateFormat string } -func (u *Utils) CleanFolder(dirPath string, keepCount int) error { +func (u *Utils) CleanFolder(dirPath string, cutoff time.Time) error { dirs, err := u.Driver.ListDirs(dirPath) if err != nil { logrus.Error(err.Error()) } logrus.Infof("Listing %s: %v", dirPath, dirs) - if len(dirs) > keepCount { - for _, old := range u.GetOldestN(dirs, len(dirs)-keepCount) { - path := path.Join(dirPath, old) - logrus.Debugf("Cleaning up %s", path) - if err := u.Driver.Delete(path); err != nil { - return err - } + for _, dir := range u.getDeleteDirs(dirs, cutoff) { + logrus.Debugf("Cleaning up %s", dir) + if err := u.Driver.Delete(filepath.Join(dirPath, dir)); err != nil { + return err } } - return nil } +func (u *Utils) getDeleteDirs(dirs []string, cutoff time.Time) []string { + deleteList := []string{} + for _, dir := range dirs { + dirTime, err := time.Parse(u.DateFormat, dir) + if err != nil { + logrus.Warnf("Could not parse %s as date: %v", dir, err) + continue + } + if dirTime.Before(cutoff) { + deleteList = append(deleteList, dir) + } + } + return deleteList + +} + func (u *Utils) GetPaths(targetPath string) (string, string, string, string) { daily := path.Join(targetPath, "daily") u.Driver.Mkdir(daily) diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go new file mode 100644 index 0000000..bf0e933 --- /dev/null +++ b/internal/utils/utils_test.go @@ -0,0 +1,58 @@ +package utils + +import ( + "reflect" + "testing" + "time" +) + +func TestUtils_getDeleteDirs(t *testing.T) { + df := "2006-01-02_15-04-05" + now := time.Now() + + type args struct { + dirs []string + cutoff time.Time + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "empty", + args: args{ + dirs: []string{}, + cutoff: now, + }, + want: []string{}, + }, + { + name: "one-passed", + args: args{ + dirs: []string{"2020-01-01_00-00-00"}, + cutoff: now, + }, + want: []string{"2020-01-01_00-00-00"}, + }, + { + name: "one-future", + args: args{ + dirs: []string{now.AddDate(1, 0, 0).Format(df)}, + cutoff: now, + }, + want: []string{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u := &Utils{ + Driver: nil, + DateFormat: df, + } + if got := u.getDeleteDirs(tt.args.dirs, tt.args.cutoff); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Utils.getDeleteDirs() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/main.go b/main.go index 06cd98d..7f8d80e 100644 --- a/main.go +++ b/main.go @@ -95,7 +95,8 @@ var rootCmd = &cobra.Command{ } util := utils.Utils{ - Driver: storageDriver, + Driver: storageDriver, + DateFormat: DateFormat, } if nowInput, err := time.Parse(DateFormat, date); err == nil { @@ -174,16 +175,16 @@ func addFunc(util utils.Utils, cmd *cobra.Command, files []string) error { func rotateFunc(util utils.Utils, cmd *cobra.Command, files []string) error { daily, weekly, monthly, yearly := util.GetPaths(util.Driver.GetTargetPath()) - if err := util.CleanFolder(daily, keepDaily); err != nil { + if err := util.CleanFolder(daily, now.AddDate(0, 0, -keepDaily)); err != nil { return err } - if err := util.CleanFolder(weekly, keepWeekly); err != nil { + if err := util.CleanFolder(weekly, now.AddDate(0, 0, -keepWeekly*7)); err != nil { return err } - if err := util.CleanFolder(monthly, keepMonthly); err != nil { + if err := util.CleanFolder(monthly, now.AddDate(0, -keepMonthly, 0)); err != nil { return err } - if err := util.CleanFolder(yearly, keepYearly); err != nil { + if err := util.CleanFolder(yearly, now.AddDate(-keepYearly, 0, 0)); err != nil { return err } diff --git a/test.sh b/test.sh index 5e0e2df..3237a06 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + go build -o ./test-binary main.go trap "rm -rf ./test-binary" EXIT