Add atomic writes, humanized sizes, debug logging, and -v/-q per-command
- Atomic writes for mfer gen: writes to temp file, renames on success, cleans up temp on error/interrupt. Prevents empty manifests on Ctrl-C. - Humanized byte sizes using dustin/go-humanize (e.g., "10 MiB" not "10485760") - Progress lines clear when done (using ANSI escape \r\033[K]) - Debug logging when files are added to manifest (mfer gen -vv) - Move -v/-q flags from global to per-command for better UX - Add tests for atomic write behavior with failing filesystem mock
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/urfave/cli/v2"
|
||||
"sneak.berlin/go/mfer/internal/checker"
|
||||
@@ -67,7 +68,7 @@ func (mfa *CLIApp) checkManifestOperation(ctx *cli.Context) error {
|
||||
return fmt.Errorf("failed to load manifest: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("manifest contains %d files, %d bytes", chk.FileCount(), chk.TotalBytes())
|
||||
log.Infof("manifest contains %d files, %s", chk.FileCount(), humanize.IBytes(uint64(chk.TotalBytes())))
|
||||
|
||||
// Set up results channel
|
||||
results := make(chan checker.Result, 1)
|
||||
@@ -79,17 +80,17 @@ func (mfa *CLIApp) checkManifestOperation(ctx *cli.Context) error {
|
||||
go func() {
|
||||
for status := range progress {
|
||||
if status.ETA > 0 {
|
||||
log.Progressf("Checking: %d/%d files, %.1f MB/s, ETA %s, %d failures",
|
||||
log.Progressf("Checking: %d/%d files, %s/s, ETA %s, %d failures",
|
||||
status.CheckedFiles,
|
||||
status.TotalFiles,
|
||||
status.BytesPerSec/1e6,
|
||||
humanize.IBytes(uint64(status.BytesPerSec)),
|
||||
status.ETA.Round(time.Second),
|
||||
status.Failures)
|
||||
} else {
|
||||
log.Progressf("Checking: %d/%d files, %.1f MB/s, %d failures",
|
||||
log.Progressf("Checking: %d/%d files, %s/s, %d failures",
|
||||
status.CheckedFiles,
|
||||
status.TotalFiles,
|
||||
status.BytesPerSec/1e6,
|
||||
humanize.IBytes(uint64(status.BytesPerSec)),
|
||||
status.Failures)
|
||||
}
|
||||
}
|
||||
@@ -141,11 +142,11 @@ func (mfa *CLIApp) checkManifestOperation(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
elapsed := time.Since(mfa.startupTime).Seconds()
|
||||
rate := float64(chk.TotalBytes()) / elapsed / 1e6
|
||||
rate := float64(chk.TotalBytes()) / elapsed
|
||||
if failures == 0 {
|
||||
log.Infof("checked %d files (%.1f MB) in %.1fs (%.1f MB/s): all OK", chk.FileCount(), float64(chk.TotalBytes())/1e6, elapsed, rate)
|
||||
log.Infof("checked %d files (%s) in %.1fs (%s/s): all OK", chk.FileCount(), humanize.IBytes(uint64(chk.TotalBytes())), elapsed, humanize.IBytes(uint64(rate)))
|
||||
} else {
|
||||
log.Infof("checked %d files (%.1f MB) in %.1fs (%.1f MB/s): %d failed", chk.FileCount(), float64(chk.TotalBytes())/1e6, elapsed, rate, failures)
|
||||
log.Infof("checked %d files (%s) in %.1fs (%s/s): %d failed", chk.FileCount(), humanize.IBytes(uint64(chk.TotalBytes())), elapsed, humanize.IBytes(uint64(rate)), failures)
|
||||
}
|
||||
|
||||
if failures > 0 {
|
||||
|
||||
Reference in New Issue
Block a user