feat: Add visual progress indicators to sync operations

- Implement ProgressReporter interface with InteractiveProgress and NoOpProgress
- Add real-time progress bars using go-pretty/progress library
- Track 6 sync phases: connection test, queue push, pull, parse, apply, and server push
- Add --quiet flag to suppress progress output
- Auto-detect TTY to disable progress when piped/redirected
- Show task-level progress during apply phase with descriptions
- Display percentage complete and elapsed time for each phase
This commit is contained in:
2026-01-05 23:20:27 +01:00
parent 59861bc3bf
commit 1c3186a342
5 changed files with 264 additions and 10 deletions
+36 -3
View File
@@ -12,6 +12,10 @@ import (
"github.com/spf13/cobra"
)
var (
quietFlag bool
)
var syncCmd = &cobra.Command{
Use: "sync",
Short: "Sync tasks with remote server",
@@ -91,7 +95,16 @@ Examples:
if response == "y" || response == "yes" {
strategy := sync.ParseStrategy(cfg.SyncStrategy)
result, err := client.Sync(strategy)
// Create progress reporter
var reporter sync.ProgressReporter
if sync.ShouldShowProgress(quietFlag) {
reporter = sync.NewInteractiveProgress(os.Stdout)
} else {
reporter = &sync.NoOpProgress{}
}
result, err := client.Sync(strategy, reporter)
if err != nil {
fmt.Fprintf(os.Stderr, "Error syncing: %v\n", err)
os.Exit(1)
@@ -172,7 +185,15 @@ var syncNowCmd = &cobra.Command{
client := sync.NewClient(cfg.SyncURL, cfg.SyncAPIKey, cfg.SyncClientID)
strategy := sync.ParseStrategy(cfg.SyncStrategy)
result, err := client.Sync(strategy)
// Create progress reporter
var reporter sync.ProgressReporter
if sync.ShouldShowProgress(quietFlag) {
reporter = sync.NewInteractiveProgress(os.Stdout)
} else {
reporter = &sync.NoOpProgress{}
}
result, err := client.Sync(strategy, reporter)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
@@ -351,7 +372,16 @@ Examples:
// Parse server tasks
// For initial merge, we'll do a full sync
result, err := client.Sync(strategy)
// Create progress reporter
var reporter sync.ProgressReporter
if sync.ShouldShowProgress(quietFlag) {
reporter = sync.NewInteractiveProgress(os.Stdout)
} else {
reporter = &sync.NoOpProgress{}
}
result, err := client.Sync(strategy, reporter)
if err != nil {
fmt.Fprintf(os.Stderr, "Error during merge: %v\n", err)
os.Exit(1)
@@ -379,6 +409,9 @@ func init() {
syncMergeCmd.Flags().Bool("prefer-local", false, "Prefer local database")
syncMergeCmd.Flags().Bool("prefer-server", false, "Prefer server database")
// Global sync flags
syncCmd.PersistentFlags().BoolVarP(&quietFlag, "quiet", "q", false, "Suppress progress output")
}
// Helper functions