wexample-wex-addon-dev-python 0.0.47__tar.gz → 0.0.49__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 (48) hide show
  1. wexample_wex_addon_dev_python-0.0.49/PKG-INFO +143 -0
  2. wexample_wex_addon_dev_python-0.0.49/README.md +118 -0
  3. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/pyproject.toml +15 -4
  4. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/check.py +1 -0
  5. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/config_value/python_package_readme_config_value.py +243 -0
  6. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/file/__pycache__/__init__.py +0 -0
  7. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/file/python_package_toml_file.py +399 -0
  8. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/middleware/__init__.py +0 -0
  9. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/middleware/__pycache__/__init__.py +0 -0
  10. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/py.typed +0 -0
  11. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/resources/__init__.py +0 -0
  12. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/resources/readme_templates/__init__.py +0 -0
  13. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/resources/readme_templates/title.md.j2 +5 -0
  14. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/workdir/__init__.py +0 -0
  15. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/workdir/__pycache__/__init__.py +0 -0
  16. wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/workdir/python_package_workdir.py +383 -0
  17. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py +26 -13
  18. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/workdir/python_workdir.py +129 -61
  19. wexample_wex_addon_dev_python-0.0.47/PKG-INFO +0 -60
  20. wexample_wex_addon_dev_python-0.0.47/README.md +0 -38
  21. wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/config_value/python_package_readme_config_value.py +0 -92
  22. wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/file/python_package_toml_file.py +0 -303
  23. wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/workdir/python_package_workdir.py +0 -214
  24. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/__init__.py +0 -0
  25. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/__pycache__}/__init__.py +0 -0
  26. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands/code → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands}/__init__.py +0 -0
  27. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands/code/check → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands/code}/__init__.py +0 -0
  28. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands/examples → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands/code/check}/__init__.py +0 -0
  29. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/check/mypy.py +0 -0
  30. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/check/pylint.py +0 -0
  31. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/check/pyright.py +0 -0
  32. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/format/__init__.py +0 -0
  33. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/format/black.py +0 -0
  34. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/format/isort.py +0 -0
  35. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/code/format.py +0 -0
  36. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands/examples/utils → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands/examples}/__init__.py +0 -0
  37. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/commands/release → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands/examples/utils}/__init__.py +0 -0
  38. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/examples/utils/some_example_type.py +0 -0
  39. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/commands/examples/validate.py +0 -0
  40. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/config_value → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/commands/release}/__init__.py +0 -0
  41. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/const → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/config_value}/__init__.py +0 -0
  42. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/file → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/config_value/__pycache__}/__init__.py +0 -0
  43. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/middleware → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/const}/__init__.py +0 -0
  44. {wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/workdir → wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/const/__pycache__}/__init__.py +0 -0
  45. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/const/package.py +0 -0
  46. /wexample_wex_addon_dev_python-0.0.47/src/wexample_wex_addon_dev_python/py.typed → /wexample_wex_addon_dev_python-0.0.49/src/wexample_wex_addon_dev_python/file/__init__.py +0 -0
  47. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py +0 -0
  48. {wexample_wex_addon_dev_python-0.0.47 → wexample_wex_addon_dev_python-0.0.49}/src/wexample_wex_addon_dev_python/python_addon_manager.py +0 -0
