diff --git a/changelog.md b/changelog.md index db6cd37..62226b6 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog +# Pending + +- Allow passing configuration(s) directly to `@app.command()` + # v0.2.1 - 11-05-2023 - Fix un-allowed kwargs: accepted signatures are `fn(paramA, paramB=..., ... **kwargs)` diff --git a/confit/cli.py b/confit/cli.py index 13f34f9..e34ad26 100644 --- a/confit/cli.py +++ b/confit/cli.py @@ -1,5 +1,6 @@ import inspect import sys +import tempfile from pathlib import Path from typing import Any, Callable, Dict, List, Optional, Type, Union @@ -76,6 +77,7 @@ def command( # noqa # Rich settings rich_help_panel: Union[str, None] = Default(None), registry: Any = None, + config: Optional[Union[Config, List[Config]]] = None, ) -> Callable[[CommandFunctionType], CommandFunctionType]: typer_command = super().command( name=name, @@ -96,14 +98,35 @@ def command( # noqa }, ) + initial_config = config + def wrapper(fn): validated = validate_arguments(fn) @typer_command def command(ctx: Context, config: Optional[List[Path]] = None): - config_path = config + config_path = config or [] has_meta = _fn_has_meta(fn) + + if initial_config is not None: + initial_configs = ( + [initial_config] + if isinstance(initial_config, Config) + else initial_config + ) + + initial_config_path = [] + + for c in initial_configs: + temp_file = tempfile.NamedTemporaryFile(delete=False) + temp_file.write( + c.to_str().encode() + ) # Write the string to the file + temp_file.close() + initial_config_path.append(Path(temp_file.name)) + config_path = initial_config_path + config_path + if config_path: config, name_from_file = merge_from_disk(config_path) else: diff --git a/tests/test_cli.py b/tests/test_cli.py index 40af076..394b010 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2,7 +2,7 @@ from typer.testing import CliRunner -from confit import Cli, Registry +from confit import Cli, Config, Registry from confit.registry import RegistryCollection, set_default_registry runner = CliRunner() @@ -94,6 +94,56 @@ def test_cli_merge(change_test_dir): assert "Other: 99" in result.stdout +app_with_initial_config = Cli(pretty_exceptions_show_locals=False) +initial_config = [ + Config( + { + "modelA": { + "submodel": { + "value": 1, + } + }, + "script": { + "other": 4, + }, + } + ), + Config( + { + "script": { + "other": 5, + }, + } + ), +] + + +@app_with_initial_config.command(name="script", config=initial_config) +def app_with_initial_config_function( + modelA: BigModel, + modelB: BigModel, + other: int, + seed: int, +): + assert modelA.submodel is modelB.submodel + assert modelA.submodel.value == 12 # --config has precedent over initial_config + assert other == 5 # initial_config[-1] has precedent over initial_config[0] + + +def test_cli_working_with_initial_config(change_test_dir): + result = runner.invoke( + app_with_initial_config, + [ + "--config", + "config.cfg", + "--seed", + "42", + ], + ) + print(result.exit_code) + assert result.exit_code == 0, result.stdout + + app_with_meta = Cli(pretty_exceptions_show_locals=False)