5
5
from typing import Dict
6
6
from typing import Generator
7
7
from typing import List
8
+ from typing import Union
8
9
9
10
import attr
10
11
import click
16
17
from _pytask .outcomes import TaskOutcome
17
18
from _pytask .report import CollectionReport
18
19
from _pytask .report import ExecutionReport
20
+ from _pytask .session import Session
19
21
from _pytask .shared import get_first_non_none_value
20
22
from rich .live import Live
21
23
from rich .status import Status
24
+ from rich .style import Style
22
25
from rich .table import Table
23
26
from rich .text import Text
24
27
@@ -83,10 +86,16 @@ def pytask_post_parse(config: dict[str, Any]) -> None:
83
86
config ["verbose" ],
84
87
config ["editor_url_scheme" ],
85
88
)
86
- config ["pm" ].register (live_execution )
89
+ config ["pm" ].register (live_execution , "live_execution" )
87
90
88
91
live_collection = LiveCollection (live_manager )
89
- config ["pm" ].register (live_collection )
92
+ config ["pm" ].register (live_collection , "live_collection" )
93
+
94
+
95
+ @hookimpl (tryfirst = True )
96
+ def pytask_execute_build (session : Session ) -> None :
97
+ live_execution = session .config ["pm" ].get_plugin ("live_execution" )
98
+ live_execution ._n_tasks = len (session .tasks )
90
99
91
100
92
101
@attr .s (eq = False )
@@ -148,6 +157,7 @@ class LiveExecution:
148
157
_editor_url_scheme = attr .ib (type = str )
149
158
_running_tasks = attr .ib (factory = dict , type = Dict [str , Task ])
150
159
_reports = attr .ib (factory = list , type = List [Dict [str , Any ]])
160
+ _n_tasks = attr .ib (default = "x" , type = Union [int , str ])
151
161
152
162
@hookimpl (hookwrapper = True )
153
163
def pytask_execute_build (self ) -> Generator [None , None , None ]:
@@ -156,7 +166,9 @@ def pytask_execute_build(self) -> Generator[None, None, None]:
156
166
self ._live_manager .start ()
157
167
yield
158
168
self ._live_manager .stop (transient = True )
159
- table = self ._generate_table (reduce_table = False , sort_table = True )
169
+ table = self ._generate_table (
170
+ reduce_table = False , sort_table = True , add_caption = False
171
+ )
160
172
if table is not None :
161
173
console .print (table )
162
174
@@ -172,7 +184,9 @@ def pytask_execute_task_log_end(self, report: ExecutionReport) -> bool:
172
184
self .update_reports (report )
173
185
return True
174
186
175
- def _generate_table (self , reduce_table : bool , sort_table : bool ) -> Table | None :
187
+ def _generate_table (
188
+ self , reduce_table : bool , sort_table : bool , add_caption : bool
189
+ ) -> Table | None :
176
190
"""Generate the table.
177
191
178
192
First, display all completed tasks and, then, all running tasks.
@@ -210,7 +224,19 @@ def _generate_table(self, reduce_table: bool, sort_table: bool) -> Table | None:
210
224
relevant_reports , key = lambda report : report ["name" ]
211
225
)
212
226
213
- table = Table ()
227
+ if add_caption :
228
+ caption_kwargs = {
229
+ "caption" : Text (
230
+ f"Completed: { len (self ._reports )} /{ self ._n_tasks } " ,
231
+ style = Style (dim = True , italic = False ),
232
+ ),
233
+ "caption_justify" : "right" ,
234
+ "caption_style" : None ,
235
+ }
236
+ else :
237
+ caption_kwargs = {}
238
+
239
+ table = Table (** caption_kwargs )
214
240
table .add_column ("Task" , overflow = "fold" )
215
241
table .add_column ("Outcome" )
216
242
for report in relevant_reports :
@@ -237,10 +263,15 @@ def _generate_table(self, reduce_table: bool, sort_table: bool) -> Table | None:
237
263
return table
238
264
239
265
def _update_table (
240
- self , reduce_table : bool = True , sort_table : bool = False
266
+ self ,
267
+ reduce_table : bool = True ,
268
+ sort_table : bool = False ,
269
+ add_caption : bool = True ,
241
270
) -> None :
242
271
"""Regenerate the table."""
243
- table = self ._generate_table (reduce_table = reduce_table , sort_table = sort_table )
272
+ table = self ._generate_table (
273
+ reduce_table = reduce_table , sort_table = sort_table , add_caption = add_caption
274
+ )
244
275
self ._live_manager .update (table )
245
276
246
277
def update_running_tasks (self , new_running_task : Task ) -> None :
0 commit comments