config-cli-gui 0.3.8__tar.gz → 0.3.9__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.
Files changed (88) hide show
  1. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/HISTORY.md +7 -0
  2. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/Makefile +7 -2
  3. {config_cli_gui-0.3.8/src/config_cli_gui.egg-info → config_cli_gui-0.3.9}/PKG-INFO +1 -1
  4. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/config.yaml +6 -6
  5. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/usage/cli.md +28 -12
  6. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/usage/config.md +13 -4
  7. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/_version.py +3 -3
  8. config_cli_gui-0.3.9/src/config_cli_gui/docs.py +279 -0
  9. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9/src/config_cli_gui.egg-info}/PKG-INFO +1 -1
  10. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/scm_version.json +2 -2
  11. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/config/config_example.py +6 -1
  12. config_cli_gui-0.3.8/src/config_cli_gui/docs.py +0 -203
  13. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/FUNDING.yml +0 -0
  14. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  15. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/actions/setup-environment/action.yml +0 -0
  18. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/dependabot.yml +0 -0
  19. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/init.sh +0 -0
  20. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/release_message.sh +0 -0
  21. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/update_funding.py +0 -0
  22. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/workflows/main.yml +0 -0
  23. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/workflows/release.yml +0 -0
  24. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.github/workflows/update_readme.yml +0 -0
  25. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.gitignore +0 -0
  26. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.idea/runConfigurations/config_generate.xml +0 -0
  27. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.idea/runConfigurations/example_project_cli.xml +0 -0
  28. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.idea/runConfigurations/example_project_gui.xml +0 -0
  29. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.pre-commit-config.yaml +0 -0
  30. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/.readthedocs.yaml +0 -0
  31. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/LICENSE +0 -0
  32. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/README.md +0 -0
  33. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/.nav.yml +0 -0
  34. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/_static/img/favicon.png +0 -0
  35. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/_static/img/logo.png +0 -0
  36. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/_static/img/settings_dlg.png +0 -0
  37. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/_static/img/settings_doc.png +0 -0
  38. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/css/custom.css +0 -0
  39. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/develop/contributing.md +0 -0
  40. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/develop/make_windows.md +0 -0
  41. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/develop/naming_convention.md +0 -0
  42. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/funding/funding.md +0 -0
  43. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/getting-started/install.md +0 -0
  44. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/getting-started/virtual-environment.md +0 -0
  45. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/docs/index.md +0 -0
  46. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/mkdocs.yml +0 -0
  47. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/pyproject.toml +0 -0
  48. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/scripts/show_filelist.ps1 +0 -0
  49. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/scripts/show_tree.ps1 +0 -0
  50. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/scripts/show_tree.py +0 -0
  51. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/scripts/update_readme.py +0 -0
  52. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/setup.cfg +0 -0
  53. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/__init__.py +0 -0
  54. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/__init__.py +0 -0
  55. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/cli.py +0 -0
  56. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/config.py +0 -0
  57. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/configtypes/__init__.py +0 -0
  58. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/configtypes/color.py +0 -0
  59. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/configtypes/font.py +0 -0
  60. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/configtypes/vector.py +0 -0
  61. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/gui.py +0 -0
  62. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/logging.py +0 -0
  63. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui/persistence.py +0 -0
  64. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/SOURCES.txt +0 -0
  65. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/dependency_links.txt +0 -0
  66. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/entry_points.txt +0 -0
  67. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/requires.txt +0 -0
  68. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/scm_file_list.json +0 -0
  69. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/src/config_cli_gui.egg-info/top_level.txt +0 -0
  70. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/template.yml.url +0 -0
  71. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/__init__.py +0 -0
  72. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/__init__.py +0 -0
  73. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/__main__.py +0 -0
  74. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/cli/__init__.py +0 -0
  75. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/cli/__main__.py +0 -0
  76. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/cli/cli_example.py +0 -0
  77. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/config/__init__.py +0 -0
  78. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/core/__init__.py +0 -0
  79. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/core/base.py +0 -0
  80. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/example.gpx +0 -0
  81. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/gui/__init__.py +0 -0
  82. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/gui/__main__.py +0 -0
  83. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/example_project/gui/gui_example.py +0 -0
  84. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/test_cli.py +0 -0
  85. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/test_config_manager.py +0 -0
  86. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/test_docs.py +0 -0
  87. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/tests/test_generic_cli.py +0 -0
  88. {config_cli_gui-0.3.8 → config_cli_gui-0.3.9}/uv.lock +0 -0
