diff --git a/main.go b/main.go index 5882ecd..7fc3ba3 100644 --- a/main.go +++ b/main.go @@ -103,18 +103,27 @@ func init() { func getBackupInterval() int { backupIntervalEnv := os.Getenv(envGitBackupInterval) - var backupInterval int - - var intervalConversionErr error - - if backupIntervalEnv != "" { - backupInterval, intervalConversionErr = strconv.Atoi(backupIntervalEnv) - if intervalConversionErr != nil { - logger.Fatalf("%s must be a number.", envGitBackupInterval) + hours, isHour := isInt(backupIntervalEnv) + + switch { + case isHour: + // an int represents hours + return hours * 60 + case strings.HasSuffix(backupIntervalEnv, "h"): + // a string ending in h represents hours + hours, isHour = isInt(backupIntervalEnv[:len(backupIntervalEnv)-1]) + if isHour { + return hours * 60 + } + case strings.HasSuffix(backupIntervalEnv, "m"): + // a string ending in m represents minutes + minutes, isMinute := isInt(backupIntervalEnv[:len(backupIntervalEnv)-1]) + if isMinute { + return minutes } } - return backupInterval + return 0 } func getLogLevel() int { @@ -219,10 +228,6 @@ func displayStartupConfig() { logger.Printf("root backup directory: %s", backupDIR) } - if backupInterval := os.Getenv(envGitBackupInterval); backupInterval != "" { - logger.Printf("git backup interval: %s hours", backupInterval) - } - // output github config if ghToken := os.Getenv(envGitHubToken); ghToken != "" { if ghOrgs := strings.ToLower(os.Getenv(envGitHubOrgs)); ghOrgs != "" { @@ -335,14 +340,9 @@ func run() error { backupInterval := getBackupInterval() if backupInterval != 0 { - hourOutput := "hour" - if backupInterval > 1 { - hourOutput = "hours" - } + logger.Printf("scheduling to run every %s", formatIntervalDuration(backupInterval)) - logger.Printf("scheduling to run every %d %s", backupInterval, hourOutput) - - _, err = scheduler.Every(int(time.Duration(backupInterval))).Hours().Run(execProviderBackups) + _, err = scheduler.Every(int(time.Duration(backupInterval))).Minutes().Run(execProviderBackups) if err != nil { return errors.Wrapf(err, "scheduler failed") } @@ -355,6 +355,18 @@ func run() error { return nil } +func formatIntervalDuration(m int) string { + if m == 0 { + return "" + } + + if m%60 == 0 { + return fmt.Sprintf("%dh", m/60) + } + + return time.Duration(int64(m) * int64(time.Minute)).String() +} + func getOrgsListFromEnvVar(envVar string) []string { orgsList := os.Getenv(envVar) @@ -477,12 +489,12 @@ func execProviderBackups() { logger.Println("backups complete") if backupInterval := getBackupInterval(); backupInterval > 0 { - nextBackupTime := startTime.Add(time.Duration(backupInterval) * time.Hour) + nextBackupTime := startTime.Add(time.Duration(backupInterval) * time.Minute) if nextBackupTime.Before(time.Now()) { logger.Fatal("error: backup took longer than scheduled interval") } - logger.Printf("next run scheduled for: %v", nextBackupTime) + logger.Printf("next run scheduled for: %s", nextBackupTime.Format("2006-01-02 15:04:05 -0700 MST")) } } @@ -527,3 +539,11 @@ func getBackupsToRetain(envVar string) int { return backupsToKeep } + +func isInt(i string) (int, bool) { + if val, err := strconv.Atoi(i); err == nil { + return val, true + } + + return 0, false +} diff --git a/main_test.go b/main_test.go index 5b2f6a7..937a2d4 100644 --- a/main_test.go +++ b/main_test.go @@ -388,6 +388,13 @@ func TestGiteaRepositoryBackup(t *testing.T) { require.NoError(t, run()) } +func TestFormatIntervalDuration(t *testing.T) { + require.Equal(t, "", formatIntervalDuration(0)) + require.Equal(t, "1h", formatIntervalDuration(60)) + require.Equal(t, "1h1m0s", formatIntervalDuration(61)) + require.Equal(t, "3m0s", formatIntervalDuration(3)) +} + func TestGiteaOrgsRepositoryBackup(t *testing.T) { if os.Getenv(envGiteaToken) == "" { t.Skipf("Skipping Gitea test as %s is missing", envGiteaToken) @@ -405,45 +412,72 @@ func TestGiteaOrgsRepositoryBackup(t *testing.T) { defer resetBackups() - unsetEnvVarsExcept([]string{envGitBackupDir, envGiteaToken, envGiteaAPIURL, envGiteaOrgs}) + unsetEnvVarsExcept([]string{envGitBackupDir, envGiteaToken, envGiteaAPIURL}) for _, org := range []string{"soba-org-two", "*"} { require.NoError(t, os.Setenv(envGiteaOrgs, org)) require.NoError(t, run()) - require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) - entriesOrgOne, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one")) - require.NoError(t, err) - entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) - require.NoError(t, err) + switch org { + case "soba-org-two": + require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) + require.NoDirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one")) + entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) + require.NoError(t, err) - require.Len(t, entriesOrgTwo, 2) + require.Len(t, entriesOrgTwo, 2) - var foundOne, foundTwo, foundThree bool + var foundOne, foundTwo bool - for _, entry := range entriesOrgOne { - if strings.HasPrefix(entry.Name(), "soba-org-one-repo-one") { - foundThree = true + for _, entry := range entriesOrgTwo { + if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") { + foundOne = true + } + + if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") { + foundTwo = true + } } - } - for _, entry := range entriesOrgTwo { - if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") { - foundOne = true + require.True(t, foundOne) + require.True(t, foundTwo) + + resetBackups() + case "*": + require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) + require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one")) + entriesOrgOne, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one")) + require.NoError(t, err) + entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two")) + require.NoError(t, err) + + require.Len(t, entriesOrgOne, 1) + require.Len(t, entriesOrgTwo, 2) + + var foundOne, foundTwo, foundThree bool + + for _, entry := range entriesOrgOne { + if strings.HasPrefix(entry.Name(), "soba-org-one-repo-one") { + foundThree = true + } } - if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") { - foundTwo = true + for _, entry := range entriesOrgTwo { + if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") { + foundOne = true + } + + if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") { + foundTwo = true + } } - } - switch org { - case "soba-org-two": - require.True(t, foundOne && foundTwo) - require.False(t, foundThree) - case "*": - require.True(t, foundOne && foundTwo && foundThree) + require.True(t, foundOne) + require.True(t, foundTwo) + require.True(t, foundThree) + + resetBackups() } resetBackups() @@ -617,3 +651,25 @@ func TestGithubRepositoryBackupWithWildcardOrgsAndPersonal(t *testing.T) { require.Regexp(t, regexp.MustCompile(`^repo[0,1]\.\d{14}\.bundle$`), entries[0].Name()) } } + +func TestGetBackupInterval(t *testing.T) { + _ = os.Setenv(envGitBackupInterval, "1h") + + require.Equal(t, 60, getBackupInterval()) + + _ = os.Setenv(envGitBackupInterval, "1") + + require.Equal(t, 60, getBackupInterval()) + + _ = os.Setenv(envGitBackupInterval, "100h") + + require.Equal(t, 6000, getBackupInterval()) + + _ = os.Setenv(envGitBackupInterval, "100m") + + require.Equal(t, 100, getBackupInterval()) + + _ = os.Setenv(envGitBackupInterval, "0") + + require.Equal(t, 0, getBackupInterval()) +}