diff --git a/backup/cmd/backup.go b/backup/cmd/backup.go index 41b8369..d27de13 100644 --- a/backup/cmd/backup.go +++ b/backup/cmd/backup.go @@ -11,12 +11,18 @@ import ( "github.com/spf13/cobra" ) -func executeSyncJobs(cfg internal.Config, simulate bool) { +func getLogPath(create bool) string { logPath := fmt.Sprintf("logs/sync-%s", time.Now().Format("2006-01-02T15-04-05")) - - if err := os.MkdirAll(logPath, 0755); err != nil { - log.Fatalf("Failed to create log directory: %v", err) + if create { + if err := os.MkdirAll(logPath, 0755); err != nil { + log.Fatalf("Failed to create log directory: %v", err) + } } + return logPath +} + +func executeSyncJobs(cfg internal.Config, simulate bool) { + logPath := getLogPath(true) overallLogPath := fmt.Sprintf("%s/summary.log", logPath) overallLogFile, err := os.OpenFile(overallLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) @@ -28,23 +34,17 @@ func executeSyncJobs(cfg internal.Config, simulate bool) { for _, job := range cfg.Jobs { jobLogPath := fmt.Sprintf("%s/job-%s.log", logPath, job.Name) - logFile, err := os.OpenFile(jobLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) - if err != nil { - overallLogger.Printf("ERROR [%s]: Failed to create job log file: %v", job.Name, err) - continue - } - defer logFile.Close() - jobLogger := log.New(logFile, "", log.LstdFlags) - - status := internal.ExecuteJob(job, simulate, false, jobLogger) + status := internal.ExecuteJob(job, simulate, false, jobLogPath) overallLogger.Printf("STATUS [%s]: %s", job.Name, status) fmt.Printf("Status [%s]: %s\n", job.Name, status) } } -func listCommands(cfg internal.Config, simulate bool) { +func listCommands(cfg internal.Config) { + logPath := getLogPath(false) for _, job := range cfg.Jobs { - internal.ExecuteJob(job, simulate, true, nil) + jobLogPath := fmt.Sprintf("%s/job-%s.log", logPath, job.Name) + internal.ExecuteJob(job, false, true, jobLogPath) } } @@ -71,7 +71,7 @@ var listCmd = &cobra.Command{ Short: "List the commands that will be executed", Run: func(cmd *cobra.Command, args []string) { cfg := loadResolvedConfig(configPath) - listCommands(cfg, true) + listCommands(cfg) }, } diff --git a/backup/internal/job.go b/backup/internal/job.go index 3d705cd..f75bc03 100644 --- a/backup/internal/job.go +++ b/backup/internal/job.go @@ -2,18 +2,20 @@ package internal import ( "fmt" - "log" "os/exec" "strings" ) var execCommand = exec.Command -func buildRsyncCmd(job Job, simulate bool) []string { - args := []string{"-aiv", "--info=progress2"} +func buildRsyncCmd(job Job, simulate bool, logPath string) []string { + args := []string{"-aiv", "--stats"} if job.Delete == nil || *job.Delete { args = append(args, "--delete") } + if logPath != "" { + args = append(args, fmt.Sprintf("--log-file=%s", logPath)) + } for _, excl := range job.Exclusions { args = append(args, fmt.Sprintf("--exclude=%s", excl)) } @@ -24,15 +26,12 @@ func buildRsyncCmd(job Job, simulate bool) []string { return args } -func ExecuteJob(job Job, simulate bool, show bool, logger *log.Logger) string { +func ExecuteJob(job Job, simulate bool, show bool, logPath string) string { if job.Enabled != nil && !*job.Enabled { - if logger != nil { - logger.Printf("SKIPPED [%s]: Job is disabled", job.Name) - } return "SKIPPED" } - args := buildRsyncCmd(job, simulate) + args := buildRsyncCmd(job, simulate, logPath) fmt.Printf("Job: %s\n", job.Name) fmt.Printf("Command: rsync %s\n", strings.Join(args, " ")) @@ -42,14 +41,9 @@ func ExecuteJob(job Job, simulate bool, show bool, logger *log.Logger) string { cmd := execCommand("rsync", args...) out, err := cmd.CombinedOutput() + fmt.Printf("Output:\n%s\n", string(out)) if err != nil { - if logger != nil { - logger.Printf("ERROR [%s]: %v\nOutput: %s", job.Name, err, string(out)) - } return "FAILURE" } - if logger != nil { - logger.Printf("SUCCESS [%s]: %s", job.Name, string(out)) - } return "SUCCESS" } diff --git a/backup/internal/job_test.go b/backup/internal/job_test.go index 02c11a4..eeb03a0 100644 --- a/backup/internal/job_test.go +++ b/backup/internal/job_test.go @@ -1,8 +1,6 @@ package internal import ( - "bytes" - "log" "os/exec" "strings" "testing" @@ -40,11 +38,10 @@ func TestBuildRsyncCmd(t *testing.T) { Delete: nil, Exclusions: []string{"*.tmp", "node_modules/"}, } - simulate := true - args := buildRsyncCmd(job, simulate) + args := buildRsyncCmd(job, true, "") expectedArgs := []string{ - "--dry-run", "-aiv", "--info=progress2", "--delete", + "--dry-run", "-aiv", "--stats", "--delete", "--exclude=*.tmp", "--exclude=node_modules/", "/home/user/Music/", "/target/user/music/home", } @@ -63,9 +60,8 @@ func TestExecuteJob(t *testing.T) { Exclusions: []string{"*.tmp"}, } simulate := true - logger := log.New(&bytes.Buffer{}, "", log.LstdFlags) - status := ExecuteJob(job, simulate, false, logger) + status := ExecuteJob(job, simulate, false, "") if status != "SUCCESS" { t.Errorf("Expected status SUCCESS, got %s", status) } @@ -77,7 +73,7 @@ func TestExecuteJob(t *testing.T) { Enabled: boolPtr(false), } - status = ExecuteJob(disabledJob, simulate, false, logger) + status = ExecuteJob(disabledJob, simulate, false, "") if status != "SKIPPED" { t.Errorf("Expected status SKIPPED, got %s", status) } @@ -89,7 +85,7 @@ func TestExecuteJob(t *testing.T) { Target: "/mnt/backup1/invalid/", } - status = ExecuteJob(invalidJob, false, false, logger) + status = ExecuteJob(invalidJob, false, false, "") if status != "FAILURE" { t.Errorf("Expected status FAILURE, got %s", status) } @@ -102,10 +98,7 @@ func TestJobSkippedEnabledTrue(t *testing.T) { Target: "/mnt/backup1/test/", Enabled: boolPtr(true), } - simulate := true - logger := log.New(&bytes.Buffer{}, "", log.LstdFlags) - - status := ExecuteJob(job, simulate, false, logger) + status := ExecuteJob(job, true, false, "") if status != "SUCCESS" { t.Errorf("Expected status SUCCESS, got %s", status) } @@ -118,10 +111,7 @@ func TestJobSkippedEnabledFalse(t *testing.T) { Target: "/mnt/backup1/disabled/", Enabled: boolPtr(false), } - simulate := true - logger := log.New(&bytes.Buffer{}, "", log.LstdFlags) - - status := ExecuteJob(disabledJob, simulate, false, logger) + status := ExecuteJob(disabledJob, true, false, "") if status != "SKIPPED" { t.Errorf("Expected status SKIPPED, got %s", status) } @@ -133,10 +123,7 @@ func TestJobSkippedEnabledOmitted(t *testing.T) { Source: "/home/omitted/", Target: "/mnt/backup1/omitted/", } - simulate := true - logger := log.New(&bytes.Buffer{}, "", log.LstdFlags) - - status := ExecuteJob(job, simulate, false, logger) + status := ExecuteJob(job, true, false, "") if status != "SUCCESS" { t.Errorf("Expected status SUCCESS, got %s", status) } @@ -153,10 +140,7 @@ func TestExecuteJobWithMockedRsync(t *testing.T) { Delete: nil, Exclusions: []string{"*.tmp"}, } - simulate := true - logger := log.New(&bytes.Buffer{}, "", log.LstdFlags) - - status := ExecuteJob(job, simulate, false, logger) + status := ExecuteJob(job, true, false, "") if status != "SUCCESS" { t.Errorf("Expected status SUCCESS, got %s", status)