@@ -4,6 +4,13 @@ Changelog
4
4
 
5
5
  (unreleased)
6
6
  ------------
7
+ - Improved cli doc generation: link to config.yaml. [Paul Magister]
8
+ - Improved cli doc generation: no more python -m. [Paul Magister]
9
+
10
+
11
+ 0.3.8 (2026-10-02)
12
+ ------------------
13
+ - Docs: Update HISTORY.md for release 0.3.8. [Paul Magister]
7
14
  - Bump python version to <3.14. [Paul Magister]
8
15
 
9
16
 
@@ -50,7 +50,7 @@ lint: ## Run pep8, black, mypy linters.
50
50
  # uv run mypy --ignore-missing-imports src/
51
51
 
52
52
  .PHONY: test
53
- test: lint ## Run tests and generate coverage report.
53
+ test: lint example-files ## Run tests and generate coverage report.
54
54
  uv run pytest -v --cov-config .coveragerc --cov=src -l --tb=short --maxfail=1 tests/
55
55
  uv run coverage xml
56
56
  uv run coverage html
@@ -115,7 +115,7 @@ release: ## Create a new tag for release.
115
115
  echo "Add modified files to commit and push them to main"
116
116
 
117
117
  .PHONY: docs
118
- docs: ## Build and sync the documentation.
118
+ docs: example-files ## Build and sync the documentation.
119
119
  @echo "sync documentation ..."
120
120
  @uv run ./scripts/update_readme.py
121
121
  @uv run ./.github/update_funding.py
@@ -138,3 +138,8 @@ pytree: ## Show project tree (excluding ignored folders)
138
138
  .PHONY: init
139
139
  init: ## Initialize the project based on an application template.
140
140
  @./.github/init.sh
141
+
142
+ .PHONY: example-files
143
+ example-files: ## Regenerate config.yaml and docs from tests/example_project.
144
+ @echo "Generating example config and docs from tests/example_project..."
145
+ @uv run python tests/example_project/config/config_example.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: config-cli-gui
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: Feature-rich Python project template for config-cli-gui.
5
5
  Author: pamagister
6
6
  Requires-Python: <3.14,>=3.10
@@ -10,7 +10,7 @@ app:
10
10
  # Enable logging to console | type=bool | choices=[True, False]
11
11
  enable_console_logging: true
12
12
  # GUI theme setting supported by ttkbootstrap | type=str | choices=['cosmo', 'flatly', 'litera', 'minty', 'lumen', 'sandstone', 'yeti', 'pulse', 'united', 'darkly', 'superhero', 'solar', 'cyborg', 'vapor', 'simplex']
13
- theme: superhero
13
+ theme: darkly
14
14
  cli:
15
15
  # Path to input (file or folder) | type=str | [CLI]
16
16
  input: ''
@@ -34,21 +34,21 @@ gui:
34
34
  # Maximum number of log lines to keep in GUI | type=int
35
35
  max_log_lines: 1000
36
36
  # Point in 2D space | type=Vector
37
- point2D: (7.0, 11.0)
37
+ point2D: (7, 11)
38
38
  # Point in 3D space | type=Vector
39
39
  point3D: (1.2, 3.4, 5.6)
40
40
  misc:
41
41
  # Example integer | type=int
42
42
  some_numeric: 42
43
43
  # Example vector 2D | type=Vector
