@@ -56,29 +56,26 @@ def format(self, verbose: int = 1) -> str: # noqa: PLR0911
5656class TaskExplanation :
5757 """Represents the explanation for why a task needs to be executed."""
5858
59- task_name : str
60- would_execute : bool
61- outcome : TaskOutcome | None = None
6259 reasons : list [ChangeReason ] = field (factory = list )
6360
64- def format (self , verbose : int = 1 ) -> str :
61+ def format (self , task_name : str , outcome : TaskOutcome , verbose : int = 1 ) -> str :
6562 """Format the task explanation as a string."""
6663 lines = []
6764
68- if self . outcome == TaskOutcome .SKIP_UNCHANGED :
69- lines .append (f"{ self . task_name } " )
65+ if outcome == TaskOutcome .SKIP_UNCHANGED :
66+ lines .append (f"{ task_name } " )
7067 lines .append (" ✓ No changes detected" )
71- elif self . outcome == TaskOutcome .PERSISTENCE :
72- lines .append (f"{ self . task_name } " )
68+ elif outcome == TaskOutcome .PERSISTENCE :
69+ lines .append (f"{ task_name } " )
7370 lines .append (" • Persisted (products exist, changes ignored)" )
74- elif self . outcome == TaskOutcome .SKIP :
75- lines .append (f"{ self . task_name } " )
71+ elif outcome == TaskOutcome .SKIP :
72+ lines .append (f"{ task_name } " )
7673 lines .append (" • Skipped by marker" )
7774 elif not self .reasons :
78- lines .append (f"{ self . task_name } " )
75+ lines .append (f"{ task_name } " )
7976 lines .append (" ✓ No changes detected" )
8077 else :
81- lines .append (f"{ self . task_name } " )
78+ lines .append (f"{ task_name } " )
8279 lines .extend (reason .format (verbose ) for reason in self .reasons )
8380
8481 return "\n " .join (lines )
@@ -116,55 +113,73 @@ def pytask_execute_log_end(session: Session, reports: list[ExecutionReport]) ->
116113 console .rule (Text ("Explanation" , style = "bold blue" ), style = "bold blue" )
117114 console .print ()
118115
119- # Collect all explanations
120- explanations = [
121- report .task ._explanation
122- for report in reports
123- if hasattr (report .task , "_explanation" )
116+ # Collect all reports with explanations
117+ reports_with_explanations = [
118+ report for report in reports if "explanation" in report .task .attributes
124119 ]
125120
126- if not explanations :
121+ if not reports_with_explanations :
127122 console .print ("No tasks require execution - everything is up to date." )
128123 return
129124
130125 # Group by outcome
131- would_execute = [e for e in explanations if e .would_execute ]
126+ would_execute = [
127+ r
128+ for r in reports_with_explanations
129+ if r .outcome == TaskOutcome .WOULD_BE_EXECUTED
130+ ]
132131 skipped = [
133- e
134- for e in explanations
135- if not e .would_execute and e .outcome != TaskOutcome .SKIP_UNCHANGED
132+ r
133+ for r in reports_with_explanations
134+ if r .outcome in (TaskOutcome .SKIP , TaskOutcome .SKIP_PREVIOUS_FAILED )
135+ ]
136+ unchanged = [
137+ r for r in reports_with_explanations if r .outcome == TaskOutcome .SKIP_UNCHANGED
136138 ]
137- unchanged = [e for e in explanations if e .outcome == TaskOutcome .SKIP_UNCHANGED ]
138139
139140 verbose = session .config .get ("verbose" , 1 )
140141
141142 if would_execute :
142- # WOULD_BE_EXECUTED has style "success" in TaskOutcome
143- console .print (
143+ console .rule (
144144 Text (
145- "Tasks that would be executed: " ,
145+ "─── Tasks that would be executed" ,
146146 style = TaskOutcome .WOULD_BE_EXECUTED .style ,
147147 ),
148+ align = "left" ,
149+ style = TaskOutcome .WOULD_BE_EXECUTED .style ,
148150 )
149151 console .print ()
150- for exp in would_execute :
151- console .print (exp .format (verbose ))
152+ for report in would_execute :
153+ explanation = report .task .attributes ["explanation" ]
154+ console .print (explanation .format (report .task .name , report .outcome , verbose ))
152155 console .print ()
153156
154157 if skipped :
155- # SKIP has style "skipped" in TaskOutcome
156- console .print (Text ("Skipped tasks:" , style = TaskOutcome .SKIP .style ))
158+ console .rule (
159+ Text ("─── Skipped tasks" , style = TaskOutcome .SKIP .style ),
160+ align = "left" ,
161+ style = TaskOutcome .SKIP .style ,
162+ )
157163 console .print ()
158- for exp in skipped :
159- console .print (exp .format (verbose ))
164+ for report in skipped :
165+ explanation = report .task .attributes ["explanation" ]
166+ console .print (explanation .format (report .task .name , report .outcome , verbose ))
160167 console .print ()
161168
162169 if unchanged and verbose >= 2 : # noqa: PLR2004
163- # SKIP_UNCHANGED has style "success" in TaskOutcome
164- console .print (
165- Text ("Tasks with no changes:" , style = TaskOutcome .SKIP_UNCHANGED .style )
170+ console .rule (
171+ Text ("─── Tasks with no changes" , style = TaskOutcome .SKIP_UNCHANGED .style ),
172+ align = "left" ,
173+ style = TaskOutcome .SKIP_UNCHANGED .style ,
166174 )
167175 console .print ()
168- for exp in unchanged :
169- console .print (exp .format (verbose ))
176+ for report in unchanged :
177+ explanation = report .task .attributes ["explanation" ]
178+ console .print (explanation .format (report .task .name , report .outcome , verbose ))
170179 console .print ()
180+
181+ elif unchanged and verbose == 1 :
182+ console .print (
183+ f"{ len (unchanged )} task(s) with no changes (use -vv to show details)" ,
184+ highlight = False ,
185+ )
0 commit comments