@@ -0,0 +1,143 @@
1
+ Metadata-Version: 2.1
2
+ Name: wexample-wex-addon-dev-python
3
+ Version: 0.0.49
4
+ Summary: Python dev addon for wex
5
+ Author-Email: weeger <contact@wexample.com>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Project-URL: homepage, https://github.com/wexample/python-wex-dev-python
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: attrs>=23.1.0
13
+ Requires-Dist: cattrs>=23.1.0
14
+ Requires-Dist: jinja2
15
+ Requires-Dist: networkx
16
+ Requires-Dist: pylint
17
+ Requires-Dist: pyright
18
+ Requires-Dist: wexample-filestate-python==0.0.45
19
+ Requires-Dist: wexample-wex-addon-app==0.0.47
20
+ Requires-Dist: wexample-wex-core==6.0.49
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest; extra == "dev"
23
+ Requires-Dist: pytest-cov; extra == "dev"
24
+ Description-Content-Type: text/markdown
25
+
26
+ # wexample-wex-addon-dev-python
27
+
28
+ Version: 0.0.49
29
+
30
+ Python dev addon for wex
31
+
32
+ ## Code Quality & Typing
33
+
34
+ All the suite packages follow strict quality standards:
35
+
36
+ - **Type hints**: Full type coverage with mypy validation
37
+ - **Code formatting**: Enforced with black and isort
38
+ - **Linting**: Comprehensive checks with custom scripts and tools
39
+ - **Testing**: High test coverage requirements
40
+
41
+ These standards ensure reliability and maintainability across the suite.
42
+
43
+ ## Versioning & Compatibility Policy
44
+
45
+ Wexample packages follow **Semantic Versioning** (SemVer):
46
+
47
+ - **MAJOR**: Breaking changes
48
+ - **MINOR**: New features, backward compatible
49
+ - **PATCH**: Bug fixes, backward compatible
50
+
51
+ We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
52
+
53
+ ## Changelog
54
+
55
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history and release notes.
56
+
57
+ Major changes are documented with migration guides when applicable.
58
+
59
+ ## Migration Notes
60
+
61
+ When upgrading between major versions, refer to the migration guides in the documentation.
62
+
63
+ Breaking changes are clearly documented with upgrade paths and examples.
64
+
65
+ ## Known Limitations & Roadmap
66
+
67
+ Current limitations and planned features are tracked in the GitHub issues.
68
+
69
+ See the [project roadmap](https://github.com/wexample/python-wex-dev-python/issues) for upcoming features and improvements.
70
+
71
+ ## Security Policy
72
+
73
+ ### Reporting Vulnerabilities
74
+
75
+ If you discover a security vulnerability, please email security@wexample.com.
76
+
77
+ **Do not** open public issues for security vulnerabilities.
78
+
79
+ We take security seriously and will respond promptly to verified reports.
80
+
81
+ ## Privacy & Telemetry
82
+
83
+ This package does **not** collect any telemetry or usage data.
84
+
85
+ Your privacy is respected — no data is transmitted to external services.
86
+
87
+ ## Support Channels
88
+
89
+ - **GitHub Issues**: Bug reports and feature requests
90
+ - **GitHub Discussions**: Questions and community support
91
+ - **Documentation**: Comprehensive guides and API reference
92
+ - **Email**: contact@wexample.com for general inquiries
93
+
94
+ Community support is available through GitHub Discussions.
95
+
96
+ ## Contribution Guidelines
97
+
98
+ We welcome contributions to the Wexample suite!
99
+
100
+ ### How to Contribute
101
+
102
+ 1. **Fork** the repository
103
+ 2. **Create** a feature branch
104
+ 3. **Make** your changes
105
+ 4. **Test** thoroughly
106
+ 5. **Submit** a pull request
107
+
108
+ ## Maintainers & Authors
109
+
110
+ Maintained by the Wexample team and community contributors.
111
+
112
+ See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the full list of contributors.
113
+
114
+ ## License
115
+
116
+ MIT
117
+
118
+ ## Useful Links
119
+
120
+ - **Homepage**: https://github.com/wexample/python-wex-dev-python
121
+ - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
122
+ - **Issue Tracker**: https://github.com/wexample/python-wex-dev-python/issues
123
+ - **Discussions**: https://github.com/wexample/python-wex-dev-python/discussions
124
+ - **PyPI**: [pypi.org/project/wexample-wex-addon-dev-python](https://pypi.org/project/wexample-wex-addon-dev-python/)
125
+
126
+ ## Integration in the Suite
127
+
128
+ This package is part of the **Wexample Suite** — a collection of high-quality Python packages designed to work seamlessly together.
129
+
130
+ ### Related Packages
131
+
132
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
133
+
134
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
135
+
136
+ # About us
137
+
138
+ Wexample stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
139
+
140
+ This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
141
+
142
+ Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
143
+
@@ -0,0 +1,118 @@
1
+ # wexample-wex-addon-dev-python
2
+
3
+ Version: 0.0.49
4
+
5
+ Python dev addon for wex
6
+
7
+ ## Code Quality & Typing
8
+
9
+ All the suite packages follow strict quality standards:
10
+
11
+ - **Type hints**: Full type coverage with mypy validation
12
+ - **Code formatting**: Enforced with black and isort
13
+ - **Linting**: Comprehensive checks with custom scripts and tools
14
+ - **Testing**: High test coverage requirements
15
+
16
+ These standards ensure reliability and maintainability across the suite.
17
+
18
+ ## Versioning & Compatibility Policy
19
+
20
+ Wexample packages follow **Semantic Versioning** (SemVer):
21
+
22
+ - **MAJOR**: Breaking changes
23
+ - **MINOR**: New features, backward compatible
24
+ - **PATCH**: Bug fixes, backward compatible
25
+
26
+ We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
27
+
28
+ ## Changelog
29
+
30
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history and release notes.
31
+
32
+ Major changes are documented with migration guides when applicable.
33
+
34
+ ## Migration Notes
35
+
36
+ When upgrading between major versions, refer to the migration guides in the documentation.
37
+
38
+ Breaking changes are clearly documented with upgrade paths and examples.
39
+
40
+ ## Known Limitations & Roadmap
41
+
42
+ Current limitations and planned features are tracked in the GitHub issues.
43
+
44
+ See the [project roadmap](https://github.com/wexample/python-wex-dev-python/issues) for upcoming features and improvements.
45
+
46
+ ## Security Policy
47
+
48
+ ### Reporting Vulnerabilities
49
+
50
+ If you discover a security vulnerability, please email security@wexample.com.
51
+
52
+ **Do not** open public issues for security vulnerabilities.
53
+
54
+ We take security seriously and will respond promptly to verified reports.
55
+
56
+ ## Privacy & Telemetry
57
+
58
+ This package does **not** collect any telemetry or usage data.
59
+
60
+ Your privacy is respected — no data is transmitted to external services.
61
+
62
+ ## Support Channels
63
+
64
+ - **GitHub Issues**: Bug reports and feature requests
65
+ - **GitHub Discussions**: Questions and community support
66
+ - **Documentation**: Comprehensive guides and API reference
67
+ - **Email**: contact@wexample.com for general inquiries
68
+
69
+ Community support is available through GitHub Discussions.
70
+
71
+ ## Contribution Guidelines
72
+
73
+ We welcome contributions to the Wexample suite!
74
+
75
+ ### How to Contribute
76
+
77
+ 1. **Fork** the repository
78
+ 2. **Create** a feature branch
79
+ 3. **Make** your changes
80
+ 4. **Test** thoroughly
81
+ 5. **Submit** a pull request
82
+
83
+ ## Maintainers & Authors
84
+
85
+ Maintained by the Wexample team and community contributors.
86
+
87
+ See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the full list of contributors.
88
+
89
+ ## License
90
+
91
+ MIT
92
+
93
+ ## Useful Links
94
+
95
+ - **Homepage**: https://github.com/wexample/python-wex-dev-python
96
+ - **Documentation**: [docs.wexample.com](https://docs.wexample.com)
97
+ - **Issue Tracker**: https://github.com/wexample/python-wex-dev-python/issues
98
+ - **Discussions**: https://github.com/wexample/python-wex-dev-python/discussions
99
+ - **PyPI**: [pypi.org/project/wexample-wex-addon-dev-python](https://pypi.org/project/wexample-wex-addon-dev-python/)
100
+
101
+ ## Integration in the Suite
102
+
103
+ This package is part of the **Wexample Suite** — a collection of high-quality Python packages designed to work seamlessly together.
104
+
105
+ ### Related Packages
106
+
107
+ The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
108
+
109
+ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
110
+
111
+ # About us
112
+
113
+ Wexample stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
114
+
115
+ This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
116
+
117
+ Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
118
+
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
6
6
 
7
7
  [project]
8
8
  name = "wexample-wex-addon-dev-python"
9
- version = "0.0.47"
9
+ version = "0.0.49"
10
10
  description = "Python dev addon for wex"
11
11
  authors = [
12
12
  { name = "weeger", email = "contact@wexample.com" },
@@ -20,11 +20,13 @@ classifiers = [
20
20
  dependencies = [
21
21
  "attrs>=23.1.0",
22
22
  "cattrs>=23.1.0",
23
+ "jinja2",
24
+ "networkx",
23
25
  "pylint",
24
26
  "pyright",
25
- "wexample-filestate-python==0.0.43",
26
- "wexample-wex-addon-app==0.0.45",
27
- "wexample-wex-core==6.0.47",
27
+ "wexample-filestate-python==0.0.45",
28
+ "wexample-wex-addon-app==0.0.47",
29
+ "wexample-wex-core==6.0.49",
28
30
  ]
29
31
 
30
32
  [project.readme]
@@ -40,6 +42,7 @@ homepage = "https://github.com/wexample/python-wex-dev-python"
40
42
  [project.optional-dependencies]
41
43
  dev = [
42
44
  "pytest",
45
+ "pytest-cov",
43
46
  ]
44
47
 
45
48
  [tool.pdm]
@@ -50,3 +53,11 @@ package-dir = "src"
50
53
  packages = [
51
54
  { include = "wexample_wex_addon_dev_python", from = "src" },
52
55
  ]
56
+
57
+ [tool.setuptools.packages.find]
58
+ include = [
59
+ "*",
60
+ ]
61
+ exclude = [
62
+ "wexample_wex_addon_dev_python.testing*",
63
+ ]
@@ -44,6 +44,7 @@ def python__code__check(
44
44
  ) -> bool:
45
45
  """Check a Python file using various code quality tools."""
46
46
  from wexample_app.response.failure_response import FailureResponse
47
+
47
48
  from wexample_wex_addon_dev_python.commands.code.check.mypy import _code_check_mypy
48
49
  from wexample_wex_addon_dev_python.commands.code.check.pylint import (
49
50
  _code_check_pylint,
@@ -0,0 +1,243 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from wexample_filestate.config_value.readme_content_config_value import (
6
+ ReadmeContentConfigValue,
7
+ )
8
+ from wexample_helpers.classes.field import public_field
9
+ from wexample_helpers.decorator.base_class import base_class
10
+
11
+ if TYPE_CHECKING:
12
+ from wexample_wex_addon_dev_python.workdir.python_package_workdir import (
13
+ PythonPackageWorkdir,
14
+ )
15
+
16
+
17
+ @base_class
18
+ class PythonPackageReadmeContentConfigValue(ReadmeContentConfigValue):
19
+ workdir: PythonPackageWorkdir = public_field(
20
+ description="The python package workdir"
21
+ )
22
+
23
+ def get_templates(self) -> list[str] | None:
24
+ # Use TOMLDocument from the workdir
25
+ doc = self.workdir.get_project_config()
26
+ project = doc.get("project", {}) if isinstance(doc, dict) else {}
27
+
28
+ # Extract information
29
+ description = project.get("description", "")
30
+ python_version = project.get("requires-python", "")
31
+ dependencies = project.get("dependencies", [])
32
+ urls = (
33
+ project.get("urls", {}) if isinstance(project.get("urls", {}), dict) else {}
34
+ )
35
+ # Accept both lowercase and capitalized homepage key variants
36
+ homepage = urls.get("homepage") or urls.get("Homepage") or ""
37
+ license_field = project.get("license", {})
38
+ if isinstance(license_field, dict):
39
+ license_info = license_field.get("text", "") or license_field.get(
40
+ "file", ""
41
+ )
42
+ else:
43
+ license_info = str(license_field) if license_field else ""
44
+
45
+ # Format dependencies list
46
+ deps_list = "\n".join([f"- {dep}" for dep in dependencies])
47
+
48
+ # Prepare context for Jinja2 rendering
49
+ context = {
50
+ "package_name": self.workdir.get_package_name(),
51
+ "version": self.workdir.get_project_version(),
52
+ "description": description,
53
+ "python_version": python_version,
54
+ "dependencies": dependencies,
55
+ "deps_list": deps_list,
56
+ "homepage": homepage,
57
+ "license_info": license_info,
58
+ }
59
+
60
+ # Define fixed order of README sections
61
+ section_names = [
62
+ "title",
63
+ "table-of-contents",
64
+ "status-compatibility",
65
+ "prerequisites",
66
+ "installation",
67
+ "quickstart",
68
+ "basic-usage",
69
+ "configuration",
70
+ "logging",
71
+ "api-reference",
72
+ "examples",
73
+ "tests",
74
+ "code-quality",
75
+ "versioning",
76
+ "changelog",
77
+ "migration-notes",
78
+ "roadmap",
79
+ "troubleshooting",
80
+ "security",
81
+ "privacy",
82
+ "support",
83
+ "contribution-guidelines",
84
+ "maintainers",
85
+ "license",
86
+ "useful-links",
87
+ "suite-integration",
88
+ "compatibility-matrix",
89
+ "requirements",
90
+ "dependencies",
91
+ "links",
92
+ "suite-signature",
93
+ ]
94
+
95
+ # First pass: collect available sections (excluding title and table-of-contents)
96
+ available_sections = []
97
+ for section_name in section_names:
98
+ if section_name not in ["title", "table-of-contents"]:
99
+ # Check if section exists
100
+ if self._section_exists(section_name):
101
+ available_sections.append(
102
+ {
103
+ "name": section_name,
104
+ "title": self._section_name_to_title(section_name),
105
+ "anchor": section_name.replace("_", "-"),
106
+ }
107
+ )
108
+
109
+ # Add available sections to context for table-of-contents
110
+ context["available_sections"] = available_sections
111
+
112
+ # Render ordered sections (supports both .md and .md.j2)
113
+ rendered_content = ""
114
+ for section_name in section_names:
115
+ section_content = self._render_readme_section(section_name, context)
116
+ if section_content:
117
+ rendered_content += f"{section_content}\n\n"
118
+
119
+ return [rendered_content]
120
+
121
+ def _render_readme_section(self, section_name: str, context: dict) -> str | None:
122
+ """
123
+ Render a README section from .md or .md.j2 file with Jinja2 support.
124
+
125
+ Searches in three levels (in order):
126
+ 1. Package-level templates
127
+ 2. Suite-level templates
128
+ 3. Default templates (bundled with the module)
129
+
130
+ Tries .md.j2 first, then .md. Both formats support Jinja2 variables.
131
+
132
+ Args:
133
+ section_name: Name of the section (without extension)
134
+ context: Jinja2 context variables for rendering
135
+
136
+ Returns:
137
+ Rendered content or None if section file not found
138
+ """
139
+ from pathlib import Path
140
+ from jinja2 import Environment, FileSystemLoader, TemplateNotFound
141
+ from wexample_app.const.globals import WORKDIR_SETUP_DIR
142
+
143
+ workdir_path = self.workdir.get_path()
144
+
145
+ search_paths = [
146
+ workdir_path / WORKDIR_SETUP_DIR / "knowledge" / "readme", # Package-level
147
+ ]
148
+
149
+ # Package may have a suite.
150
+ suite_path = self.workdir.find_suite_workdir_path()
151
+ if suite_path is not None:
152
+ search_paths.append(
153
+ suite_path
154
+ / WORKDIR_SETUP_DIR
155
+ / "knowledge"
156
+ / "package-readme", # Suite-level
157
+ )
158
+
159
+ # Add default templates path (bundled with the module)
160
+ default_templates_path = (
161
+ Path(__file__).parent.parent / "resources" / "readme_templates"
162
+ )
163
+ search_paths.append(default_templates_path)
164
+
165
+ # Try .md.j2 first (Jinja2 template)
166
+ for search_path in search_paths:
167
+ if not search_path.exists():
168
+ continue
169
+
170
+ env = Environment(loader=FileSystemLoader(str(search_path)))
171
+ try:
172
+ template = env.get_template(f"{section_name}.md.j2")
173
+ return template.render(context)
174
+ except TemplateNotFound:
175
+ pass
176
+
177
+ # Try .md (static markdown, still rendered with Jinja2)
178
+ for search_path in search_paths:
179
+ md_path = search_path / f"{section_name}.md"
180
+ if md_path.exists():
181
+ content = md_path.read_text(encoding="utf-8")
182
+ env = Environment(loader=FileSystemLoader(str(search_path)))
183
+ template = env.from_string(content)
184
+ return template.render(context)
185
+
186
+ return None
187
+
188
+ def _section_exists(self, section_name: str) -> bool:
189
+ """
190
+ Check if a section file exists (.md or .md.j2).
191
+
192
+ Searches in three levels:
193
+ 1. Package-level templates
194
+ 2. Suite-level templates
195
+ 3. Default templates (bundled with the module)
196
+
197
+ Args:
198
+ section_name: Name of the section (without extension)
199
+
200
+ Returns:
201
+ True if section file exists, False otherwise
202
+ """
203
+ from pathlib import Path
204
+ from wexample_app.const.globals import WORKDIR_SETUP_DIR
205
+
206
+ workdir_path = self.workdir.get_path()
207
+
208
+ search_paths = [
209
+ workdir_path / WORKDIR_SETUP_DIR / "knowledge" / "readme",
210
+ ]
211
+
212
+ # Package may have a suite.
213
+ suite_path = self.workdir.find_suite_workdir_path()
214
+ if suite_path is not None:
215
+ search_paths.append(
216
+ suite_path / WORKDIR_SETUP_DIR / "knowledge" / "package-readme",
217
+ )
218
+
219
+ # Add default templates path (bundled with the module)
220
+ default_templates_path = (
221
+ Path(__file__).parent.parent / "resources" / "readme_templates"
222
+ )
223
+ search_paths.append(default_templates_path)
224
+
225
+ for search_path in search_paths:
226
+ if (search_path / f"{section_name}.md.j2").exists():
227
+ return True
228
+ if (search_path / f"{section_name}.md").exists():
229
+ return True
230
+
231
+ return False
232
+
233
+ def _section_name_to_title(self, section_name: str) -> str:
234
+ """
235
+ Convert section name to human-readable title.
236
+
237
+ Args:
238
+ section_name: Section name (e.g., "basic-usage")
239
+
240
+ Returns:
241
+ Human-readable title (e.g., "Basic Usage")
242
+ """
243
+ return section_name.replace("-", " ").replace("_", " ").title()