44
- some_vector2d: (1.0, 2.0)
44
+ some_vector2d: (1, 2)
45
45
  # Example vector 3D | type=Vector
46
46
  some_vector3d: (1.1, 2.2, 3.3)
47
- # Path to the file to use | type=str
47
+ # Path to the file to use | type=PosixPath
48
48
  some_file: some_file.txt
49
49
  # Color setting for the application | type=Color
50
50
  some_color: '#ff0000'
51
51
  # Date setting for the application | type=datetime
52
- some_date: '2025-12-31T10:30:00'
52
+ some_date: '2025-12-31T10:30:45'
53
53
  # Font setting for the application | type=Font
54
- some_font: 'DejaVuSans.ttf, 12.0, #0000ff'
54
+ some_font: 'DejaVuSans.ttf, 12, #0000ff'
@@ -3,13 +3,22 @@
3
3
  Command line options for app
4
4
 
5
5
  ```bash
6
- python -m app [OPTIONS] input
6
+ app [OPTIONS] <input>
7
+ ```
8
+
9
+ For development from a source checkout, the equivalent module invocation is:
10
+
11
+ ```bash
12
+ python -m app [OPTIONS] <input>
7
13
  ```
8
14
 
9
15
  ## Options
10
16
 
11
17
  | Option | Type | Description | Default | Choices |
12
18
  |-----------------------|------|---------------------------------------------------|------------|---------------|
19
+ | --config | str | Path to configuration file | - | - |
20
+ | -v, --verbose | bool | Enable debug logging | False | [True, False] |
21
+ | -q, --quiet | bool | Show warnings and errors only | False | [True, False] |
13
22
  | `input` | str | Path to input (file or folder) | *required* | - |
14
23
  | `--output` | str | Path to output destination | *required* | - |
15
24
  | `--min_dist` | int | Maximum distance between two waypoints | 20 | - |
@@ -23,37 +32,44 @@ python -m app [OPTIONS] input
23
32
  ### 1. Basic usage
24
33
 
25
34
  ```bash
26
- python -m app input
35
+ app input
27
36
  ```
28
37
 
29
38
  ### 2. With verbose logging
30
39
 
31
40
  ```bash
32
- python -m app -v input
33
- python -m app --verbose input
41
+ app -v input
42
+ app --verbose input
34
43
  ```
35
44
 
36
45
  ### 3. With quiet mode
37
46
 
38
47
  ```bash
39
- python -m app -q input
40
- python -m app --quiet input
48
+ app -q input
49
+ app --quiet input
41
50
  ```
42
51
 
43
- ### 4. With min_dist parameter
52
+ ### 4. With output parameter
44
53
 
45
54
  ```bash
46
- python -m app --min_dist 20 input
55
+ app --output input
47
56
  ```
48
57
 
49
- ### 5. With extract_waypoints parameter
58
+ ### 5. With min_dist parameter
50
59
 
51
60
  ```bash
52
- python -m app --extract_waypoints True input
61
+ app --min_dist 20 input
53
62
  ```
54
63
 
55
- ### 6. With elevation parameter
64
+ ### 6. With extract_waypoints parameter
56
65
 
57
66
  ```bash
58
- python -m app --elevation True input
67
+ app --extract_waypoints True input
68
+ ```
69
+
70
+ ### Developer usage
71
+
72
+ ```bash
73
+ python -m app --help
74
+ python -m app input
59
75
  ```
@@ -3,7 +3,16 @@
3
3
  These parameters are available to configure the behavior of your application.
4
4
  The parameters in the cli category can be accessed via the command line interface.
5
5
 
6
- ## Category "app"
6
+ ## Configuration File Reference
7
+
8
+ The actual configuration is stored in [`config.yaml`](../../config.yaml). You can:
9
+
10
+ - Edit the configuration file directly using your text editor
11
+ - Use the `--config` command-line option to specify a custom config file
12
+ - Place a `config.yaml` in your application's config
13
+ directory (typically `~/.config/config-cli-gui/`)
14
+
15
+ ## Category "app" {#app}
7
16
 
