kspl 1.1.1__tar.gz → 1.3.0__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.
@@ -1,29 +1,26 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: kspl
3
- Version: 1.1.1
3
+ Version: 1.3.0
4
4
  Summary: KConfig GUI for Software Product Lines with multiple variants.
5
- Home-page: https://github.com/cuinixam/kspl
6
5
  License: MIT
7
6
  Author: Cuinixam
8
7
  Author-email: cuinixam@me.com
9
- Requires-Python: >=3.10,<4.0
8
+ Requires-Python: <4.0,>=3.10
10
9
  Classifier: Development Status :: 2 - Pre-Alpha
11
10
  Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: MIT License
13
11
  Classifier: Natural Language :: English
14
12
  Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Topic :: Software Development :: Libraries
20
- Requires-Dist: customtkinter (>=5.2.0,<6.0.0)
21
- Requires-Dist: kconfiglib (>=14.1.0,<15.0.0)
22
- Requires-Dist: packaging (>=23.2,<24.0)
23
- Requires-Dist: py-app-dev (>=2.0.0,<3.0.0)
19
+ Requires-Dist: customtkinter (>=5,<6)
20
+ Requires-Dist: kconfiglib (>=14,<15)
21
+ Requires-Dist: py-app-dev (>=2,<3)
24
22
  Project-URL: Bug Tracker, https://github.com/cuinixam/kspl/issues
25
23
  Project-URL: Changelog, https://github.com/cuinixam/kspl/blob/main/CHANGELOG.md
26
- Project-URL: Documentation, https://kspl.readthedocs.io
27
24
  Project-URL: Repository, https://github.com/cuinixam/kspl
28
25
  Description-Content-Type: text/markdown
29
26
 
@@ -33,19 +30,19 @@ Description-Content-Type: text/markdown
33
30
  <a href="https://github.com/cuinixam/kspl/actions/workflows/ci.yml?query=branch%3Amain">
34
31
  <img src="https://img.shields.io/github/actions/workflow/status/cuinixam/kspl/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
35
32
  </a>
36
- <a href="https://kspl.readthedocs.io">
37
- <img src="https://img.shields.io/readthedocs/kspl.svg?logo=read-the-docs&logoColor=fff&style=flat-square" alt="Documentation Status">
38
- </a>
39
33
  <a href="https://codecov.io/gh/cuinixam/kspl">
40
34
  <img src="https://img.shields.io/codecov/c/github/cuinixam/kspl.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
41
35
  </a>
42
36
  </p>
43
37
  <p align="center">
44
- <a href="https://python-poetry.org/">
45
- <img src="https://img.shields.io/badge/packaging-poetry-299bd7?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAASCAYAAABrXO8xAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJJSURBVHgBfZLPa1NBEMe/s7tNXoxW1KJQKaUHkXhQvHgW6UHQQ09CBS/6V3hKc/AP8CqCrUcpmop3Cx48eDB4yEECjVQrlZb80CRN8t6OM/teagVxYZi38+Yz853dJbzoMV3MM8cJUcLMSUKIE8AzQ2PieZzFxEJOHMOgMQQ+dUgSAckNXhapU/NMhDSWLs1B24A8sO1xrN4NECkcAC9ASkiIJc6k5TRiUDPhnyMMdhKc+Zx19l6SgyeW76BEONY9exVQMzKExGKwwPsCzza7KGSSWRWEQhyEaDXp6ZHEr416ygbiKYOd7TEWvvcQIeusHYMJGhTwF9y7sGnSwaWyFAiyoxzqW0PM/RjghPxF2pWReAowTEXnDh0xgcLs8l2YQmOrj3N7ByiqEoH0cARs4u78WgAVkoEDIDoOi3AkcLOHU60RIg5wC4ZuTC7FaHKQm8Hq1fQuSOBvX/sodmNJSB5geaF5CPIkUeecdMxieoRO5jz9bheL6/tXjrwCyX/UYBUcjCaWHljx1xiX6z9xEjkYAzbGVnB8pvLmyXm9ep+W8CmsSHQQY77Zx1zboxAV0w7ybMhQmfqdmmw3nEp1I0Z+FGO6M8LZdoyZnuzzBdjISicKRnpxzI9fPb+0oYXsNdyi+d3h9bm9MWYHFtPeIZfLwzmFDKy1ai3p+PDls1Llz4yyFpferxjnyjJDSEy9CaCx5m2cJPerq6Xm34eTrZt3PqxYO1XOwDYZrFlH1fWnpU38Y9HRze3lj0vOujZcXKuuXm3jP+s3KbZVra7y2EAAAAAASUVORK5CYII=" alt="Poetry">
38
+ <a href="https://github.com/astral-sh/uv">
39
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
40
+ </a>
41
+ <a href="https://github.com/astral-sh/ruff">
42
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
46
43
  </a>
