Coverage for /usr/local/lib/python3.10/site-packages/opal_common-0.0.0-py3.10.egg/opal_common/confi/cli.py: 12%
37 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 11:54 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 11:54 +0000
1from typing import Callable, Dict, List
3import click
4import typer
5from opal_common.confi.types import ConfiEntry
6from typer.main import Typer
9def create_click_cli(confi_entries: Dict[str, ConfiEntry], callback: Callable):
10 cli = callback
11 for key, entry in confi_entries.items():
12 option_kwargs = entry.get_cli_option_kwargs()
13 # make the key fit cmd-style (i.e. kebab-case)
14 adjusted_key = entry.key.lower().replace("_", "-")
15 keys = [f"--{adjusted_key}", entry.key]
16 # add flag if given (i.e '-t' option)
17 if entry.flags is not None:
18 keys.extend(entry.flags)
19 # use lower case as the key, and as is (no prefix, and no case altering) as the name
20 # see https://click.palletsprojects.com/en/7.x/options/#name-your-options
21 cli = click.option(*keys, **option_kwargs)(cli)
22 # pass context
23 cli = click.pass_context(cli)
24 # wrap in group
25 cli = click.group(invoke_without_command=True)(cli)
26 return cli
29def get_cli_object_for_config_objects(
30 config_objects: list,
31 typer_app: Typer = None,
32 help: str = None,
33 on_start: Callable = None,
34):
35 # callback to save CLI results back to objects
36 def callback(ctx, **kwargs):
37 if callable(on_start):
38 on_start(ctx, **kwargs)
40 for key, value in kwargs.items():
41 # find the confi-object which the key belongs to and ...
42 for config_obj in config_objects:
43 if key in config_obj.entries:
44 # ... update that object with the new value
45 setattr(config_obj, key, value)
46 config_obj._entries[key].value = value
48 if help is not None:
49 callback.__doc__ = help
50 # Create a merged config-entires map
51 entries = {}
52 for config_obj in config_objects:
53 entries.update(config_obj.entries)
54 # convert to a click-cli group
55 click_group = create_click_cli(entries, callback)
56 # add the typer app into our click group
57 if typer_app is not None:
58 typer_click_object = typer.main.get_command(typer_app)
59 # add the app commands directly to out click app
60 for name, cmd in typer_click_object.commands.items():
61 click_group.add_command(cmd, name)
62 return click_group