8
17
  | Name | Type | Description | Default | Choices |
9
18
  |------------------------|------|---------------------------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -14,7 +23,7 @@ The parameters in the cli category can be accessed via the command line interfac
14
23
  | enable_console_logging | bool | Enable logging to console | True | [True, False] |
15
24
  | theme | str | GUI theme setting supported by ttkbootstrap | 'darkly' | ['cosmo', 'flatly', 'litera', 'minty', 'lumen', 'sandstone', 'yeti', 'pulse', 'united', 'darkly', 'superhero', 'solar', 'cyborg', 'vapor', 'simplex'] |
16
25
 
17
- ## Category "cli"
26
+ ## Category "cli" {#cli}
18
27
 
19
28
  | Name | Type | Description | Default | Choices |
20
29
  |-------------------|------|---------------------------------------------------|---------|---------------|
@@ -24,7 +33,7 @@ The parameters in the cli category can be accessed via the command line interfac
24
33
  | extract_waypoints | bool | Extract starting points of each track as waypoint | True | [True, False] |
25
34
  | elevation | bool | Include elevation data in waypoints | False | [True, False] |
26
35
 
27
- ## Category "gui"
36
+ ## Category "gui" {#gui}
28
37
 
29
38
  | Name | Type | Description | Default | Choices |
30
39
  |-------------------|--------|------------------------------------------------|-----------------------|---------------|
@@ -36,7 +45,7 @@ The parameters in the cli category can be accessed via the command line interfac
36
45
  | point2D | Vector | Point in 2D space | Vector(7, 11) | - |
37
46
  | point3D | Vector | Point in 3D space | Vector(1.2, 3.4, 5.6) | - |
38
47
 
39
- ## Category "misc"
48
+ ## Category "misc" {#misc}
40
49
 
41
50
  | Name | Type | Description | Default | Choices |
42
51
  |---------------|-----------|-----------------------------------|--------------------------------------------------------------|---------|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.3.8'
22
- __version_tuple__ = version_tuple = (0, 3, 8)
21
+ __version__ = version = '0.3.9'
22
+ __version_tuple__ = version_tuple = (0, 3, 9)
23
23
 
