@@ -2,10 +2,13 @@ use std::io::Write;
22
33use crate :: app:: ContextWithRepoRoot ;
44use crate :: services:: error:: ClassifiedError ;
5+ use crate :: services:: sync:: progress:: {
6+ IndicatifProgressReporter , NoopProgressReporter , ProgressReporter ,
7+ } ;
58use crate :: services:: sync:: render_sync;
69use crate :: services:: sync:: sync:: {
7- run_current_sync_with_progress_and_clock, NoopSyncProgressSink , SyncProgressClock ,
8- SyncProgressEvent , SyncProgressSink , SystemSyncProgressClock , TraceSyncError ,
10+ run_current_sync_with_progress_and_clock, SyncProgressClock , SystemSyncProgressClock ,
11+ TraceSyncError ,
912} ;
1013use crate :: services:: sync:: SyncRequest ;
1114
@@ -31,61 +34,6 @@ fn classify_sync_error(err: TraceSyncError) -> ClassifiedError {
3134 ClassifiedError :: runtime ( format ! ( "{err}" ) )
3235}
3336
34- struct StderrSyncProgressReporter < ' a , W > {
35- writer : & ' a mut W ,
36- }
37-
38- impl < ' a , W > StderrSyncProgressReporter < ' a , W > {
39- fn new ( writer : & ' a mut W ) -> Self {
40- Self { writer }
41- }
42- }
43-
44- impl < W > SyncProgressSink for StderrSyncProgressReporter < ' _ , W >
45- where
46- W : Write ,
47- {
48- fn report ( & mut self , event : SyncProgressEvent ) {
49- let _ = writeln ! ( self . writer, "{}" , format_progress_event( & event) ) ;
50- let _ = self . writer . flush ( ) ;
51- }
52- }
53-
54- fn format_progress_event ( event : & SyncProgressEvent ) -> String {
55- match event {
56- SyncProgressEvent :: Started { timestamp } => {
57- format ! ( "Starting Agent Trace sync at {timestamp}..." )
58- }
59- SyncProgressEvent :: BatchAccepted {
60- stream,
61- batch_rows,
62- uploaded,
63- cursor,
64- } => format ! (
65- "{stream}: uploaded batch of {batch_rows} rows ({uploaded} total, cursor {cursor})"
66- ) ,
67- SyncProgressEvent :: StreamCompleted {
68- stream,
69- uploaded,
70- cursor,
71- batches,
72- } if * batches == 0 => {
73- format ! ( "{stream}: complete - no new rows uploaded (cursor {cursor})" )
74- }
75- SyncProgressEvent :: StreamCompleted {
76- stream,
77- uploaded,
78- cursor,
79- batches,
80- } => format ! (
81- "{stream}: complete - {uploaded} rows uploaded in {batches} batches (cursor {cursor})"
82- ) ,
83- SyncProgressEvent :: Finished { timestamp } => {
84- format ! ( "Agent Trace sync finished at {timestamp}." )
85- }
86- }
87- }
88-
8937impl SyncCommand {
9038 #[ allow( dead_code) ]
9139 pub fn execute < C > ( & self , context : & C ) -> Result < String , ClassifiedError >
@@ -124,11 +72,16 @@ impl SyncCommand {
12472
12573 let report = match self . request . format {
12674 crate :: services:: output_format:: OutputFormat :: Text => {
127- let mut progress = StderrSyncProgressReporter :: new ( stderr) ;
128- run_current_sync_with_progress_and_clock ( & repo_root, & mut progress, clock)
75+ let mut progress = IndicatifProgressReporter :: new ( stderr) ;
76+ let result =
77+ run_current_sync_with_progress_and_clock ( & repo_root, & mut progress, clock) ;
78+ if result. is_ok ( ) {
79+ progress. finish_successfully ( ) ;
80+ }
81+ result
12982 }
13083 crate :: services:: output_format:: OutputFormat :: Json => {
131- let mut progress = NoopSyncProgressSink ;
84+ let mut progress = NoopProgressReporter ;
13285 run_current_sync_with_progress_and_clock ( & repo_root, & mut progress, clock)
13386 }
13487 }
@@ -138,38 +91,3 @@ impl SyncCommand {
13891 . map_err ( |error| ClassifiedError :: runtime ( format ! ( "{error:#}" ) ) )
13992 }
14093}
141-
142- #[ cfg( test) ]
143- mod tests {
144- use super :: * ;
145-
146- #[ test]
147- fn progress_reporter_writes_deterministic_text_lines_and_flushes_each_event ( ) {
148- let mut output = Vec :: new ( ) ;
149- let mut reporter = StderrSyncProgressReporter :: new ( & mut output) ;
150-
151- reporter. report ( SyncProgressEvent :: Started {
152- timestamp : "2026-01-02T03:04:05Z" . to_string ( ) ,
153- } ) ;
154- reporter. report ( SyncProgressEvent :: BatchAccepted {
155- stream : "messages" ,
156- batch_rows : 500 ,
157- uploaded : 500 ,
158- cursor : 500 ,
159- } ) ;
160- reporter. report ( SyncProgressEvent :: StreamCompleted {
161- stream : "parts" ,
162- uploaded : 0 ,
163- cursor : 12 ,
164- batches : 0 ,
165- } ) ;
166- reporter. report ( SyncProgressEvent :: Finished {
167- timestamp : "2026-01-02T03:04:06Z" . to_string ( ) ,
168- } ) ;
169-
170- assert_eq ! (
171- String :: from_utf8( output) . expect( "progress output should be UTF-8" ) ,
172- "Starting Agent Trace sync at 2026-01-02T03:04:05Z...\n messages: uploaded batch of 500 rows (500 total, cursor 500)\n parts: complete - no new rows uploaded (cursor 12)\n Agent Trace sync finished at 2026-01-02T03:04:06Z.\n "
173- ) ;
174- }
175- }
0 commit comments