diff options
| author | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-06 22:03:47 +0200 |
|---|---|---|
| committer | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-06 22:03:47 +0200 |
| commit | 990f6e2aacbbb6869259390d973fde30fac13501 (patch) | |
| tree | 18d4a7f0add623c8141be64247eae46967e49fff | |
| parent | 1043b58c164ac48757cdb373967ead2b34aa7388 (diff) | |
| download | sourcewatch-990f6e2aacbbb6869259390d973fde30fac13501.tar.gz sourcewatch-990f6e2aacbbb6869259390d973fde30fac13501.zip | |
Add progress logging for initial sync
- Log start of sync with source directory
- Print progress every 1000 files during sync
- Log completion with stats (files, dirs, skipped, errors) and elapsed time
- Print 'watcher: ready' when monitoring begins
- Exit cleanly on dry-run
| -rw-r--r-- | main.go | 7 | ||||
| -rw-r--r-- | sync.go | 38 |
2 files changed, 44 insertions, 1 deletions
@@ -32,6 +32,13 @@ func main() { log.Fatalf("initial sync failed: %v", err) } + if *dryRun { + log.Println("dry-run complete, exiting") + return + } + + log.Println("watcher: ready, monitoring for changes ...") + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() @@ -1,7 +1,9 @@ package main import ( + "fmt" "io" + "log" "os" "path/filepath" "time" @@ -18,12 +20,25 @@ type Manifest struct { Files map[string]FileMeta } +type syncStats struct { + files int + dirs int + skipped int + errors int +} + func initialSync(hostDir, dataDir string, stack *GitignoreStack, dryRun bool) (*Manifest, error) { manifest := &Manifest{Files: make(map[string]FileMeta)} + stats := &syncStats{} + start := time.Now() + + log.Printf("initial sync: scanning %s ...", hostDir) err := filepath.Walk(hostDir, func(path string, info os.FileInfo, err error) error { if err != nil { - return err + stats.errors++ + logError("walk", path, err) + return nil } relPath, err := filepath.Rel(hostDir, path) @@ -47,18 +62,30 @@ func initialSync(hostDir, dataDir string, stack *GitignoreStack, dryRun bool) (* } if stack.IsIgnored(relPath) { + stats.skipped++ if info.IsDir() { return filepath.SkipDir } return nil } + if info.IsDir() { + stats.dirs++ + } else { + stats.files++ + } + + if stats.files%1000 == 0 && stats.files > 0 { + fmt.Fprintf(os.Stderr, "\r synced %d files, %d dirs ...", stats.files, stats.dirs) + } + destPath := filepath.Join(dataDir, relPath) linkTarget := "" if info.Mode()&os.ModeSymlink != 0 { linkTarget, err = os.Readlink(path) if err != nil { + stats.errors++ logError("readlink", relPath, err) return nil } @@ -78,29 +105,38 @@ func initialSync(hostDir, dataDir string, stack *GitignoreStack, dryRun bool) (* if info.IsDir() { if err := os.MkdirAll(destPath, info.Mode()); err != nil { + stats.errors++ logError("mkdir", relPath, err) } return nil } if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil { + stats.errors++ logError("mkdir", filepath.Dir(relPath), err) return nil } if linkTarget != "" { if err := os.Symlink(linkTarget, destPath); err != nil { + stats.errors++ logError("symlink", relPath, err) } return nil } if err := copyFileWithRetry(path, destPath, info.Mode()); err != nil { + stats.errors++ logError("copy", relPath, err) } return nil }) + elapsed := time.Since(start) + fmt.Fprintf(os.Stderr, "\r") + log.Printf("initial sync: done in %s — %d files, %d dirs, %d skipped, %d errors", + elapsed.Round(time.Millisecond), stats.files, stats.dirs, stats.skipped, stats.errors) + return manifest, err } |