24
- __commit_id__ = commit_id = 'g250985e4a'
24
+ __commit_id__ = commit_id = 'gddc907973'
@@ -0,0 +1,279 @@
1
+ from pathlib import Path
2
+ from textwrap import dedent
3
+
4
+ from config_cli_gui.config import ConfigManager
5
+
6
+
7
+ class DocumentationGenerator:
8
+ """Generates documentation and configuration files from ConfigManager."""
9
+
10
+ def __init__(self, config_manager: ConfigManager):
11
+ self.config_manager = config_manager
12
+
13
+ def generate_config_markdown_doc(
14
+ self,
15
+ output_file: str,
16
+ config_file_path: str | None = "../../config.yaml",
17
+ link_strategy: str = "relative",
18
+ ):
19
+ """Generate Markdown documentation for all configuration parameters.
20
+
21
+ Args:
22
+ output_file: Path where the markdown file will be written
23
+ config_file_path: Path to the config.yaml file (for creating links)
24
+ Can be relative (e.g., "../../config.yaml") or absolute
25
+ link_strategy: How to generate links to config.yaml:
26
+ - "relative": relative path (default, for documentation)
27
+ - "file": file:// URI (for file explorer/installed app)
28
+ - "none": no links (default if config_file_path is None)
29
+ """
30
+
31
+ def pad(s, width):
32
+ return s + " " * (width - len(s))
33
+
34
+ # Create introduction with link to config file if provided
35
+ markdown_content = dedent("""
36
+ # Configuration Parameters
37
+
38
+ These parameters are available to configure the behavior of your application.
39
+ The parameters in the cli category can be accessed via the command line interface.
40
+
41
+ """).lstrip()
42
+
43
+ # Add config file link if provided
44
+ if config_file_path:
45
+ if link_strategy == "file":
46
+ # Convert to absolute path for file:// URI
47
+ from pathlib import Path as PathlibPath
48
+
49
+ abs_path = PathlibPath(config_file_path).resolve()
50
+ link = f"file://{abs_path.as_posix()}"
51
+ else:
52
+ # Use relative path (default)
53
+ link = config_file_path
54
+
55
+ markdown_content += dedent(f"""
56
+ ## Configuration File Reference
57
+
58
+ The actual configuration is stored in [`config.yaml`]({link}). You can:
59
+
60
+ - Edit the configuration file directly using your text editor
61
+ - Use the `--config` command-line option to specify a custom config file
62
+ - Place a `config.yaml` in your application's config
63
+ directory (typically `~/.config/config-cli-gui/`)
64
+
65
+ """).lstrip()
66
+
67
+ for category_name, category in self.config_manager._categories.items():
68
+ # Create anchor-friendly category name
69
+ category_anchor = category_name.lower().replace(" ", "-")
70
+ markdown_content += f'## Category "{category_name}" {{#{category_anchor}}}\n\n'
71
+
72
+ # Collect all parameters for this category
73
+ rows = []
74
+ header = ["Name", "Type", "Description", "Default", "Choices"]
75
+
76
+ for param in category.get_parameters():
77
+ name = param.name
78
+ typ = type(param.value).__name__
79
+ desc = param.help
80
+ value = repr(param.value)
81
+ choices = str(param.choices) if param.choices else "-"
82
+
83
+ rows.append((name, typ, desc, value, choices))
84
+
85
+ if not rows:
86
+ continue
87
+
88
+ # Calculate column widths
89
+ all_rows = [header] + rows
90
+ widths = [max(len(str(col)) for col in column) for column in zip(*all_rows)]
91
+
92
+ # Create Markdown table
93
+ table = (
94
+ "| "
95
+ + " | ".join(pad(h, w) for h, w in zip(header, widths))
96
+ + " |\n"
97
+ + "|-"
98
+ + "-|-".join("-" * w for w in widths)
99
+ + "-|\n"
100
+ )
101
+ for row in rows:
102
+ table += "| " + " | ".join(pad(str(col), w) for col, w in zip(row, widths)) + " |\n"
103
+
104
+ markdown_content += table + "\n"
105
+
106
+ # Write to file
107
+ Path(output_file).parent.mkdir(parents=True, exist_ok=True)
108
+ with open(output_file, "w", encoding="utf-8") as f:
109
+ f.write(markdown_content)
110
+
111
+ def generate_default_config_file(self, output_file: str):
112
+ """Generate a default configuration file with all parameters and descriptions."""
113
+ output_path = Path(output_file)
114
+ output_path.parent.mkdir(parents=True, exist_ok=True)
115
+ self.config_manager.save_to_file(output_path.as_posix())
116
+
117
+ def generate_cli_markdown_doc(self, output_file: str, app_name: str = "app"):
118
+ """Generate Markdown CLI documentation.
119
+
120
+ The generated doc prefers the installed command for end users (for example
121
+ ``gpx-kml-converter --help``), while still including the direct module
122
+ invocation as a development fallback (``python -m gpx_kml_converter``).
123
+ """
124
+ cli_params = self.config_manager.get_cli_parameters()
125
+
126
+ if not cli_params:
127
+ return
128
+
129
+ base_app_name = (app_name or self.config_manager.get_app_name()).strip() or "app"
130
+ command_name = base_app_name.replace("_", "-")
131
+ module_name = base_app_name.replace("-", "_")
132
+
133
+ rows = [
134
+ ("--config", "str", "Path to configuration file", "-", "-"),
135
+ ("-v, --verbose", "bool", "Enable debug logging", "False", "[True, False]"),
136
+ (
137
+ "-q, --quiet",
138
+ "bool",
139
+ "Show warnings and errors only",
140
+ "False",
141
+ "[True, False]",
142
+ ),
143
+ ]
144
+ required_params = []
145
+ optional_params = []
146
+
147
+ for param in cli_params:
148
+ cli_arg = (
149
+ f"`{param.name}`" if param.required else (f"`{param.cli_arg or f'--{param.name}'}`")
150
+ )
151
+ typ = type(param.value).__name__
152
+ desc = param.help
153
+ value = (
154
+ "*required*" if param.required or param.value in (None, "") else repr(param.value)
155
+ )
156
+ choices = str(param.choices) if param.choices else "-"
157
+
158
+ rows.append((cli_arg, typ, desc, value, choices))
159
+ if param.required:
160
+ required_params.append(param)
161
+ else:
162
+ optional_params.append(param)
163
+
164
+ # Generate table
165
+ def pad(s, width):
166
+ return s + " " * (width - len(s))
167
+
168
+ header = ["Option", "Type", "Description", "Default", "Choices"]
169
+ widths = [max(len(str(col)) for col in column) for column in zip(*rows, strict=False)]
170
+
171
+ table = dedent(
172
+ "| "
173
+ + " | ".join(pad(h, w) for h, w in zip(header, widths, strict=False))
174
+ + " |\n"
175
+ + "|-"
176
+ + "-|-".join("-" * w for w in widths)
177
+ + "-|\n"
178
+ )
179
+ for row in rows:
180
+ table += (
181
+ "| "
182
+ + " | ".join(pad(str(col), w) for col, w in zip(row, widths, strict=False))
183
+ + " |\n"
184
+ )
185
+
186
+ required_arg_names = [param.name for param in required_params]
187
+ required_target = (
188
+ " ".join(f"<{name}>" for name in required_arg_names) if required_arg_names else "input"
189
+ )
190
+ usage_command = f"{command_name} [OPTIONS] {required_target}".strip()
191
+ usage_module = f"python -m {module_name} [OPTIONS] {required_target}".strip()
192
+
193
+ examples = []
194
+ primary_target = required_arg_names[0] if required_arg_names else "input"
195
+
196
+ examples.append(
197
+ dedent(f"""
198
+ ### 1. Basic usage
199
+
200
+ ```bash
201
+ {command_name} {primary_target}
202
+ ```
203
+ """)
204
+ )
205
+
206
+ examples.append(
207
+ dedent(f"""
208
+ ### 2. With verbose logging
209
+
210
+ ```bash
211
+ {command_name} -v {primary_target}
212
+ {command_name} --verbose {primary_target}
213
+ ```
214
+ """)
215
+ )
216
+
217
+ examples.append(
218
+ dedent(f"""
219
+ ### 3. With quiet mode
220
+
221
+ ```bash
222
+ {command_name} -q {primary_target}
223
+ {command_name} --quiet {primary_target}
224
+ ```
225
+ """)
226
+ )
227
+
228
+ for i, param in enumerate(optional_params[:3], 4):
229
+ if param.name in {"verbose", "quiet", "config"}:
230
+ continue
231
+ example_value = param.choices[0] if param.choices else param.value
232
+ examples.append(
233
+ dedent(f"""
234
+ ### {i}. With {param.name} parameter
235
+
236
+ ```bash
237
+ {command_name} --{param.name} {example_value} {primary_target}
238
+ ```
239
+ """)
240
+ )
241
+
242
+ examples.append(
243
+ dedent(f"""
244
+ ### Developer usage
245
+
246
+ ```bash
247
+ python -m {module_name} --help
248
+ python -m {module_name} {primary_target}
249
+ ```
250
+ """)
251
+ )
252
+
253
+ markdown = dedent(f"""
254
+ # Command Line Interface
255
+
256
+ Command line options for {base_app_name}
257
+
258
+ ```bash
259
+ {usage_command}
260
+ ```
261
+
262
+ For development from a source checkout, the equivalent module invocation is:
263
+
264
+ ```bash
265
+ {usage_module}
266
+ ```
267
+
268
+ ## Options
269
+
270
+ {table}
271
+
272
+ ## Examples
273
+
274
+ {"".join(examples)}
275
+ """).strip()
276
+
277
+ Path(output_file).parent.mkdir(parents=True, exist_ok=True)
278
+ with open(output_file, "w", encoding="utf-8") as f:
279
+ f.write(markdown)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: config-cli-gui
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: Feature-rich Python project template for config-cli-gui.
5
5
  Author: pamagister