47
- <a href="https://github.com/ambv/black">
48
- <img src="https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square" alt="black">
44
+ <a href="https://github.com/cuinixam/pypeline">
45
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/cuinixam/pypeline/refs/heads/main/assets/badge/v0.json" alt="pypeline">
49
46
  </a>
50
47
  <a href="https://github.com/pre-commit/pre-commit">
51
48
  <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
@@ -59,44 +56,33 @@ Description-Content-Type: text/markdown
59
56
  <img src="https://img.shields.io/pypi/l/kspl.svg?style=flat-square" alt="License">
60
57
  </p>
61
58
 
62
- KConfig GUI for Software Product Lines with multiple variants.
59
+ ---
63
60
 
64
- ## Installation
61
+ **Source Code**: <a href="https://github.com/cuinixam/kspl" target="_blank">https://github.com/cuinixam/kspl </a>
65
62
 
66
- Install this via pip (or your favourite package manager):
63
+ ---
67
64
 
68
- `pip install kspl`
65
+ KConfig GUI for Software Product Lines with multiple variants.
69
66
 
70
67
  ## Start developing
71
68
 
72
- The project uses Poetry for dependencies management and packaging.
73
- If you do not have Poetry installed, you can run the `boostrap.ps1` script.
74
- This will install Python and Poetry as configured in `scoopfile.json`.
75
-
76
- ```powershell
77
- Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
78
- .\bootstrap.ps1
79
- ```
80
-
81
- To install the development dependencies in a virtual environment, type:
69
+ The project uses UV for dependencies management and packaging and the [pypeline](https://github.com/cuinixam/pypeline) for streamlining the development workflow.
70
+ Use pipx (or your favorite package manager) to install the `pypeline` in an isolated environment:
82
71
 
83
72
  ```shell
84
- poetry install
73
+ pipx install pypeline-runner
85
74
  ```
86
75
 
87
- This will also generate a `poetry.lock` file, you should track this file in version control. To execute the test suite, call pytest inside Poetry's virtual environment via `poetry run`:
76
+ To bootstrap the project and run all the steps configured in the `pypeline.yaml` file, execute the following command:
88
77
 
89
78
  ```shell
90
- poetry run pytest
79
+ pypeline run
91
80
  ```
92
81
 
93
- Check out the Poetry documentation for more information on the available commands.
94
-
95
82
  For those using [VS Code](https://code.visualstudio.com/) there are tasks defined for the most common commands:
96
83
 
97
- - install development dependencies
98
84
  - run tests
99
- - run all checks configured for pre-commit
85
+ - run pre-commit checks (linters, formatters, etc.)
100
86
  - generate documentation
101
87
 
102
88
  See the `.vscode/tasks.json` for more details.
@@ -120,6 +106,8 @@ This project follows the [all-contributors](https://github.com/all-contributors/
120
106
 
121
107
  ## Credits
122
108
 
109
+ [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/copier-org/copier)
110
+
123
111
  This package was created with
124
112
  [Copier](https://copier.readthedocs.io/) and the
125
113
  [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
@@ -4,19 +4,19 @@
4
4
  <a href="https://github.com/cuinixam/kspl/actions/workflows/ci.yml?query=branch%3Amain">
5
5
  <img src="https://img.shields.io/github/actions/workflow/status/cuinixam/kspl/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
6
6
  </a>
7
- <a href="https://kspl.readthedocs.io">
8
- <img src="https://img.shields.io/readthedocs/kspl.svg?logo=read-the-docs&logoColor=fff&style=flat-square" alt="Documentation Status">
9
- </a>
10
7
  <a href="https://codecov.io/gh/cuinixam/kspl">
11
8
  <img src="https://img.shields.io/codecov/c/github/cuinixam/kspl.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
12
9
  </a>
13
10
  </p>
14
11
  <p align="center">
15
- <a href="https://python-poetry.org/">
16
- <img src="https://img.shields.io/badge/packaging-poetry-299bd7?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAASCAYAAABrXO8xAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJJSURBVHgBfZLPa1NBEMe/s7tNXoxW1KJQKaUHkXhQvHgW6UHQQ09CBS/6V3hKc/AP8CqCrUcpmop3Cx48eDB4yEECjVQrlZb80CRN8t6OM/teagVxYZi38+Yz853dJbzoMV3MM8cJUcLMSUKIE8AzQ2PieZzFxEJOHMOgMQQ+dUgSAckNXhapU/NMhDSWLs1B24A8sO1xrN4NECkcAC9ASkiIJc6k5TRiUDPhnyMMdhKc+Zx19l6SgyeW76BEONY9exVQMzKExGKwwPsCzza7KGSSWRWEQhyEaDXp6ZHEr416ygbiKYOd7TEWvvcQIeusHYMJGhTwF9y7sGnSwaWyFAiyoxzqW0PM/RjghPxF2pWReAowTEXnDh0xgcLs8l2YQmOrj3N7ByiqEoH0cARs4u78WgAVkoEDIDoOi3AkcLOHU60RIg5wC4ZuTC7FaHKQm8Hq1fQuSOBvX/sodmNJSB5geaF5CPIkUeecdMxieoRO5jz9bheL6/tXjrwCyX/UYBUcjCaWHljx1xiX6z9xEjkYAzbGVnB8pvLmyXm9ep+W8CmsSHQQY77Zx1zboxAV0w7ybMhQmfqdmmw3nEp1I0Z+FGO6M8LZdoyZnuzzBdjISicKRnpxzI9fPb+0oYXsNdyi+d3h9bm9MWYHFtPeIZfLwzmFDKy1ai3p+PDls1Llz4yyFpferxjnyjJDSEy9CaCx5m2cJPerq6Xm34eTrZt3PqxYO1XOwDYZrFlH1fWnpU38Y9HRze3lj0vOujZcXKuuXm3jP+s3KbZVra7y2EAAAAAASUVORK5CYII=" alt="Poetry">
12
+ <a href="https://github.com/astral-sh/uv">
13
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
14
+ </a>
15
+ <a href="https://github.com/astral-sh/ruff">
16
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
17
17
  </a>
18
- <a href="https://github.com/ambv/black">
19
- <img src="https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square" alt="black">
18
+ <a href="https://github.com/cuinixam/pypeline">
19
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/cuinixam/pypeline/refs/heads/main/assets/badge/v0.json" alt="pypeline">
20
20
  </a>
21
21
  <a href="https://github.com/pre-commit/pre-commit">
22
22
  <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
@@ -30,44 +30,33 @@
30
30
  <img src="https://img.shields.io/pypi/l/kspl.svg?style=flat-square" alt="License">
31
31
  </p>
32
32
 
33
- KConfig GUI for Software Product Lines with multiple variants.
33
+ ---
34
34
 
35
- ## Installation
35
+ **Source Code**: <a href="https://github.com/cuinixam/kspl" target="_blank">https://github.com/cuinixam/kspl </a>
36
36
 
37
- Install this via pip (or your favourite package manager):
37
+ ---
38
38
 
39
- `pip install kspl`
39
+ KConfig GUI for Software Product Lines with multiple variants.
40
40
 
41
41
  ## Start developing
42
42
 
43
- The project uses Poetry for dependencies management and packaging.
44
- If you do not have Poetry installed, you can run the `boostrap.ps1` script.
45
- This will install Python and Poetry as configured in `scoopfile.json`.
46
-
47
- ```powershell
48
- Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
49
- .\bootstrap.ps1
50
- ```
51
-
52
- To install the development dependencies in a virtual environment, type:
43
+ The project uses UV for dependencies management and packaging and the [pypeline](https://github.com/cuinixam/pypeline) for streamlining the development workflow.
44
+ Use pipx (or your favorite package manager) to install the `pypeline` in an isolated environment:
53
45
 
54
46
  ```shell
55
- poetry install
47
+ pipx install pypeline-runner
56
48
  ```
57
49
 
58
- This will also generate a `poetry.lock` file, you should track this file in version control. To execute the test suite, call pytest inside Poetry's virtual environment via `poetry run`:
50
+ To bootstrap the project and run all the steps configured in the `pypeline.yaml` file, execute the following command:
59
51
 
60
52
  ```shell
61
- poetry run pytest
53
+ pypeline run
62
54
  ```
63
55
 
64
- Check out the Poetry documentation for more information on the available commands.
65
-
66
56
  For those using [VS Code](https://code.visualstudio.com/) there are tasks defined for the most common commands:
67
57
 
68
- - install development dependencies
69
58
  - run tests
70
- - run all checks configured for pre-commit
59
+ - run pre-commit checks (linters, formatters, etc.)
71
60
  - generate documentation
72
61
 
73
62
  See the `.vscode/tasks.json` for more details.
@@ -91,6 +80,8 @@ This project follows the [all-contributors](https://github.com/all-contributors/
91
80
 
92
81
  ## Credits
93
82
 
83
+ [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/copier-org/copier)
84
+
94
85
  This package was created with
95
86
  [Copier](https://copier.readthedocs.io/) and the
96
87
  [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
@@ -0,0 +1,167 @@
1
+ [build-system]
2
+ build-backend = "poetry.core.masonry.api"
3
+
4
+ requires = [ "poetry-core>=2,<3" ]
5
+
6
+ [project]
7
+ name = "kspl"
8
+ version = "1.3.0"
9
+ description = "KConfig GUI for Software Product Lines with multiple variants."
10
+ readme = "README.md"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Cuinixam", email = "cuinixam@me.com" },
14
+ ]
15
+ requires-python = "<4.0,>=3.10"
16
+ classifiers = [
17
+ "Development Status :: 2 - Pre-Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Natural Language :: English",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Software Development :: Libraries",
27
+ ]
28
+
29
+ dependencies = [
30
+ "customtkinter>=5,<6",
31
+ "kconfiglib>=14,<15",
32
+ "py-app-dev>=2,<3",
33
+ ]
34
+ urls."Bug Tracker" = "https://github.com/cuinixam/kspl/issues"
35
+ urls.Changelog = "https://github.com/cuinixam/kspl/blob/main/CHANGELOG.md"
36
+ urls.repository = "https://github.com/cuinixam/kspl"
37
+ scripts.kspl = "kspl.main:main"
38
+
39
+ [dependency-groups]
40
+ dev = [
41
+ "pypeline-runner>=1,<2",
42
+ "pytest>=8,<9",
43
+ "pytest-cov>=6,<7",
44
+ "pre-commit>=4,<5",
45
+ "wrapt",
46
+ ]
47
+
48
+ [tool.ruff]
49
+ target-version = "py39"
50
+ line-length = 180
51
+ lint.select = [
52
+ "B", # flake8-bugbear
53
+ "D", # flake8-docstrings
54
+ "C4", # flake8-comprehensions
55
+ "S", # flake8-bandit
56
+ "F", # pyflake
57
+ "E", # pycodestyle
58
+ "W", # pycodestyle
59
+ "UP", # pyupgrade
60
+ "I", # isort
61
+ "RUF", # ruff specific
62
+ ]
63
+ lint.ignore = [
64
+ "D100", # Missing docstring in public module
65
+ "D101", # Missing docstring in public class
66
+ "D102", # Missing docstring in public method
67
+ "D103", # Missing docstring in public function
68
+ "D104", # Missing docstring in public package
69
+ "D105", # Missing docstring in magic method
70
+ "D106", # Missing docstring in public nested class
71
+ "D107", # Missing docstring in `__init__`
72
+ "D203", # 1 blank line required before class docstring
73
+ "D212", # Multi-line docstring summary should start at the first line
74
+ "D401", # First line of docstring should be in imperative mood
75
+ ]
76
+ lint.per-file-ignores."bootstrap.py" = [ "D200", "D205", "D417", "S603", "UP006", "UP035" ]
77
+ lint.per-file-ignores."conftest.py" = [ "D100" ]
78
+ lint.per-file-ignores."setup.py" = [ "D100" ]
79
+ lint.per-file-ignores."tests/**/*" = [
80
+ "D100",
81
+ "D101",
82
+ "D102",
83
+ "D103",
84
+ "D104",
85
+ "S101",
86
+ ]
87
+ lint.isort.known-first-party = [ "kspl", "tests" ]
88
+
89
+ [tool.pytest.ini_options]
90
+ addopts = """\
91
+ -v
92
+ -Wdefault
93
+ --cov=kspl
94
+ --cov-report=term
95
+ --cov-report=xml
96
+ """
97
+ pythonpath = [ "src" ]
98
+
99
+ [tool.coverage.run]
100
+ branch = true
101
+
102
+ [tool.coverage.paths]
103
+ source = [
104
+ "src",
105
+ ".tox/**/site-packages",
106
+ ]
107
+
108
+ [tool.coverage.report]
109
+ exclude_lines = [
110
+ "pragma: no cover",
111
+ "@overload",
112
+ "if TYPE_CHECKING",
113
+ "raise NotImplementedError",
114
+ 'if __name__ == "__main__":',
115
+ ]
116
+
117
+ [tool.mypy]
118
+ check_untyped_defs = true
119
+ disallow_any_generics = true
120
+ disallow_incomplete_defs = true
121
+ disallow_untyped_defs = true
122
+ mypy_path = "src/"
123
+ no_implicit_optional = true
124
+ show_error_codes = true
125
+ warn_unreachable = true
126
+ warn_unused_ignores = true
127
+ exclude = [
128
+ 'setup.py',
129
+ ]
130
+
131
+ [[tool.mypy.overrides]]
132
+ module = "tests.*"
133
+ allow_untyped_defs = true
134
+
135
+ [tool.semantic_release]
136
+ version_toml = [ "pyproject.toml:project.version" ]
137
+ version_variables = [
138
+ "src/kspl/__init__.py:__version__",
139
+ ]
140
+ build_command = """
141
+ pip install uv
142
+ uv lock
143
+ git add uv.lock
144
+ uv build
145
+ """
146
+
147
+ [tool.semantic_release.changelog]
148
+ exclude_commit_patterns = [
149
+ '''chore(?:\([^)]*?\))?: .+''',
150
+ '''ci(?:\([^)]*?\))?: .+''',
151
+ '''refactor(?:\([^)]*?\))?: .+''',
152
+ '''style(?:\([^)]*?\))?: .+''',
153
+ '''test(?:\([^)]*?\))?: .+''',
154
+ '''build\((?!deps\): .+)''',
155
+ '''Merged? .*''',
156
+ '''Initial [Cc]ommit.*''', # codespell:ignore
157
+ ]
158
+
159
+ [tool.semantic_release.changelog.environment]
160
+ keep_trailing_newline = true
161
+
162
+ [tool.semantic_release.branches.main]
163
+ match = "main"
164
+
165
+ [tool.semantic_release.branches.noop]
166
+ match = "(?!main$)"
167
+ prerelease = true
@@ -0,0 +1 @@
1
+ __version__ = "1.3.0"
@@ -1,9 +1,13 @@
1
- """Used to run main from the command line when run from this repository.
2
- This is required because kspl module is not visible when running
3
- from the repository."""
4
- import runpy
5
- import sys
6
- from pathlib import Path
7
-
8
- sys.path.insert(0, Path(__file__).parent.parent.absolute().as_posix())
9
- runpy.run_module("kspl.main", run_name="__main__")
1
+ """
2
+ Used to run main from the command line when run from this repository.
3
+
4
+ This is required because kspl module is not visible when running
5
+ from the repository.
6
+ """
7
+
8
+ import runpy
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ sys.path.insert(0, Path(__file__).parent.parent.absolute().as_posix())
13
+ runpy.run_module("kspl.main", run_name="__main__")
@@ -1,85 +1,88 @@
1
- from dataclasses import dataclass
2
- from pathlib import Path
3
- from typing import Any, Dict, List, Optional
4
-
5
- from py_app_dev.core.exceptions import UserNotificationException
6
- from py_app_dev.core.logging import logger
7
-
8
- from kspl.kconfig import EditableConfigElement, KConfig
9
-
10
-
11
- @dataclass
12
- class VariantViewData:
13
- """A variant is a set of configuration values for a KConfig model."""
14
-
15
- name: str
16
- config_dict: Dict[str, Any]
17
-
18
-
19
- @dataclass
20
- class VariantData:
21
- name: str
22
- config: KConfig
23
-
24
- def find_element(self, element_name: str) -> Optional[EditableConfigElement]:
25
- return self.config.find_element(element_name)
26
-
27
-
28
- class SPLKConfigData:
29
- def __init__(self, project_root_dir: Path) -> None:
30
- self.project_root_dir = project_root_dir.absolute()
31
- variant_config_files = self._search_variant_config_file(self.project_root_dir)
32
- if not self.kconfig_model_file.is_file():
33
- raise UserNotificationException(
34
- f"File {self.kconfig_model_file} does not exist."
35
- )
36
- self.model = KConfig(self.kconfig_model_file)
37
- if variant_config_files:
38
- self.variant_configs: List[VariantData] = [
39
- VariantData(
40
- self._get_variant_name(file), KConfig(self.kconfig_model_file, file)
41
- )
42
- for file in variant_config_files
43
- ]
44
- else:
45
- self.variant_configs = [VariantData("Default", self.model)]
46
- self.logger = logger.bind()
47
-
48
- @property
49
- def kconfig_model_file(self) -> Path:
50
- return self.project_root_dir / "KConfig"
51
-
52
- def get_elements(self) -> List[EditableConfigElement]:
53
- return self.model.elements
54
-
55
- def get_variants(self) -> List[VariantViewData]:
56
- variants = []
57
-
58
- for variant in self.variant_configs:
59
- variants.append(
60
- VariantViewData(
61
- variant.name,
62
- {
63
- config_elem.name: config_elem.value
64
- for config_elem in variant.config.elements
65
- if not config_elem.is_menu
66
- },
67
- )
68
- )
69
- return variants
70
-
71
- def _get_variant_name(self, file: Path) -> str:
72
- return file.relative_to(self.project_root_dir / "variants").parent.as_posix()
73
-
74
- def _search_variant_config_file(self, project_dir: Path) -> List[Path]:
75
- """
76
- Finds all files called 'config.txt' in the variants directory
77
- and returns a list with their paths.
78
- """
79
- return list((project_dir / "variants").glob("**/config.txt"))
80
-
81
- def find_variant_config(self, variant_name: str) -> Optional[VariantData]:
82
- for variant in self.variant_configs:
83
- if variant.name == variant_name:
84
- return variant
85
- return None
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+ from typing import Any
4
+
5
+ from py_app_dev.core.exceptions import UserNotificationException
6
+ from py_app_dev.core.logging import logger
7
+
8
+ from kspl.kconfig import EditableConfigElement, KConfig
9
+
10
+
11
+ @dataclass
12
+ class VariantViewData:
13
+ """A variant is a set of configuration values for a KConfig model."""
14
+
15
+ name: str
16
+ config_dict: dict[str, Any]
17
+
18
+
19
+ @dataclass
20
+ class VariantData:
21
+ name: str
22
+ config: KConfig
23
+
24
+ def find_element(self, element_name: str) -> EditableConfigElement | None:
25
+ return self.config.find_element(element_name)
26
+
27
+
28
+ class SPLKConfigData:
29
+ def __init__(self, project_root_dir: Path) -> None:
30
+ self.project_root_dir = project_root_dir.absolute()
31
+ variant_config_files = self._search_variant_config_file(self.project_root_dir)
32
+ if not self.kconfig_model_file.is_file():
33
+ raise UserNotificationException(f"File {self.kconfig_model_file} does not exist.")
34
+ self.model = KConfig(self.kconfig_model_file)
35
+ if variant_config_files:
36
+ self.variant_configs: list[VariantData] = [VariantData(self._get_variant_name(file), KConfig(self.kconfig_model_file, file)) for file in variant_config_files]
37
+ else:
38
+ self.variant_configs = [VariantData("Default", self.model)]
39
+ self.logger = logger.bind()
40
+
41
+ @property
42
+ def kconfig_model_file(self) -> Path:
43
+ return self.project_root_dir / "KConfig"
44
+
45
+ def get_elements(self) -> list[EditableConfigElement]:
46
+ return self.model.elements
47
+
48
+ def get_variants(self) -> list[VariantViewData]:
49
+ variants = []
50
+
51
+ for variant in self.variant_configs:
52
+ variants.append(
53
+ VariantViewData(
54
+ variant.name,
55
+ {config_elem.name: config_elem.value for config_elem in variant.config.elements if not config_elem.is_menu},
56
+ )
57
+ )
58
+ return variants
59
+
60
+ def _get_variant_name(self, file: Path) -> str:
61
+ return file.relative_to(self.project_root_dir / "variants").parent.as_posix()
62
+
63
+ def _search_variant_config_file(self, project_dir: Path) -> list[Path]:
64
+ """Finds all files called 'config.txt' in the variants directory and returns a list with their paths."""
65
+ return list((project_dir / "variants").glob("**/config.txt"))
66
+
67
+ def find_variant_config(self, variant_name: str) -> VariantData | None:
68
+ for variant in self.variant_configs:
69
+ if variant.name == variant_name:
70
+ return variant
71
+ return None
72
+
73
+ def refresh_data(self) -> None:
74
+ """Refresh the KConfig data by reloading all configuration files."""
75
+ variant_config_files = self._search_variant_config_file(self.project_root_dir)
76
+ if not self.kconfig_model_file.is_file():
77
+ raise UserNotificationException(f"File {self.kconfig_model_file} does not exist.")
78
+
79
+ # Reload the model
80
+ self.model = KConfig(self.kconfig_model_file)
81
+
82
+ # Reload variant configurations
83
+ if variant_config_files:
84
+ self.variant_configs = [VariantData(self._get_variant_name(file), KConfig(self.kconfig_model_file, file)) for file in variant_config_files]
85
+ else:
86
+ self.variant_configs = [VariantData("Default", self.model)]
87
+
88
+ self.logger.info(f"Refreshed data: found {len(self.variant_configs)} variants")