11"""A Typer CLI for CPPython interfacing"""
22
3+ import contextlib
4+ from collections .abc import Generator
35from importlib .metadata import entry_points
46from pathlib import Path
57from typing import Annotated
68
79import typer
810from rich import print
11+ from rich .console import Console
912from rich .syntax import Syntax
1013
1114from cppython .configuration import ConfigurationLoader
1215from cppython .console .schema import ConsoleConfiguration , ConsoleInterface
1316from cppython .core .schema import PluginReport , ProjectConfiguration
1417from cppython .project import Project
18+ from cppython .utility .output import OutputSession
1519
1620app = typer .Typer (no_args_is_help = True )
1721
2529app .add_typer (list_app , name = 'list' )
2630
2731
28- def get_enabled_project (context : typer .Context ) -> Project :
29- """Helper to load and validate an enabled Project from CLI context."""
32+ def _get_configuration (context : typer .Context ) -> ConsoleConfiguration :
33+ """Extract the ConsoleConfiguration object from the CLI context.
34+
35+ Raises:
36+ ValueError: If the configuration object is missing
37+ """
3038 configuration = context .find_object (ConsoleConfiguration )
3139 if configuration is None :
3240 raise ValueError ('The configuration object is missing' )
41+ return configuration
42+
43+
44+ def get_enabled_project (context : typer .Context ) -> Project :
45+ """Helper to load and validate an enabled Project from CLI context."""
46+ configuration = _get_configuration (context )
3347
3448 # Use ConfigurationLoader to load and merge all configuration sources
3549 loader = ConfigurationLoader (configuration .project_configuration .project_root )
@@ -47,6 +61,23 @@ def get_enabled_project(context: typer.Context) -> Project:
4761 return project
4862
4963
64+ @contextlib .contextmanager
65+ def _session_project (context : typer .Context ) -> Generator [Project ]:
66+ """Create an enabled Project wrapped in an OutputSession.
67+
68+ Yields the project with its session already attached. The session
69+ (spinner + log file) is torn down when the ``with`` block exits.
70+ """
71+ project = get_enabled_project (context )
72+ configuration = _get_configuration (context )
73+ verbose = configuration .project_configuration .verbosity > 0
74+ console = Console (width = 120 )
75+
76+ with OutputSession (console , verbose = verbose ) as session :
77+ project .session = session
78+ yield project
79+
80+
5081def _parse_groups_argument (groups : str | None ) -> list [str ] | None :
5182 """Parse pip-style dependency groups from command argument.
5283
@@ -211,12 +242,10 @@ def install(
211242 Raises:
212243 ValueError: If the configuration object is missing
213244 """
214- project = get_enabled_project (context )
215-
216- # Parse groups from pip-style syntax
217245 group_list = _parse_groups_argument (groups )
218246
219- project .install (groups = group_list )
247+ with _session_project (context ) as project :
248+ project .install (groups = group_list )
220249
221250
222251@app .command ()
@@ -239,12 +268,10 @@ def update(
239268 Raises:
240269 ValueError: If the configuration object is missing
241270 """
242- project = get_enabled_project (context )
243-
244- # Parse groups from pip-style syntax
245271 group_list = _parse_groups_argument (groups )
246272
247- project .update (groups = group_list )
273+ with _session_project (context ) as project :
274+ project .update (groups = group_list )
248275
249276
250277@list_app .command ()
@@ -295,8 +322,8 @@ def publish(
295322 Raises:
296323 ValueError: If the configuration object is missing
297324 """
298- project = get_enabled_project (context )
299- project .publish ()
325+ with _session_project (context ) as project :
326+ project .publish ()
300327
301328
302329@app .command ()
@@ -315,8 +342,8 @@ def build(
315342 context: The CLI configuration object
316343 configuration: Optional named configuration
317344 """
318- project = get_enabled_project (context )
319- project .build (configuration = configuration )
345+ with _session_project (context ) as project :
346+ project .build (configuration = configuration )
320347
321348
322349@app .command ()
@@ -335,8 +362,8 @@ def test(
335362 context: The CLI configuration object
336363 configuration: Optional named configuration
337364 """
338- project = get_enabled_project (context )
339- project .test (configuration = configuration )
365+ with _session_project (context ) as project :
366+ project .test (configuration = configuration )
340367
341368
342369@app .command ()
@@ -355,8 +382,8 @@ def bench(
355382 context: The CLI configuration object
356383 configuration: Optional named configuration
357384 """
358- project = get_enabled_project (context )
359- project .bench (configuration = configuration )
385+ with _session_project (context ) as project :
386+ project .bench (configuration = configuration )
360387
361388
362389@app .command ()
@@ -380,5 +407,5 @@ def run(
380407 target: The name of the build target to run
381408 configuration: Optional named configuration
382409 """
383- project = get_enabled_project (context )
384- project .run (target , configuration = configuration )
410+ with _session_project (context ) as project :
411+ project .run (target , configuration = configuration )
0 commit comments