6
6
  Requires-Python: <3.14,>=3.10
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "0.3.8",
2
+ "tag": "0.3.9",
3
3
  "distance": 0,
4
- "node": "g250985e4a0c10f70ecf64392a37ba8294e8c45ae",
4
+ "node": "gddc9079730c4ede01e053a2bc94b1a9bf2c7a81e",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-10-02"
@@ -196,7 +196,12 @@ def main():
196
196
  doc_gen.generate_default_config_file(output_file=default_config)
197
197
  print(f"Generated: {default_config}")
198
198
 
199
- doc_gen.generate_config_markdown_doc(output_file=default_config_doc)
199
+ # Generate config markdown with link to config.yaml
200
+ doc_gen.generate_config_markdown_doc(
201
+ output_file=default_config_doc,
202
+ config_file_path="../../config.yaml",
203
+ link_strategy="relative",
204
+ )
200
205
  print(f"Generated: {default_config_doc}")
201
206
 
202
207
  doc_gen.generate_cli_markdown_doc(output_file=default_cli_doc)
@@ -1,203 +0,0 @@
1
- from pathlib import Path
2
- from textwrap import dedent
3
-
4
- from config_cli_gui.config import ConfigManager
5
-
6
-
7
- class DocumentationGenerator:
8
- """Generates documentation and configuration files from ConfigManager."""
9
-
10
- def __init__(self, config_manager: ConfigManager):
11
- self.config_manager = config_manager
12
-
13
- def generate_config_markdown_doc(self, output_file: str):
14
- """Generate Markdown documentation for all configuration parameters."""
15
-
16
- def pad(s, width):
17
- return s + " " * (width - len(s))
18
-
19
- markdown_content = dedent(
20
- """
21
- # Configuration Parameters
22
-
23
- These parameters are available to configure the behavior of your application.
24
- The parameters in the cli category can be accessed via the command line interface.
25
-
26
- """
27
- ).lstrip()
28
-
29
- for category_name, category in self.config_manager._categories.items():
30
- markdown_content += f'## Category "{category_name}"\n\n'
31
-
32
- # Collect all parameters for this category
33
- rows = []
34
- header = ["Name", "Type", "Description", "Default", "Choices"]
35
-
36
- for param in category.get_parameters():
37
- name = param.name
38
- typ = type(param.value).__name__
39
- desc = param.help
40
- value = repr(param.value)
41
- choices = str(param.choices) if param.choices else "-"
42
-
43
- rows.append((name, typ, desc, value, choices))
44
-
45
- if not rows:
46
- continue
47
-
48
- # Calculate column widths
49
- all_rows = [header] + rows
50
- widths = [max(len(str(col)) for col in column) for column in zip(*all_rows)]
51
-
52
- # Create Markdown table
53
- table = (
54
- "| "
55
- + " | ".join(pad(h, w) for h, w in zip(header, widths))
56
- + " |\n"
57
- + "|-"
58
- + "-|-".join("-" * w for w in widths)
59
- + "-|\n"
60
- )
61
- for row in rows:
62
- table += "| " + " | ".join(pad(str(col), w) for col, w in zip(row, widths)) + " |\n"
63
-
64
- markdown_content += table + "\n"
65
-
66
- # Write to file
67
- Path(output_file).parent.mkdir(parents=True, exist_ok=True)
68
- with open(output_file, "w", encoding="utf-8") as f:
69
- f.write(markdown_content)
70
-
71
- def generate_default_config_file(self, output_file: str):
72
- """Generate a default configuration file with all parameters and descriptions."""
73
- output_path = Path(output_file)
74
- output_path.parent.mkdir(parents=True, exist_ok=True)
75
- self.config_manager.save_to_file(output_path.as_posix())
76
-
77
- def generate_cli_markdown_doc(self, output_file: str, app_name: str = "app"):
78
- """Generate Markdown CLI documentation."""
79
- cli_params = self.config_manager.get_cli_parameters()
80
-
81
- if not cli_params:
82
- return
83
-
84
- rows = []
85
- required_params = []
86
- optional_params = []
87
-
88
- for param in cli_params:
89
- cli_arg = f"`--{param.name}`" if not param.required else f"`{param.name}`"
90
- typ = type(param.value).__name__
91
- desc = param.help
92
- value = (
93
- "*required*" if param.required or param.value in (None, "") else repr(param.value)
94
- )
95
- choices = str(param.choices) if param.choices else "-"
96
-
97
- rows.append((cli_arg, typ, desc, value, choices))
98
- if value == "*required*":
99
- required_params.append(param)
100
- else:
101
- optional_params.append(param)
102
-
103
- # Generate table
104
- def pad(s, width):
105
- return s + " " * (width - len(s))
106
-
107
- widths = [max(len(str(col)) for col in column) for column in zip(*rows)]
108
- header = ["Option", "Type", "Description", "Default", "Choices"]
109
-
110
- table = (
111
- "| "
112
- + " | ".join(pad(h, w) for h, w in zip(header, widths))
113
- + " |\n"
114
- + "|-"
115
- + "-|-".join("-" * w for w in widths)
116
- + "-|\n"
117
- )
118
- for row in rows:
119
- table += "| " + " | ".join(pad(str(col), w) for col, w in zip(row, widths)) + " |\n"
120
-
121
- # Generate examples
122
- examples = []
123
- required_arg = required_params[0].name if required_params else "example.input"
124
-
125
- examples.append(
126
- dedent(
127
- f"""
128
- ### 1. Basic usage
129
-
130
- ```bash
131
- python -m {app_name} {required_arg}
132
- ```
133
- """
134
- )
135
- )
136
-
137
- # Add logging examples
138
- examples.append(
139
- dedent(
140
- f"""
141
- ### 2. With verbose logging
142
-
143
- ```bash
144
- python -m {app_name} -v {required_arg}
145
- python -m {app_name} --verbose {required_arg}
146
- ```
147
- """
148
- )
149
- )
150
-
151
- examples.append(
152
- dedent(
153
- f"""
154
- ### 3. With quiet mode
155
-
156
- ```bash
157
- python -m {app_name} -q {required_arg}
158
- python -m {app_name} --quiet {required_arg}
159
- ```
160
- """
161
- )
162
- )
163
-
164
- # Add more examples with optional parameters
165
- for i, param in enumerate(optional_params[:3], 4):
166
- if param.name in ["verbose", "quiet"]:
167
- continue
168
- example_value = param.choices[0] if param.choices else param.value
169
- examples.append(
170
- dedent(
171
- f"""
172
- ### {i}. With {param.name} parameter
173
-
174
- ```bash
175
- python -m {app_name} --{param.name} {example_value} {required_arg}
176
- ```
177
- """
178
- )
179
- )
180
-
181
- markdown = dedent(
182
- f"""
183
- # Command Line Interface
184
-
185
- Command line options for {app_name}
186
-
187
- ```bash
188
- python -m {app_name} [OPTIONS] {required_arg if required_params else ""}
189
- ```
190
-
191
- ## Options
192
-
193
- {table}
194
-
195
- ## Examples
196
-
197
- {"".join(examples)}
198
- """
199
- ).strip()
200
-
201
- Path(output_file).parent.mkdir(parents=True, exist_ok=True)
202
- with open(output_file, "w", encoding="utf-8") as f:
203
- f.write(markdown)
File without changes
File without changes
File without changes
File without changes