@@ -3049,34 +3049,47 @@ class CaptureTerminalConsole(TerminalConsole):
30493049 def __init__ (self , console : t .Optional [RichConsole ] = None , ** kwargs : t .Any ) -> None :
30503050 super ().__init__ (console = console , ** kwargs )
30513051 self ._captured_outputs : t .List [str ] = []
3052+ self ._warnings : t .List [str ] = []
30523053 self ._errors : t .List [str ] = []
30533054
30543055 @property
30553056 def captured_output (self ) -> str :
30563057 return "" .join (self ._captured_outputs )
30573058
3059+ @property
3060+ def captured_warnings (self ) -> str :
3061+ return "" .join (self ._warnings )
3062+
30583063 @property
30593064 def captured_errors (self ) -> str :
30603065 return "" .join (self ._errors )
30613066
30623067 def consume_captured_output (self ) -> str :
3063- output = self .captured_output
3064- self .clear_captured_outputs ()
3065- return output
3068+ try :
3069+ return self .captured_output
3070+ finally :
3071+ self ._captured_outputs = []
30663072
3067- def consume_captured_errors (self ) -> str :
3068- errors = self .captured_errors
3069- self .clear_captured_errors ()
3070- return errors
3073+ def consume_captured_warnings (self ) -> str :
3074+ try :
3075+ return self .captured_warnings
3076+ finally :
3077+ self ._warnings = []
30713078
3072- def clear_captured_outputs (self ) -> None :
3073- self ._captured_outputs = []
3079+ def consume_captured_errors (self ) -> str :
3080+ try :
3081+ return self .captured_errors
3082+ finally :
3083+ self ._errors = []
30743084
3075- def clear_captured_errors (self ) -> None :
3076- self ._errors = []
3085+ def log_warning (self , short_message : str , long_message : t .Optional [str ] = None ) -> None :
3086+ if short_message not in self ._warnings :
3087+ self ._warnings .append (short_message )
3088+ super ().log_warning (short_message , long_message )
30773089
30783090 def log_error (self , message : str ) -> None :
3079- self ._errors .append (message )
3091+ if message not in self ._errors :
3092+ self ._errors .append (message )
30803093 super ().log_error (message )
30813094
30823095 def log_skipped_models (self , snapshot_names : t .Set [str ]) -> None :
@@ -3087,9 +3100,8 @@ def log_skipped_models(self, snapshot_names: t.Set[str]) -> None:
30873100 super ().log_skipped_models (snapshot_names )
30883101
30893102 def log_failed_models (self , errors : t .List [NodeExecutionFailedError ]) -> None :
3090- if errors :
3091- self ._errors .append ("\n " .join (str (ex ) for ex in errors ))
3092- super ().log_failed_models (errors )
3103+ self ._errors .extend ([str (ex ) for ex in errors if str (ex ) not in self ._errors ])
3104+ super ().log_failed_models (errors )
30933105
30943106 def _print (self , value : t .Any , ** kwargs : t .Any ) -> None :
30953107 with self .console .capture () as capture :
@@ -3110,6 +3122,11 @@ class MarkdownConsole(CaptureTerminalConsole):
31103122 AUDIT_PADDING = 7
31113123
31123124 def __init__ (self , ** kwargs : t .Any ) -> None :
3125+ self .alert_block_max_content_length = int (kwargs .pop ("alert_block_max_content_length" , 500 ))
3126+ self .alert_block_collapsible_threshold = int (
3127+ kwargs .pop ("alert_block_collapsible_threshold" , 200 )
3128+ )
3129+
31133130 super ().__init__ (
31143131 ** {** kwargs , "console" : RichConsole (no_color = True , width = kwargs .pop ("width" , None ))}
31153132 )
@@ -3434,18 +3451,40 @@ def show_linter_violations(
34343451 self ._print (msg )
34353452 self ._errors .append (msg )
34363453
3437- def log_error (self , message : str ) -> None :
3438- super ().log_error (f"```\n \\ [ERROR] { message } ```\n \n " )
3454+ @property
3455+ def captured_warnings (self ) -> str :
3456+ return self ._render_alert_block ("WARNING" , self ._warnings )
34393457
3440- def log_warning (self , short_message : str , long_message : t .Optional [str ] = None ) -> None :
3441- logger .warning (long_message or short_message )
3458+ @property
3459+ def captured_errors (self ) -> str :
3460+ return self ._render_alert_block ("CAUTION" , self ._errors )
34423461
3443- if not short_message .endswith ("\n " ):
3444- short_message += (
3445- "\n " # so that the closing ``` ends up on a newline which is important for GitHub
3446- )
3462+ def _render_alert_block (self , block_type : str , items : t .List [str ]) -> str :
3463+ # GitHub Markdown alert syntax, https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
3464+ if items :
3465+ item_contents = ""
3466+ list_indicator = "- " if len (items ) > 1 else ""
3467+
3468+ for item in items :
3469+ item = item .replace ("\n " , "\n > " )
3470+ item_contents += f"> { list_indicator } { item } \n "
3471+
3472+ if len (item_contents ) > self .alert_block_max_content_length :
3473+ truncation_msg = (
3474+ "...\n >\n > Truncated. Please check the console for full information.\n "
3475+ )
3476+ item_contents = item_contents [
3477+ 0 : self .alert_block_max_content_length - len (truncation_msg )
3478+ ]
3479+ item_contents += truncation_msg
3480+ break
3481+
3482+ if len (item_contents ) > self .alert_block_collapsible_threshold :
3483+ item_contents = f"> <details>\n { item_contents } > </details>"
3484+
3485+ return f"> [!{ block_type } ]\n { item_contents } \n "
34473486
3448- self . _print ( f"``` \n \\ [WARNING] { short_message } ``` \n \n " )
3487+ return ""
34493488
34503489 def _print (self , value : t .Any , ** kwargs : t .Any ) -> None :
34513490 self .console .print (value , ** kwargs )
@@ -3472,7 +3511,7 @@ def _print(self, value: t.Any, **kwargs: t.Any) -> None:
34723511 super ()._print (value , ** kwargs )
34733512 for captured_output in self ._captured_outputs :
34743513 print (captured_output )
3475- self .clear_captured_outputs ()
3514+ self .consume_captured_output ()
34763515
34773516 def _prompt (self , message : str , ** kwargs : t .Any ) -> t .Any :
34783517 self ._print (message )
0 commit comments