config-cli-gui 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.idea/runConfigurations/config_generate.xml +3 -3
- config_cli_gui-0.2.2/.idea/runConfigurations/example_project_cli.xml +24 -0
- config_cli_gui-0.2.2/.idea/runConfigurations/example_project_gui.xml +24 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/HISTORY.md +14 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/PKG-INFO +1 -1
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/config.yaml +2 -2
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/usage/config.md +5 -5
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui/_version.py +3 -3
- config_cli_gui-0.2.2/src/config_cli_gui/cli.py +147 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui/config.py +1 -1
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/PKG-INFO +1 -1
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/SOURCES.txt +4 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/cli/cli_example.py +11 -10
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/config/config_example.py +5 -5
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/core/base.py +7 -1
- config_cli_gui-0.2.2/tests/example_project/example.gpx +6042 -0
- config_cli_gui-0.2.2/tests/test_cli.py +157 -0
- config_cli_gui-0.2.0/src/config_cli_gui/cli.py +0 -179
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/FUNDING.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/actions/setup-environment/action.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/dependabot.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/init.sh +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/release_message.sh +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/update_funding.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/workflows/main.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/workflows/release.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.github/workflows/update_readme.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.gitignore +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.pre-commit-config.yaml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/.readthedocs.yaml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/LICENSE +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/Makefile +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/README.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/.nav.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/_static/img/favicon.png +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/_static/img/logo.png +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/css/custom.css +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/develop/contributing.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/develop/make_windows.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/develop/naming_convention.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/funding/funding.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/getting-started/install.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/getting-started/virtual-environment.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/index.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/docs/usage/cli.md +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/mkdocs.yml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/pyproject.toml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/scripts/show_filelist.ps1 +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/scripts/show_tree.ps1 +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/scripts/show_tree.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/scripts/update_readme.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/setup.cfg +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui/docs.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui/gui.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/dependency_links.txt +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/entry_points.txt +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/requires.txt +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/src/config_cli_gui.egg-info/top_level.txt +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/template.yml.url +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/__main__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/cli/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/cli/__main__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/config/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/core/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/core/logging.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/gui/__init__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/gui/__main__.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/gui/config.yaml +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/gui/gui_example.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/test_config_manager.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/test_docs.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/test_generic_cli.py +0 -0
- {config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/uv.lock +0 -0
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
<env name="PYTHONUNBUFFERED" value="1" />
|
|
9
9
|
</envs>
|
|
10
10
|
<option name="SDK_HOME" value="" />
|
|
11
|
-
<option name="WORKING_DIRECTORY" value="$
|
|
11
|
+
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
|
12
12
|
<option name="IS_MODULE_SDK" value="true" />
|
|
13
13
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
|
14
14
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
|
15
15
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
|
16
|
-
<option name="SCRIPT_NAME" value="
|
|
16
|
+
<option name="SCRIPT_NAME" value="example_project.config.config_example" />
|
|
17
17
|
<option name="PARAMETERS" value="" />
|
|
18
18
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
|
19
19
|
<option name="EMULATE_TERMINAL" value="false" />
|
|
20
|
-
<option name="MODULE_MODE" value="
|
|
20
|
+
<option name="MODULE_MODE" value="true" />
|
|
21
21
|
<option name="REDIRECT_INPUT" value="false" />
|
|
22
22
|
<option name="INPUT_FILE" value="" />
|
|
23
23
|
<method v="2" />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="example_project.cli" type="PythonConfigurationType" factoryName="Python">
|
|
3
|
+
<module name="config-cli-gui" />
|
|
4
|
+
<option name="ENV_FILES" value="" />
|
|
5
|
+
<option name="INTERPRETER_OPTIONS" value="" />
|
|
6
|
+
<option name="PARENT_ENVS" value="true" />
|
|
7
|
+
<envs>
|
|
8
|
+
<env name="PYTHONUNBUFFERED" value="1" />
|
|
9
|
+
</envs>
|
|
10
|
+
<option name="SDK_HOME" value="" />
|
|
11
|
+
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
|
12
|
+
<option name="IS_MODULE_SDK" value="true" />
|
|
13
|
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
|
14
|
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
|
15
|
+
<option name="SCRIPT_NAME" value="example_project.cli" />
|
|
16
|
+
<option name="PARAMETERS" value="--elevation --min_dist 77 --output outputfile.gpx tests/example_project/example.gpx" />
|
|
17
|
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
|
18
|
+
<option name="EMULATE_TERMINAL" value="false" />
|
|
19
|
+
<option name="MODULE_MODE" value="true" />
|
|
20
|
+
<option name="REDIRECT_INPUT" value="false" />
|
|
21
|
+
<option name="INPUT_FILE" value="" />
|
|
22
|
+
<method v="2" />
|
|
23
|
+
</configuration>
|
|
24
|
+
</component>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="example_project.gui" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
|
|
3
|
+
<module name="config-cli-gui" />
|
|
4
|
+
<option name="ENV_FILES" value="" />
|
|
5
|
+
<option name="INTERPRETER_OPTIONS" value="" />
|
|
6
|
+
<option name="PARENT_ENVS" value="true" />
|
|
7
|
+
<envs>
|
|
8
|
+
<env name="PYTHONUNBUFFERED" value="1" />
|
|
9
|
+
</envs>
|
|
10
|
+
<option name="SDK_HOME" value="" />
|
|
11
|
+
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
|
12
|
+
<option name="IS_MODULE_SDK" value="true" />
|
|
13
|
+
<option name="ADD_CONTENT_ROOTS" value="true" />
|
|
14
|
+
<option name="ADD_SOURCE_ROOTS" value="true" />
|
|
15
|
+
<option name="SCRIPT_NAME" value="example_project.gui" />
|
|
16
|
+
<option name="PARAMETERS" value="" />
|
|
17
|
+
<option name="SHOW_COMMAND_LINE" value="false" />
|
|
18
|
+
<option name="EMULATE_TERMINAL" value="false" />
|
|
19
|
+
<option name="MODULE_MODE" value="true" />
|
|
20
|
+
<option name="REDIRECT_INPUT" value="false" />
|
|
21
|
+
<option name="INPUT_FILE" value="" />
|
|
22
|
+
<method v="2" />
|
|
23
|
+
</configuration>
|
|
24
|
+
</component>
|
|
@@ -4,6 +4,20 @@ Changelog
|
|
|
4
4
|
|
|
5
5
|
(unreleased)
|
|
6
6
|
------------
|
|
7
|
+
- #9 cli: unittests. [Paul Magister]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
0.2.1 (2025-11-14)
|
|
11
|
+
------------------
|
|
12
|
+
- #9 Fix cli bugs: allow toggle or bool. [Paul Magister]
|
|
13
|
+
- #9 Fix cli bugs. [Paul Magister]
|
|
14
|
+
- #9 Fix problems and add ide configs. [Paul Magister]
|
|
15
|
+
- #9 fix cli_example.py. [Paul Magister]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
0.2.0 (2025-11-13)
|
|
19
|
+
------------------
|
|
20
|
+
- Docs: Update HISTORY.md for release 0.2.0. [Paul Magister]
|
|
7
21
|
- #9 fix posix path issue. [Paul Magister]
|
|
8
22
|
- #9 fix posix path issue. [Paul Magister]
|
|
9
23
|
|
|
@@ -42,7 +42,7 @@ gui:
|
|
|
42
42
|
misc:
|
|
43
43
|
# Color setting for the application | type=Color, default=#ff0000
|
|
44
44
|
some_color: '#ff0000'
|
|
45
|
-
# Date setting for the application | type=datetime, default=2025-
|
|
46
|
-
some_date: '2025-
|
|
45
|
+
# Date setting for the application | type=datetime, default=2025-12-31 10:30:45
|
|
46
|
+
some_date: '2025-12-31T10:30:45'
|
|
47
47
|
# Path to the file to use | type=PosixPath, default=some_file.txt
|
|
48
48
|
some_file: some_file.txt
|
|
@@ -39,9 +39,9 @@ The parameters in the cli category can be accessed via the command line interfac
|
|
|
39
39
|
|
|
40
40
|
## Category "misc"
|
|
41
41
|
|
|
42
|
-
| Name | Type | Description | Default
|
|
43
|
-
|
|
44
|
-
| some_file | PosixPath | Path to the file to use | PosixPath('some_file.txt')
|
|
45
|
-
| some_color | Color | Color setting for the application | Color(255, 0, 0)
|
|
46
|
-
| some_date | datetime | Date setting for the application | datetime.datetime(2025,
|
|
42
|
+
| Name | Type | Description | Default | Choices |
|
|
43
|
+
|------------|-----------|-----------------------------------|---------------------------------------------|---------|
|
|
44
|
+
| some_file | PosixPath | Path to the file to use | PosixPath('some_file.txt') | - |
|
|
45
|
+
| some_color | Color | Color setting for the application | Color(255, 0, 0) | - |
|
|
46
|
+
| some_date | datetime | Date setting for the application | datetime.datetime(2025, 12, 31, 10, 30, 45) | - |
|
|
47
47
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
31
|
+
__version__ = version = '0.2.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 2)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g965db4933'
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# config_cli_gui/cli_example.py
|
|
2
|
+
"""Generic CLI generator for configuration framework."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import traceback
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from config_cli_gui.config import ConfigManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def str2bool(v: str):
|
|
13
|
+
if isinstance(v, bool):
|
|
14
|
+
return v
|
|
15
|
+
if v.lower() in ("yes", "true", "t", "1"):
|
|
16
|
+
return True
|
|
17
|
+
if v.lower() in ("no", "false", "f", "0"):
|
|
18
|
+
return False
|
|
19
|
+
raise argparse.ArgumentTypeError("Boolean value expected.")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ToggleOrBool(argparse.Action):
|
|
23
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
24
|
+
if values is None:
|
|
25
|
+
# toggle mode
|
|
26
|
+
current = getattr(namespace, self.dest, None)
|
|
27
|
+
default = self.default
|
|
28
|
+
setattr(namespace, self.dest, not default if current is None else not current)
|
|
29
|
+
else:
|
|
30
|
+
# explicit boolean mode
|
|
31
|
+
setattr(namespace, self.dest, str2bool(values))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CliGenerator:
|
|
35
|
+
"""Generates a CLI automatically from a ConfigManager."""
|
|
36
|
+
|
|
37
|
+
def __init__(self, config_manager: ConfigManager, app_name: str = "app"):
|
|
38
|
+
self.config_manager = config_manager
|
|
39
|
+
self.app_name = app_name
|
|
40
|
+
|
|
41
|
+
# ----------------------------------------------------------------------
|
|
42
|
+
# Argument parser builder
|
|
43
|
+
# ----------------------------------------------------------------------
|
|
44
|
+
def create_argument_parser(self, description: str = None) -> argparse.ArgumentParser:
|
|
45
|
+
if description is None:
|
|
46
|
+
description = f"Command line interface for {self.app_name}"
|
|
47
|
+
|
|
48
|
+
parser = argparse.ArgumentParser(description=description)
|
|
49
|
+
|
|
50
|
+
# Config file argument
|
|
51
|
+
parser.add_argument("--config", help="Path to configuration file")
|
|
52
|
+
|
|
53
|
+
# verbosity
|
|
54
|
+
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose logging")
|
|
55
|
+
parser.add_argument("-q", "--quiet", action="store_true", help="Quiet mode")
|
|
56
|
+
|
|
57
|
+
# CLI parameters
|
|
58
|
+
for p in self.config_manager.get_cli_parameters():
|
|
59
|
+
if p.required: # POSITONAL ARGUMENT
|
|
60
|
+
parser.add_argument(p.name, help=p.help)
|
|
61
|
+
continue
|
|
62
|
+
|
|
63
|
+
# OPTIONAL FLAG
|
|
64
|
+
kwargs = {
|
|
65
|
+
"help": f"{p.help} (default: {p.value})",
|
|
66
|
+
"default": argparse.SUPPRESS,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Handle different parameter types
|
|
70
|
+
if isinstance(p.value, bool):
|
|
71
|
+
kwargs["nargs"] = "?" # allow optional argument
|
|
72
|
+
kwargs["default"] = p.value # default remains as defined
|
|
73
|
+
kwargs["const"] = None # triggers toggle mode
|
|
74
|
+
kwargs["action"] = ToggleOrBool
|
|
75
|
+
else:
|
|
76
|
+
kwargs["type"] = type(p.value)
|
|
77
|
+
if p.choices:
|
|
78
|
+
kwargs["choices"] = p.choices
|
|
79
|
+
|
|
80
|
+
parser.add_argument(p.cli_arg, **kwargs)
|
|
81
|
+
|
|
82
|
+
return parser
|
|
83
|
+
|
|
84
|
+
# ----------------------------------------------------------------------
|
|
85
|
+
# convert args → config overrides
|
|
86
|
+
# ----------------------------------------------------------------------
|
|
87
|
+
def create_config_overrides(self, args: argparse.Namespace) -> dict[str, Any]:
|
|
88
|
+
overrides = {}
|
|
89
|
+
|
|
90
|
+
for p in self.config_manager.get_cli_parameters():
|
|
91
|
+
if hasattr(args, p.name):
|
|
92
|
+
overrides[f"{p.category}__{p.name}"] = getattr(args, p.name)
|
|
93
|
+
|
|
94
|
+
if getattr(args, "verbose", False):
|
|
95
|
+
overrides["app__log_level"] = "DEBUG"
|
|
96
|
+
elif getattr(args, "quiet", False):
|
|
97
|
+
overrides["app__log_level"] = "WARNING"
|
|
98
|
+
|
|
99
|
+
return overrides
|
|
100
|
+
|
|
101
|
+
# ----------------------------------------------------------------------
|
|
102
|
+
# Main CLI runner
|
|
103
|
+
# ----------------------------------------------------------------------
|
|
104
|
+
def run_cli(
|
|
105
|
+
self,
|
|
106
|
+
main_function: Callable[[ConfigManager], int],
|
|
107
|
+
description: str = None,
|
|
108
|
+
validator: Callable[[ConfigManager], bool] = None,
|
|
109
|
+
) -> int:
|
|
110
|
+
parser = self.create_argument_parser(description)
|
|
111
|
+
args = parser.parse_args()
|
|
112
|
+
|
|
113
|
+
# Load config_file only ONCE
|
|
114
|
+
config = ConfigManager(
|
|
115
|
+
categories=tuple(self.config_manager._categories.values()),
|
|
116
|
+
config_file=getattr(args, "config", None),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Apply CLI overrides
|
|
120
|
+
overrides = self.create_config_overrides(args)
|
|
121
|
+
config.apply_overrides(overrides)
|
|
122
|
+
|
|
123
|
+
# Try to get logger if logging is configured
|
|
124
|
+
try:
|
|
125
|
+
from .logging import get_logger
|
|
126
|
+
|
|
127
|
+
logger = get_logger(f"{self.app_name}.cli")
|
|
128
|
+
logger.info(f"Starting {self.app_name} CLI")
|
|
129
|
+
logger.debug(f"Command line arguments: {vars(args)}")
|
|
130
|
+
except ImportError:
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
# Optional validation
|
|
134
|
+
if validator and not validator(config):
|
|
135
|
+
print("Configuration validation failed.")
|
|
136
|
+
return 1
|
|
137
|
+
|
|
138
|
+
# Execute main
|
|
139
|
+
try:
|
|
140
|
+
return main_function(config)
|
|
141
|
+
except KeyboardInterrupt:
|
|
142
|
+
print("Interrupted.")
|
|
143
|
+
return 130
|
|
144
|
+
except Exception as e:
|
|
145
|
+
print(f"Unexpected error: {e}")
|
|
146
|
+
traceback.print_exc()
|
|
147
|
+
return 1
|
|
@@ -23,6 +23,8 @@ uv.lock
|
|
|
23
23
|
.github/workflows/release.yml
|
|
24
24
|
.github/workflows/update_readme.yml
|
|
25
25
|
.idea/runConfigurations/config_generate.xml
|
|
26
|
+
.idea/runConfigurations/example_project_cli.xml
|
|
27
|
+
.idea/runConfigurations/example_project_gui.xml
|
|
26
28
|
docs/.nav.yml
|
|
27
29
|
docs/index.md
|
|
28
30
|
docs/_static/img/favicon.png
|
|
@@ -54,11 +56,13 @@ src/config_cli_gui.egg-info/entry_points.txt
|
|
|
54
56
|
src/config_cli_gui.egg-info/requires.txt
|
|
55
57
|
src/config_cli_gui.egg-info/top_level.txt
|
|
56
58
|
tests/__init__.py
|
|
59
|
+
tests/test_cli.py
|
|
57
60
|
tests/test_config_manager.py
|
|
58
61
|
tests/test_docs.py
|
|
59
62
|
tests/test_generic_cli.py
|
|
60
63
|
tests/example_project/__init__.py
|
|
61
64
|
tests/example_project/__main__.py
|
|
65
|
+
tests/example_project/example.gpx
|
|
62
66
|
tests/example_project/cli/__init__.py
|
|
63
67
|
tests/example_project/cli/__main__.py
|
|
64
68
|
tests/example_project/cli/cli_example.py
|
|
@@ -4,13 +4,12 @@ This file uses the CliGenerator from the generic config framework.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from config_cli_gui.cli import CliGenerator
|
|
7
|
-
from config_cli_gui.config import ConfigManager
|
|
8
7
|
from tests.example_project.config.config_example import ProjectConfigManager
|
|
9
8
|
from tests.example_project.core.base import BaseGPXProcessor
|
|
10
9
|
from tests.example_project.core.logging import initialize_logging
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
def run_main_processing(_config:
|
|
12
|
+
def run_main_processing(_config: ProjectConfigManager) -> int:
|
|
14
13
|
"""Main processing function that gets called by the CLI generator.
|
|
15
14
|
|
|
16
15
|
Args:
|
|
@@ -32,11 +31,12 @@ def run_main_processing(_config: ConfigManager) -> int:
|
|
|
32
31
|
|
|
33
32
|
# Create and run BaseGPXProcessor
|
|
34
33
|
processor = BaseGPXProcessor(
|
|
35
|
-
_config.
|
|
36
|
-
_config.
|
|
37
|
-
_config.
|
|
38
|
-
_config.
|
|
39
|
-
_config.
|
|
34
|
+
_config.cli.input.value,
|
|
35
|
+
_config.cli.output.value,
|
|
36
|
+
_config.cli.min_dist.value,
|
|
37
|
+
_config.app.date_format.value,
|
|
38
|
+
_config.cli.elevation.value,
|
|
39
|
+
_config.cli.extract_waypoints.value,
|
|
40
40
|
logger=logger,
|
|
41
41
|
)
|
|
42
42
|
|
|
@@ -58,10 +58,11 @@ def main():
|
|
|
58
58
|
# Create the base configuration manager
|
|
59
59
|
config_manager = ProjectConfigManager()
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
cli_generator = CliGenerator(
|
|
62
|
+
config_manager=config_manager,
|
|
63
|
+
app_name="config_cli_gui",
|
|
64
|
+
)
|
|
63
65
|
|
|
64
|
-
# Run the CLI with our main processing function
|
|
65
66
|
return cli_generator.run_cli(
|
|
66
67
|
main_function=run_main_processing,
|
|
67
68
|
description="Example CLI for config-cli-gui using the generic config framework.",
|
{config_cli_gui-0.2.0 → config_cli_gui-0.2.2}/tests/example_project/config/config_example.py
RENAMED
|
@@ -56,7 +56,7 @@ class CliConfig(ConfigCategory):
|
|
|
56
56
|
|
|
57
57
|
elevation: ConfigParameter = ConfigParameter(
|
|
58
58
|
name="elevation",
|
|
59
|
-
value=
|
|
59
|
+
value=False,
|
|
60
60
|
help="Include elevation data in waypoints",
|
|
61
61
|
is_cli=True,
|
|
62
62
|
)
|
|
@@ -181,7 +181,7 @@ class MiscConfig(ConfigCategory):
|
|
|
181
181
|
|
|
182
182
|
some_date: ConfigParameter = ConfigParameter(
|
|
183
183
|
name="some_date",
|
|
184
|
-
value=datetime.
|
|
184
|
+
value=datetime.fromisoformat("2025-12-31 10:30:45"),
|
|
185
185
|
help="Date setting for the application",
|
|
186
186
|
)
|
|
187
187
|
|
|
@@ -202,9 +202,9 @@ class ProjectConfigManager(ConfigManager): # Inherit from ConfigManager
|
|
|
202
202
|
|
|
203
203
|
def main():
|
|
204
204
|
"""Main function to generate config file and documentation."""
|
|
205
|
-
default_config: str = "
|
|
206
|
-
default_cli_doc: str = "
|
|
207
|
-
default_config_doc: str = "
|
|
205
|
+
default_config: str = "config.yaml"
|
|
206
|
+
default_cli_doc: str = "docs/usage/cli.md"
|
|
207
|
+
default_config_doc: str = "docs/usage/config.md"
|
|
208
208
|
_config = ProjectConfigManager()
|
|
209
209
|
doc_gen = DocumentationGenerator(_config)
|
|
210
210
|
doc_gen.generate_default_config_file(output_file=default_config)
|
|
@@ -11,6 +11,7 @@ class BaseGPXProcessor:
|
|
|
11
11
|
min_dist=10,
|
|
12
12
|
date_format="%Y-%m-%d",
|
|
13
13
|
elevation=True,
|
|
14
|
+
extract_waypoints=True,
|
|
14
15
|
logger=None,
|
|
15
16
|
):
|
|
16
17
|
# ensure that input is converted into a list[Path]
|
|
@@ -29,7 +30,12 @@ class BaseGPXProcessor:
|
|
|
29
30
|
self.include_elevation = elevation
|
|
30
31
|
self.logger = logger
|
|
31
32
|
|
|
32
|
-
self.logger.info(
|
|
33
|
+
self.logger.info("example module successfully initialized with:")
|
|
34
|
+
self.logger.info(f"output: {output}")
|
|
35
|
+
self.logger.info(f"min_dist: {min_dist}")
|
|
36
|
+
self.logger.info(f"date_format: {date_format}")
|
|
37
|
+
self.logger.info(f"elevation: {elevation}")
|
|
38
|
+
self.logger.info(f"extract_waypoints: {extract_waypoints}")
|
|
33
39
|
|
|
34
40
|
def compress_files(self) -> list[str]:
|
|
35
41
|
"""Shrink the size of all given gpx/kml files in se
|