|
| 1 | +import concurrent |
1 | 2 | import sys |
| 3 | +from contextlib import ExitStack |
2 | 4 |
|
3 | 5 | import asyncclick as click |
4 | | -from jumpstarter_cli_common.exceptions import handle_exceptions |
| 6 | +from anyio import create_task_group, get_cancelled_exc_class, run, to_thread |
| 7 | +from anyio.from_thread import BlockingPortal |
| 8 | +from jumpstarter_cli_common.exceptions import async_handle_exceptions, leaf_exceptions |
| 9 | +from jumpstarter_cli_common.signal import signal_handler |
5 | 10 |
|
6 | | -from jumpstarter.utils.env import env |
| 11 | +from jumpstarter.utils.env import env_async |
| 12 | + |
| 13 | + |
| 14 | +async def j_async(): |
| 15 | + @async_handle_exceptions |
| 16 | + async def cli(): |
| 17 | + async with BlockingPortal() as portal: |
| 18 | + with ExitStack() as stack: |
| 19 | + async with env_async(portal, stack) as client: |
| 20 | + async with client.log_stream_async(): |
| 21 | + await to_thread.run_sync(lambda: client.cli()(standalone_mode=False)) |
| 22 | + |
| 23 | + try: |
| 24 | + async with create_task_group() as tg: |
| 25 | + tg.start_soon(signal_handler, tg.cancel_scope) |
| 26 | + |
| 27 | + try: |
| 28 | + await cli() |
| 29 | + finally: |
| 30 | + tg.cancel_scope.cancel() |
| 31 | + |
| 32 | + except* click.ClickException as excgroup: |
| 33 | + for exc in leaf_exceptions(excgroup): |
| 34 | + exc.show() |
| 35 | + |
| 36 | + sys.exit(1) |
| 37 | + except* ( |
| 38 | + get_cancelled_exc_class(), |
| 39 | + concurrent.futures._base.CancelledError, |
| 40 | + ) as _: |
| 41 | + sys.exit(2) |
7 | 42 |
|
8 | 43 |
|
9 | 44 | def j(): |
10 | | - with env() as client: |
11 | | - |
12 | | - @handle_exceptions |
13 | | - def cli(): |
14 | | - with client.log_stream(): |
15 | | - client.cli()(standalone_mode=False) |
16 | | - |
17 | | - try: |
18 | | - cli() |
19 | | - except click.ClickException as e: |
20 | | - e.show() |
21 | | - sys.exit(1) |
| 45 | + run(j_async) |
22 | 46 |
|
23 | 47 |
|
24 | 48 | if __name__ == "__main__": |
|
0 commit comments