22
33use std:: {
44 env,
5- io:: BufRead ,
5+ io:: { BufRead , Write , stdout } ,
66 path:: PathBuf ,
77 sync:: { Arc , Mutex } ,
88} ;
@@ -147,21 +147,21 @@ impl RestClient {
147147 if feedback_inputs. step_summary {
148148 self . client . append_step_summary ( & summary) ?;
149149 }
150- if let Some ( summary_output_file) = feedback_inputs. summary_output_file {
150+ if let Some ( summary_output_file) = & feedback_inputs. summary_output_file {
151151 let output_file = if summary_output_file. is_absolute ( ) {
152152 summary_output_file
153153 } else {
154- feedback_inputs. repo_root . join ( & summary_output_file)
154+ & feedback_inputs. repo_root . join ( summary_output_file)
155155 } ;
156156 if let Some ( parent) = output_file. parent ( ) {
157157 std:: fs:: create_dir_all ( parent) . map_err ( |e| ClientError :: MkDirFailed {
158158 file_path : output_file. clone ( ) ,
159159 source : e,
160160 } ) ?;
161161 }
162- std:: fs:: write ( & output_file, & summary) . map_err ( |e| {
162+ std:: fs:: write ( output_file, & summary) . map_err ( |e| {
163163 ClientError :: SummaryOutputFileWriteFailed {
164- file_path : output_file,
164+ file_path : output_file. to_owned ( ) ,
165165 source : e,
166166 }
167167 } ) ?;
@@ -184,35 +184,6 @@ impl RestClient {
184184 ] ;
185185 self . client . write_output_variables ( & output_vars) ?;
186186
187- if feedback_inputs. thread_comments != ThreadComments :: Off {
188- // post thread comment for PR or push event
189- if comment. as_ref ( ) . is_none_or ( |c| c. len ( ) > u16:: MAX as usize ) {
190- comment = Some ( Self :: make_comment (
191- files,
192- format_checks_failed,
193- tidy_checks_failed,
194- & clang_versions,
195- Some ( u16:: MAX as u64 ) ,
196- ) ?) ;
197- }
198- let options = ThreadCommentOptions {
199- policy : if feedback_inputs. thread_comments == ThreadComments :: Update {
200- CommentPolicy :: Update
201- } else {
202- // feedback_inputs.thread_comments is not Off and not Update, so it must be just On.
203- CommentPolicy :: Anew
204- } ,
205- comment : comment. unwrap_or_default ( ) ,
206- kind : if format_checks_failed == 0 && tidy_checks_failed == 0 {
207- CommentKind :: Lgtm
208- } else {
209- CommentKind :: Concerns
210- } ,
211- marker : COMMENT_MARKER . to_string ( ) ,
212- no_lgtm : feedback_inputs. no_lgtm ,
213- } ;
214- self . client . post_thread_comment ( options) . await ?;
215- }
216187 if self . client . is_pr_event ( ) && feedback_inputs. pr_review {
217188 let summary_only = [ "true" , "on" , "1" ] . contains (
218189 & env:: var ( "CPP_LINTER_PR_REVIEW_SUMMARY_ONLY" )
@@ -230,6 +201,7 @@ impl RestClient {
230201 & feedback_inputs. repo_root ,
231202 ) ?;
232203 }
204+ self . show_patch ( & feedback_inputs) ?;
233205
234206 let mut options = ReviewOptions {
235207 marker : COMMENT_MARKER . to_string ( ) ,
@@ -267,32 +239,37 @@ impl RestClient {
267239 . map_err ( |e| ClientError :: MutexPoisoned ( e. to_string ( ) ) ) ?;
268240 file. maybe_append_patch ( & feedback_inputs. repo_root ) ?;
269241 }
242+ self . show_patch ( & feedback_inputs) ?;
270243 }
271- let auto_fix_patch_path = feedback_inputs
272- . repo_root
273- . join ( ClangParams :: CACHE_DIR )
274- . join ( ClangParams :: AUTO_FIX_PATCH ) ;
275- if let Ok ( patch_file) = std:: fs:: File :: open ( & auto_fix_patch_path) {
276- self . client . write_output_variables ( & [ OutputVariable {
277- name : "fix-patch-path" . to_string ( ) ,
278- value : auto_fix_patch_path. to_string_lossy ( ) . replace ( "\\ " , "/" ) ,
279- } ] ) ?;
280244
281- log:: info!( "Generated patch content:" ) ;
282- let mut reader = std:: io:: BufReader :: new ( patch_file) ;
283- let mut line_buf = String :: new ( ) ;
284- while let Ok ( bytes_read) = reader. read_line ( & mut line_buf)
285- && bytes_read > 0
286- {
287- if line_buf. starts_with ( '+' ) {
288- print ! ( "{}" , line_buf. green( ) ) ; // Green for additions
289- } else if line_buf. starts_with ( '-' ) {
290- print ! ( "{}" , line_buf. red( ) ) ; // Red for deletions
291- } else {
292- print ! ( "{line_buf}" ) ; // Default style for context lines
293- }
294- line_buf. clear ( ) ;
245+ if feedback_inputs. thread_comments != ThreadComments :: Off {
246+ // post thread comment for PR or push event
247+ if comment. as_ref ( ) . is_none_or ( |c| c. len ( ) > u16:: MAX as usize ) {
248+ comment = Some ( Self :: make_comment (
249+ files,
250+ format_checks_failed,
251+ tidy_checks_failed,
252+ & clang_versions,
253+ Some ( u16:: MAX as u64 ) ,
254+ ) ?) ;
295255 }
256+ let options = ThreadCommentOptions {
257+ policy : if feedback_inputs. thread_comments == ThreadComments :: Update {
258+ CommentPolicy :: Update
259+ } else {
260+ // feedback_inputs.thread_comments is not Off and not Update, so it must be just On.
261+ CommentPolicy :: Anew
262+ } ,
263+ comment : comment. unwrap_or_default ( ) ,
264+ kind : if format_checks_failed == 0 && tidy_checks_failed == 0 {
265+ CommentKind :: Lgtm
266+ } else {
267+ CommentKind :: Concerns
268+ } ,
269+ marker : COMMENT_MARKER . to_string ( ) ,
270+ no_lgtm : feedback_inputs. no_lgtm ,
271+ } ;
272+ self . client . post_thread_comment ( options) . await ?;
296273 }
297274 Ok ( format_checks_failed + tidy_checks_failed)
298275 }
@@ -427,6 +404,50 @@ impl RestClient {
427404 comment. push_str ( USER_OUTREACH ) ;
428405 Ok ( comment)
429406 }
407+
408+ /// Show the generated patch content in the console output.
409+ ///
410+ /// And also write the patch path to the output variable `fix-patch-path` for CI platforms.
411+ fn show_patch ( & self , feedback_inputs : & FeedbackInput ) -> Result < ( ) , ClientError > {
412+ let auto_fix_patch_path = feedback_inputs
413+ . repo_root
414+ . join ( ClangParams :: CACHE_DIR )
415+ . join ( ClangParams :: AUTO_FIX_PATCH ) ;
416+ if let Ok ( patch_file) = std:: fs:: File :: open ( & auto_fix_patch_path) {
417+ self . client . write_output_variables ( & [ OutputVariable {
418+ name : "fix-patch-path" . to_string ( ) ,
419+ value : auto_fix_patch_path. to_string_lossy ( ) . replace ( "\\ " , "/" ) ,
420+ } ] ) ?;
421+
422+ log:: info!( "Generated patch content:" ) ;
423+ let stdout_handle = stdout ( ) ;
424+ let mut reader = std:: io:: BufReader :: new ( patch_file) ;
425+ let mut line_buf = String :: new ( ) ;
426+ let mut stdout_lock = stdout_handle. lock ( ) ;
427+ while let Ok ( bytes_read) = reader. read_line ( & mut line_buf)
428+ && bytes_read > 0
429+ {
430+ if line_buf. starts_with ( '+' ) {
431+ // Green for additions
432+ stdout_lock
433+ . write_all ( line_buf. green ( ) . to_string ( ) . as_bytes ( ) )
434+ . map_err ( ClientError :: StdoutWriteFailed ) ?;
435+ } else if line_buf. starts_with ( '-' ) {
436+ // Red for deletions
437+ stdout_lock
438+ . write_all ( line_buf. red ( ) . to_string ( ) . as_bytes ( ) )
439+ . map_err ( ClientError :: StdoutWriteFailed ) ?;
440+ } else {
441+ // Default style for context lines
442+ stdout_lock
443+ . write_all ( line_buf. as_bytes ( ) )
444+ . map_err ( ClientError :: StdoutWriteFailed ) ?;
445+ }
446+ line_buf. clear ( ) ;
447+ }
448+ }
449+ Ok ( ( ) )
450+ }
430451}
431452
432453/// A closing tag for details blocks in markdown comments.
0 commit comments