diff --git a/internal/command/progress.go b/internal/command/progress.go index ebe9874..e2e4182 100644 --- a/internal/command/progress.go +++ b/internal/command/progress.go @@ -135,9 +135,28 @@ type progressOperation struct { mu sync.Mutex lineOpen bool + paused bool err error } +func (op *progressOperation) pause() { + if op == nil || !op.enabled || !op.terminal { + return + } + op.mu.Lock() + defer op.mu.Unlock() + op.paused = true +} + +func (op *progressOperation) resume() { + if op == nil || !op.enabled || !op.terminal { + return + } + op.mu.Lock() + defer op.mu.Unlock() + op.paused = false +} + func (op *progressOperation) Complete(message string) error { if op == nil || !op.enabled { return nil @@ -186,7 +205,7 @@ func (op *progressOperation) runTicker() { func (op *progressOperation) writeDot() { op.mu.Lock() defer op.mu.Unlock() - if op.err != nil { + if op.err != nil || op.paused { return } _, err := fmt.Fprint(op.writer, ".") diff --git a/internal/command/progress_test.go b/internal/command/progress_test.go index 441128f..5c3b94f 100644 --- a/internal/command/progress_test.go +++ b/internal/command/progress_test.go @@ -107,6 +107,36 @@ func TestProgressReporterTTYDotsAndCompletion(t *testing.T) { } } +func TestProgressReporterPausesAndResumesTTYDots(t *testing.T) { + var out lockedBuffer + ticker := newFakeProgressTicker() + reporter := newProgressReporter(&out, false) + reporter.isTerminal = func(io.Writer) bool { return true } + reporter.newTicker = func(time.Duration) progressTicker { return ticker } + + op, err := reporter.Start("Braid: pushing mirror vendor/basic") + if err != nil { + t.Fatalf("Start returned error: %v", err) + } + op.pause() + op.writeDot() + if got, want := out.String(), "Braid: pushing mirror vendor/basic"; got != want { + t.Fatalf("paused progress output = %q, want %q", got, want) + } + op.resume() + ticker.ch <- time.Now() + waitForProgressOutput(t, &out, ".") + if err := op.Complete("Braid: pushed mirror vendor/basic"); err != nil { + t.Fatalf("Complete returned error: %v", err) + } + + got := out.String() + want := "Braid: pushing mirror vendor/basic.\nBraid: pushed mirror vendor/basic\n" + if got != want { + t.Fatalf("progress output = %q, want %q", got, want) + } +} + func TestProgressSeparatedWriterBreaksOpenTTYLine(t *testing.T) { var out lockedBuffer ticker := newFakeProgressTicker() diff --git a/internal/command/push.go b/internal/command/push.go index 7ef3480..7229d91 100644 --- a/internal/command/push.go +++ b/internal/command/push.go @@ -418,9 +418,11 @@ func (h PushHandler) pushViaTempRepo(ctx context.Context, repo RepoContext, sour if err := verifyTempPushIndex(ctx, tempGit, newTree); err != nil { return err } + pushProgress.pause() if err := tempGit.CommitVerboseMessageFile(ctx, seedPath, stdin, stdout, stderr); err != nil { return err } + pushProgress.resume() } else { var provenanceTemplate pushProvenanceTemplate if provenanceOK { @@ -435,11 +437,17 @@ func (h PushHandler) pushViaTempRepo(ctx context.Context, repo RepoContext, sour return err } if templatePath != "" { + pushProgress.pause() if err := tempGit.CommitVerboseMessageFile(ctx, templatePath, stdin, stdout, stderr); err != nil { return err } - } else if err := tempGit.CommitVerbose(ctx, stdin, stdout, stderr); err != nil { - return err + pushProgress.resume() + } else { + pushProgress.pause() + if err := tempGit.CommitVerbose(ctx, stdin, stdout, stderr); err != nil { + return err + } + pushProgress.resume() } } lease := "--force-with-lease=refs/heads/" + branch + ":" + expectedOld