clear-skies-doc-builder 2.0.6__tar.gz → 2.0.8__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 (58) hide show
  1. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/CHANGELOG.md +16 -0
  2. clear_skies_doc_builder-2.0.8/LATEST_CHANGELOG.md +5 -0
  3. clear_skies_doc_builder-2.0.8/PKG-INFO +197 -0
  4. clear_skies_doc_builder-2.0.8/README.md +177 -0
  5. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/pyproject.toml +1 -1
  6. clear_skies_doc_builder-2.0.8/src/clearskies_doc_builder/build_callable.py +39 -0
  7. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/builders/builder.py +37 -1
  8. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/builders/module.py +38 -4
  9. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/builders/single_class.py +43 -13
  10. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/uv.lock +1 -1
  11. clear_skies_doc_builder-2.0.6/LATEST_CHANGELOG.md +0 -12
  12. clear_skies_doc_builder-2.0.6/PKG-INFO +0 -40
  13. clear_skies_doc_builder-2.0.6/README.md +0 -20
  14. clear_skies_doc_builder-2.0.6/src/clearskies_doc_builder/build_callable.py +0 -24
  15. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.copier-answers.yml +0 -0
  16. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.editorconfig +0 -0
  17. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.github/workflows/create-version.yaml +0 -0
  18. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.github/workflows/docs.yaml +0 -0
  19. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.github/workflows/run-tests.yml +0 -0
  20. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.github/workflows/tests-matrix.yaml +0 -0
  21. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.github/workflows/tests.yaml +0 -0
  22. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.gitignore +0 -0
  23. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.pre-commit-config.yaml +0 -0
  24. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.python-version +0 -0
  25. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/.vscode/settings.json +0 -0
  26. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/LICENSE +0 -0
  27. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/cliff.toml +0 -0
  28. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/ruff.toml +0 -0
  29. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/__init__.py +0 -0
  30. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/backends/__init__.py +0 -0
  31. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/backends/attribute_backend.py +0 -0
  32. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/backends/class_backend.py +0 -0
  33. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/backends/module_backend.py +0 -0
  34. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/backends/python.py +0 -0
  35. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/builders/__init__.py +0 -0
  36. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/builders/single_class_to_section.py +0 -0
  37. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/__init__.py +0 -0
  38. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/any.py +0 -0
  39. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/attribute.py +0 -0
  40. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/attributes.py +0 -0
  41. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/base_classes.py +0 -0
  42. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/class_column.py +0 -0
  43. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/method.py +0 -0
  44. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/module.py +0 -0
  45. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/columns/module_classes.py +0 -0
  46. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/configs/__init__.py +0 -0
  47. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/__init__.py +0 -0
  48. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/arg.py +0 -0
  49. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/attribute.py +0 -0
  50. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/attribute_reference.py +0 -0
  51. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/class_model.py +0 -0
  52. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/class_reference.py +0 -0
  53. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/method.py +0 -0
  54. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/method_reference.py +0 -0
  55. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/module.py +0 -0
  56. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/module_reference.py +0 -0
  57. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/models/property.py +0 -0
  58. {clear_skies_doc_builder-2.0.6 → clear_skies_doc_builder-2.0.8}/src/clearskies_doc_builder/prepare_doc_space.py +0 -0
@@ -5,12 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.8] - 2026-01-28
9
+
10
+ ### Added
11
+ - Add support for just headings
12
+
13
+ ## [2.0.7] - 2026-01-28
14
+
15
+ ### Added
16
+ - Add multi hierarchy
17
+
18
+ ### Changed
19
+ - Bump version to v2.0.7 by @github-actions[bot]
20
+
8
21
  ## [2.0.6] - 2026-01-28
9
22
 
10
23
  ### Added
11
24
  - Add some basic tests
12
25
 
13
26
  ### Changed
27
+ - Bump version to v2.0.6 by @github-actions[bot]
14
28
  - Update to latest copier version
15
29
  - Update dependencies
16
30
 
@@ -69,6 +83,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
69
83
  * @ made their first contribution
70
84
  * @tnijboer made their first contribution in [#1](https://github.com/clearskies-py/doc-builder/pull/1)
71
85
  * @cmancone made their first contribution
86
+ [2.0.8]: https://github.com/clearskies-py/doc-builder/compare/v2.0.7..v2.0.8
87
+ [2.0.7]: https://github.com/clearskies-py/doc-builder/compare/v2.0.6..v2.0.7
72
88
  [2.0.6]: https://github.com/clearskies-py/doc-builder/compare/v2.0.5..v2.0.6
73
89
  [2.0.5]: https://github.com/clearskies-py/doc-builder/compare/v2.0.4..v2.0.5
74
90
  [2.0.4]: https://github.com/clearskies-py/doc-builder/compare/v2.0.3..v2.0.4
@@ -0,0 +1,5 @@
1
+ ## [2.0.8] - 2026-01-28
2
+
3
+ ### Added
4
+ - Add support for just headings
5
+
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.4
2
+ Name: clear-skies-doc-builder
3
+ Version: 2.0.8
4
+ Summary: The docbuilder for all 'official' clearskies plugins (as well as the main clearskies docs)
5
+ Project-URL: repository, https://github.com/clearskies-py/docs
6
+ Project-URL: issues, https://github.com/clearskies-py/docs/issues
7
+ Project-URL: changelog, https://github.com/clearskies-py/docs/blob/main/CHANGELOG.md
8
+ Author-email: Conor Mancone <cmancone@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Requires-Python: <4.0,>=3.11
16
+ Requires-Dist: clear-skies<3.0.0,>=2.0.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: types-requests>=2.32.4; extra == 'dev'
19
+ Description-Content-Type: text/markdown
20
+
21
+ # docs
22
+
23
+ The documentation builder for clearskies and related plugins
24
+
25
+ ## Overview
26
+
27
+ Each "official" clearskies module (including the core clearskies library itself) has the documentation primarily written in the codebase as docblocks. The documentation site is then built by extracting these docblocks and stitching them together. To be clear, this isn't about the low-level "API" documentation that describes every single class/method in the framework. Rather, this is about the primary documentation site itself (clearskies.info) which is focused on high-level use cases and examples of the primary configuration options. As a result, it's not a simple matter of just iterating over the classes/methods and building documentation. To build a coherent documentation site, each plugin has a configuration file that basically outlines the final "structure" or organization of the resulting documentation, as well as the name of a builder class that will combine that configuration information with the codebase itself to create the actual docs.
28
+
29
+ The docs themselves (in the source code) are all written with markdown. This documentation builder then takes that markdwon and adds the necessary headers/etc so to make them valid files for [Jekyll](https://jekyllrb.com/), the builder for the current documentation site. The site itself is hosted in S3, so building an actual documentation site means:
30
+
31
+ 1. Properly documenting everything inside of the source code via markdown.
32
+ 2. Creating a config file (`docs/python/config.json`) to map source code docs to Jekyll files.
33
+ 3. Creating a skeleton of a Jekyll site in the `doc/jekyll` folder of the plugin.
34
+ 4. Installing this doc builder via `poetry add clear-skies-doc-builder`.
35
+ 5. Run the doc builder.
36
+ 6. Build with Jekyll.
37
+ 7. Push to the appropriate subfolder via S3.
38
+ 8. (Only once) Update the main clearskies doc site to know about the new subfolder for this plugin.
39
+
40
+ Of course, we want the Jekyll sites to be consistent with eachother in terms of style/look. In the long run we'll probably have this doc builder also bootstrap the Jekyll site, but for now you just have to manually setup the Jekyll build using the main clearskies repo as a template.
41
+
42
+ ## Configuration File Structure
43
+
44
+ The `config.json` file defines the documentation structure using a tree of entries. Each entry specifies a documentation section with its source class and builder.
45
+
46
+ ### Basic Structure
47
+
48
+ ```json
49
+ {
50
+ "tree": [
51
+ {
52
+ "title": "Section Title",
53
+ "source": "package.module.ClassName",
54
+ "builder": "clearskies_doc_builder.builders.Module",
55
+ "classes": ["package.module.Class1", "package.module.Class2"]
56
+ }
57
+ ]
58
+ }
59
+ ```
60
+
61
+ ### Nested Hierarchy (Parent/Grand-Parent)
62
+
63
+ The doc builder supports up to 3 levels of navigation hierarchy using `parent` and `grand_parent` fields. This is useful for organizing documentation of submodules under a common heading.
64
+
65
+ #### Two-Level Hierarchy (Parent) - Module with Classes
66
+
67
+ Use this when you want to document a submodule's classes under a parent section:
68
+
69
+ ```json
70
+ {
71
+ "tree": [
72
+ {
73
+ "title": "Cursors",
74
+ "source": "clearskies.cursors.Cursor",
75
+ "builder": "clearskies_doc_builder.builders.Module",
76
+ "classes": [
77
+ "clearskies.cursors.MemoryCursor",
78
+ "clearskies.cursors.FileCursor"
79
+ ]
80
+ },
81
+ {
82
+ "title": "From Environment",
83
+ "source": "clearskies.cursors.from_environment.FromEnvironmentBase",
84
+ "builder": "clearskies_doc_builder.builders.Module",
85
+ "parent": "Cursors",
86
+ "classes": [
87
+ "clearskies.cursors.from_environment.EnvCursor",
88
+ "clearskies.cursors.from_environment.SecretsCursor"
89
+ ]
90
+ }
91
+ ]
92
+ }
93
+ ```
94
+
95
+ This creates:
96
+ - `docs/cursors/index.md` - Parent section with overview
97
+ - `docs/cursors/memory-cursor.md` - Class documentation
98
+ - `docs/cursors/file-cursor.md` - Class documentation
99
+ - `docs/cursors/from-environment/index.md` - Submodule section with `parent: Cursors`
100
+ - `docs/cursors/from-environment/env-cursor.md` - Class with `parent: From Environment`
101
+ - `docs/cursors/from-environment/secrets-cursor.md` - Class with `parent: From Environment`
102
+
103
+ #### Three-Level Hierarchy (Grand-Parent)
104
+
105
+ For deeper nesting, use `grand_parent` to create a third level:
106
+
107
+ ```json
108
+ {
109
+ "tree": [
110
+ {
111
+ "title": "Cursors",
112
+ "source": "clearskies.cursors.Cursor",
113
+ "builder": "clearskies_doc_builder.builders.Module",
114
+ "classes": ["clearskies.cursors.MemoryCursor"]
115
+ },
116
+ {
117
+ "title": "From Environment",
118
+ "source": "clearskies.cursors.from_environment.FromEnvironmentBase",
119
+ "builder": "clearskies_doc_builder.builders.SingleClass",
120
+ "parent": "Cursors"
121
+ },
122
+ {
123
+ "title": "AWS Secrets",
124
+ "source": "clearskies.cursors.from_environment.aws.AWSSecretsBase",
125
+ "builder": "clearskies_doc_builder.builders.Module",
126
+ "parent": "From Environment",
127
+ "grand_parent": "Cursors",
128
+ "classes": [
129
+ "clearskies.cursors.from_environment.aws.SecretsManagerCursor",
130
+ "clearskies.cursors.from_environment.aws.ParameterStoreCursor"
131
+ ]
132
+ }
133
+ ]
134
+ }
135
+ ```
136
+
137
+ This creates:
138
+ - `docs/cursors/index.md` - Grand-parent section
139
+ - `docs/cursors/from-environment/index.md` - Parent section with `parent: Cursors`
140
+ - `docs/cursors/from-environment/aws-secrets/index.md` - Child section with `parent: From Environment` and `grand_parent: Cursors`
141
+ - `docs/cursors/from-environment/aws-secrets/secrets-manager-cursor.md` - Class documentation
142
+
143
+ The `grand_parent` field enables the Jekyll "just-the-docs" theme's three-level navigation, allowing you to document submodule classes under their logical grouping.
144
+
145
+ #### Parent-Only Sections (No Classes)
146
+
147
+ You can create a parent section that only serves as a navigation container without documenting any classes directly. This is useful when you want to group multiple submodules under a common heading:
148
+
149
+ ```json
150
+ {
151
+ "tree": [
152
+ {
153
+ "title": "Cursors",
154
+ "source": "clearskies.cursors.Cursor",
155
+ "builder": "clearskies_doc_builder.builders.Module"
156
+ },
157
+ {
158
+ "title": "IAM Cursors",
159
+ "source": "clearskies.cursors.iam.IamCursor",
160
+ "builder": "clearskies_doc_builder.builders.Module",
161
+ "parent": "Cursors",
162
+ "classes": ["clearskies.cursors.iam.RdsMysql"]
163
+ },
164
+ {
165
+ "title": "Port Forwarding",
166
+ "source": "clearskies.cursors.port_forwarding.PortForwarder",
167
+ "builder": "clearskies_doc_builder.builders.Module",
168
+ "parent": "Cursors",
169
+ "classes": ["clearskies.cursors.port_forwarding.Ssm"]
170
+ }
171
+ ]
172
+ }
173
+ ```
174
+
175
+ Note that the "Cursors" entry has no `classes` field - it just creates an index page with the overview from the source class docblock. The child sections ("IAM Cursors" and "Port Forwarding") will appear as sub-navigation items under "Cursors".
176
+
177
+ #### Using SingleClass for Individual Classes
178
+
179
+ You can also use `SingleClass` builder for documenting individual classes within a hierarchy:
180
+
181
+ ```json
182
+ {
183
+ "tree": [
184
+ {
185
+ "title": "Cursors",
186
+ "source": "clearskies.cursors.Cursor",
187
+ "builder": "clearskies_doc_builder.builders.SingleClass"
188
+ },
189
+ {
190
+ "title": "Environment Cursor",
191
+ "source": "clearskies.cursors.from_environment.EnvironmentCursor",
192
+ "builder": "clearskies_doc_builder.builders.SingleClass",
193
+ "parent": "Cursors"
194
+ }
195
+ ]
196
+ }
197
+ ```
@@ -0,0 +1,177 @@
1
+ # docs
2
+
3
+ The documentation builder for clearskies and related plugins
4
+
5
+ ## Overview
6
+
7
+ Each "official" clearskies module (including the core clearskies library itself) has the documentation primarily written in the codebase as docblocks. The documentation site is then built by extracting these docblocks and stitching them together. To be clear, this isn't about the low-level "API" documentation that describes every single class/method in the framework. Rather, this is about the primary documentation site itself (clearskies.info) which is focused on high-level use cases and examples of the primary configuration options. As a result, it's not a simple matter of just iterating over the classes/methods and building documentation. To build a coherent documentation site, each plugin has a configuration file that basically outlines the final "structure" or organization of the resulting documentation, as well as the name of a builder class that will combine that configuration information with the codebase itself to create the actual docs.
8
+
9
+ The docs themselves (in the source code) are all written with markdown. This documentation builder then takes that markdwon and adds the necessary headers/etc so to make them valid files for [Jekyll](https://jekyllrb.com/), the builder for the current documentation site. The site itself is hosted in S3, so building an actual documentation site means:
10
+
11
+ 1. Properly documenting everything inside of the source code via markdown.
12
+ 2. Creating a config file (`docs/python/config.json`) to map source code docs to Jekyll files.
13
+ 3. Creating a skeleton of a Jekyll site in the `doc/jekyll` folder of the plugin.
14
+ 4. Installing this doc builder via `poetry add clear-skies-doc-builder`.
15
+ 5. Run the doc builder.
16
+ 6. Build with Jekyll.
17
+ 7. Push to the appropriate subfolder via S3.
18
+ 8. (Only once) Update the main clearskies doc site to know about the new subfolder for this plugin.
19
+
20
+ Of course, we want the Jekyll sites to be consistent with eachother in terms of style/look. In the long run we'll probably have this doc builder also bootstrap the Jekyll site, but for now you just have to manually setup the Jekyll build using the main clearskies repo as a template.
21
+
22
+ ## Configuration File Structure
23
+
24
+ The `config.json` file defines the documentation structure using a tree of entries. Each entry specifies a documentation section with its source class and builder.
25
+
26
+ ### Basic Structure
27
+
28
+ ```json
29
+ {
30
+ "tree": [
31
+ {
32
+ "title": "Section Title",
33
+ "source": "package.module.ClassName",
34
+ "builder": "clearskies_doc_builder.builders.Module",
35
+ "classes": ["package.module.Class1", "package.module.Class2"]
36
+ }
37
+ ]
38
+ }
39
+ ```
40
+
41
+ ### Nested Hierarchy (Parent/Grand-Parent)
42
+
43
+ The doc builder supports up to 3 levels of navigation hierarchy using `parent` and `grand_parent` fields. This is useful for organizing documentation of submodules under a common heading.
44
+
45
+ #### Two-Level Hierarchy (Parent) - Module with Classes
46
+
47
+ Use this when you want to document a submodule's classes under a parent section:
48
+
49
+ ```json
50
+ {
51
+ "tree": [
52
+ {
53
+ "title": "Cursors",
54
+ "source": "clearskies.cursors.Cursor",
55
+ "builder": "clearskies_doc_builder.builders.Module",
56
+ "classes": [
57
+ "clearskies.cursors.MemoryCursor",
58
+ "clearskies.cursors.FileCursor"
59
+ ]
60
+ },
61
+ {
62
+ "title": "From Environment",
63
+ "source": "clearskies.cursors.from_environment.FromEnvironmentBase",
64
+ "builder": "clearskies_doc_builder.builders.Module",
65
+ "parent": "Cursors",
66
+ "classes": [
67
+ "clearskies.cursors.from_environment.EnvCursor",
68
+ "clearskies.cursors.from_environment.SecretsCursor"
69
+ ]
70
+ }
71
+ ]
72
+ }
73
+ ```
74
+
75
+ This creates:
76
+ - `docs/cursors/index.md` - Parent section with overview
77
+ - `docs/cursors/memory-cursor.md` - Class documentation
78
+ - `docs/cursors/file-cursor.md` - Class documentation
79
+ - `docs/cursors/from-environment/index.md` - Submodule section with `parent: Cursors`
80
+ - `docs/cursors/from-environment/env-cursor.md` - Class with `parent: From Environment`
81
+ - `docs/cursors/from-environment/secrets-cursor.md` - Class with `parent: From Environment`
82
+
83
+ #### Three-Level Hierarchy (Grand-Parent)
84
+
85
+ For deeper nesting, use `grand_parent` to create a third level:
86
+
87
+ ```json
88
+ {
89
+ "tree": [
90
+ {
91
+ "title": "Cursors",
92
+ "source": "clearskies.cursors.Cursor",
93
+ "builder": "clearskies_doc_builder.builders.Module",
94
+ "classes": ["clearskies.cursors.MemoryCursor"]
95
+ },
96
+ {
97
+ "title": "From Environment",
98
+ "source": "clearskies.cursors.from_environment.FromEnvironmentBase",
99
+ "builder": "clearskies_doc_builder.builders.SingleClass",
100
+ "parent": "Cursors"
101
+ },
102
+ {
103
+ "title": "AWS Secrets",
104
+ "source": "clearskies.cursors.from_environment.aws.AWSSecretsBase",
105
+ "builder": "clearskies_doc_builder.builders.Module",
106
+ "parent": "From Environment",
107
+ "grand_parent": "Cursors",
108
+ "classes": [
109
+ "clearskies.cursors.from_environment.aws.SecretsManagerCursor",
110
+ "clearskies.cursors.from_environment.aws.ParameterStoreCursor"
111
+ ]
112
+ }
113
+ ]
114
+ }
115
+ ```
116
+
117
+ This creates:
118
+ - `docs/cursors/index.md` - Grand-parent section
119
+ - `docs/cursors/from-environment/index.md` - Parent section with `parent: Cursors`
120
+ - `docs/cursors/from-environment/aws-secrets/index.md` - Child section with `parent: From Environment` and `grand_parent: Cursors`
121
+ - `docs/cursors/from-environment/aws-secrets/secrets-manager-cursor.md` - Class documentation
122
+
123
+ The `grand_parent` field enables the Jekyll "just-the-docs" theme's three-level navigation, allowing you to document submodule classes under their logical grouping.
124
+
125
+ #### Parent-Only Sections (No Classes)
126
+
127
+ You can create a parent section that only serves as a navigation container without documenting any classes directly. This is useful when you want to group multiple submodules under a common heading:
128
+
129
+ ```json
130
+ {
131
+ "tree": [
132
+ {
133
+ "title": "Cursors",
134
+ "source": "clearskies.cursors.Cursor",
135
+ "builder": "clearskies_doc_builder.builders.Module"
136
+ },
137
+ {
138
+ "title": "IAM Cursors",
139
+ "source": "clearskies.cursors.iam.IamCursor",
140
+ "builder": "clearskies_doc_builder.builders.Module",
141
+ "parent": "Cursors",
142
+ "classes": ["clearskies.cursors.iam.RdsMysql"]
143
+ },
144
+ {
145
+ "title": "Port Forwarding",
146
+ "source": "clearskies.cursors.port_forwarding.PortForwarder",
147
+ "builder": "clearskies_doc_builder.builders.Module",
148
+ "parent": "Cursors",
149
+ "classes": ["clearskies.cursors.port_forwarding.Ssm"]
150
+ }
151
+ ]
152
+ }
153
+ ```
154
+
155
+ Note that the "Cursors" entry has no `classes` field - it just creates an index page with the overview from the source class docblock. The child sections ("IAM Cursors" and "Port Forwarding") will appear as sub-navigation items under "Cursors".
156
+
157
+ #### Using SingleClass for Individual Classes
158
+
159
+ You can also use `SingleClass` builder for documenting individual classes within a hierarchy:
160
+
161
+ ```json
162
+ {
163
+ "tree": [
164
+ {
165
+ "title": "Cursors",
166
+ "source": "clearskies.cursors.Cursor",
167
+ "builder": "clearskies_doc_builder.builders.SingleClass"
168
+ },
169
+ {
170
+ "title": "Environment Cursor",
171
+ "source": "clearskies.cursors.from_environment.EnvironmentCursor",
172
+ "builder": "clearskies_doc_builder.builders.SingleClass",
173
+ "parent": "Cursors"
174
+ }
175
+ ]
176
+ }
177
+ ```
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "clear-skies-doc-builder"
3
3
  description = "The docbuilder for all 'official' clearskies plugins (as well as the main clearskies docs)"
4
- version = "2.0.6"
4
+ version = "2.0.8"
5
5
  license = "MIT"
6
6
  readme = "./README.md"
7
7
  authors = [{name = "Conor Mancone", email = "cmancone@gmail.com"}]
@@ -0,0 +1,39 @@
1
+ from typing import Any
2
+
3
+ from clearskies_doc_builder import models
4
+ from clearskies_doc_builder.prepare_doc_space import prepare_doc_space
5
+
6
+
7
+ def build_callable(modules: models.Module, classes: models.Class, config: dict[str, Any], project_root: str):
8
+ doc_root = prepare_doc_space(project_root)
9
+ nav_order_parent_count: dict[str, int] = {}
10
+
11
+ for index, branch in enumerate(config["tree"]):
12
+ # For nav_order tracking, we need to track by the immediate parent
13
+ # If there's a grand_parent, the parent is the immediate container
14
+ # If there's only a parent, that's the immediate container
15
+ # If neither, it's a top-level item (doesn't need tracking)
16
+ parent = branch.get("parent")
17
+ grand_parent = branch.get("grand_parent")
18
+
19
+ # Determine nav_order based on hierarchy level
20
+ if parent or grand_parent:
21
+ # Child items: track by their immediate parent
22
+ nav_order_title_tracker = parent
23
+ if nav_order_title_tracker not in nav_order_parent_count:
24
+ nav_order_parent_count[nav_order_title_tracker] = 0
25
+ nav_order_parent_count[nav_order_title_tracker] += 1
26
+ nav_order = nav_order_parent_count[nav_order_title_tracker]
27
+ else:
28
+ # Top-level items: use index-based nav_order
29
+ nav_order = index + 2
30
+
31
+ builder_class = classes.find("import_path=" + branch["builder"]).type
32
+ builder = builder_class(
33
+ branch,
34
+ modules,
35
+ classes,
36
+ doc_root,
37
+ nav_order=nav_order,
38
+ )
39
+ builder.build()
@@ -30,6 +30,40 @@ class Builder:
30
30
  with output_file.open(mode="w") as doc_file:
31
31
  doc_file.write(doc)
32
32
 
33
+ def make_index_from_class_overview_with_hierarchy(
34
+ self, title_snake_case, source_class, section_folder_path, section_name, parent=None, grand_parent=None
35
+ ):
36
+ """
37
+ Create an index file for a module section with support for nested hierarchy.
38
+
39
+ This method creates the index.md file for a module section, supporting up to 3 levels
40
+ of navigation hierarchy (grand_parent -> parent -> current).
41
+
42
+ Args:
43
+ title_snake_case: The snake-case version of the title for the filename
44
+ source_class: The source class to extract documentation from
45
+ section_folder_path: Path to the section folder
46
+ section_name: The section name for permalink generation
47
+ parent: Optional parent title for 2-level hierarchy
48
+ grand_parent: Optional grand_parent title for 3-level hierarchy
49
+ """
50
+ filename = "index"
51
+ section_folder_path.mkdir(parents=True, exist_ok=True)
52
+
53
+ # Use instance attributes if not provided as arguments
54
+ parent = parent if parent is not None else getattr(self, "parent", None)
55
+ grand_parent = grand_parent if grand_parent is not None else getattr(self, "grand_parent", None)
56
+
57
+ doc = self.build_header(self.title, filename, section_name, parent, self.nav_order, True, grand_parent)
58
+ (elevator_pitch, overview) = self.parse_overview_doc(
59
+ self.raw_docblock_to_md(source_class.doc).lstrip("\n").lstrip(" ")
60
+ )
61
+ doc += f"\n\n# {self.title}\n\n{elevator_pitch}\n\n## Overview\n\n{overview}"
62
+
63
+ output_file = section_folder_path / f"{filename}.md"
64
+ with output_file.open(mode="w") as doc_file:
65
+ doc_file.write(doc)
66
+
33
67
  def parse_overview_doc(self, overview_doc):
34
68
  parts = overview_doc.lstrip("\n").split("\n", 1)
35
69
  if len(parts) < 2:
@@ -105,7 +139,7 @@ class Builder:
105
139
  self._attribute_cache[source_class.source_file] = doc_strings
106
140
  return doc_strings
107
141
 
108
- def build_header(self, title, filename, section_name, parent, nav_order, has_children):
142
+ def build_header(self, title, filename, section_name, parent, nav_order, has_children, grand_parent=None):
109
143
  permalink = "/docs/" + (f"{section_name}/" if section_name else "") + f"{filename}.html"
110
144
  header = f"""---
111
145
  layout: default
@@ -113,6 +147,8 @@ title: {title}
113
147
  permalink: {permalink}
114
148
  nav_order: {nav_order}
115
149
  """
150
+ if grand_parent:
151
+ header += f"grand_parent: {grand_parent}\n"
116
152
  if parent:
117
153
  header += f"parent: {parent}\n"
118
154
  if has_children:
@@ -9,16 +9,45 @@ from .builder import Builder
9
9
  class Module(Builder):
10
10
  def __init__(self, branch, modules, classes, doc_root, nav_order):
11
11
  super().__init__(branch, modules, classes, doc_root, nav_order)
12
- self.class_list = branch["classes"]
12
+ self.class_list = branch.get("classes", [])
13
13
  self.args_to_additional_attributes_map = branch.get("args_to_additional_attributes_map", {})
14
+ self.parent = branch.get("parent", False)
15
+ self.grand_parent = branch.get("grand_parent", False)
14
16
 
15
17
  def build(self):
16
18
  title_snake_case = clearskies.functional.string.title_case_to_snake_case(self.title.replace(" ", "")).replace(
17
19
  "_", "-"
18
20
  )
19
- section_folder_path = self.doc_root / title_snake_case
21
+
22
+ # Determine the section folder path based on hierarchy
23
+ if self.grand_parent:
24
+ # Three-level hierarchy: grand_parent/parent/title/
25
+ grand_parent_snake = (
26
+ clearskies.functional.string.title_case_to_snake_case(self.grand_parent)
27
+ .replace("_", "-")
28
+ .replace(" ", "")
29
+ )
30
+ parent_snake = (
31
+ clearskies.functional.string.title_case_to_snake_case(self.parent).replace("_", "-").replace(" ", "")
32
+ )
33
+ section_name = f"{grand_parent_snake}/{parent_snake}/{title_snake_case}"
34
+ section_folder_path = self.doc_root / grand_parent_snake / parent_snake / title_snake_case
35
+ elif self.parent:
36
+ # Two-level hierarchy: parent/title/
37
+ parent_snake = (
38
+ clearskies.functional.string.title_case_to_snake_case(self.parent).replace("_", "-").replace(" ", "")
39
+ )
40
+ section_name = f"{parent_snake}/{title_snake_case}"
41
+ section_folder_path = self.doc_root / parent_snake / title_snake_case
42
+ else:
43
+ # Top-level: title/
44
+ section_name = title_snake_case
45
+ section_folder_path = self.doc_root / title_snake_case
46
+
20
47
  source_class = self.classes.find(f"import_path={self.source}")
21
- self.make_index_from_class_overview(title_snake_case, source_class, section_folder_path)
48
+ self.make_index_from_class_overview_with_hierarchy(
49
+ title_snake_case, source_class, section_folder_path, section_name
50
+ )
22
51
 
23
52
  default_args = self.default_args()
24
53
 
@@ -28,7 +57,12 @@ class Module(Builder):
28
57
  source_class = self.classes.find(f"import_path={class_name}")
29
58
  title = source_class.name
30
59
  filename = clearskies.functional.string.title_case_to_snake_case(source_class.name).replace("_", "-")
31
- class_doc = self.build_header(source_class.name, filename, title_snake_case, self.title, nav_order, False)
60
+ # For classes within a module, the module title becomes the parent
61
+ # and if the module has a parent, that becomes the grand_parent
62
+ class_grand_parent = self.parent if self.parent else None
63
+ class_doc = self.build_header(
64
+ source_class.name, filename, section_name, self.title, nav_order, False, class_grand_parent
65
+ )
32
66
  (elevator_pitch, overview) = self.parse_overview_doc(
33
67
  self.raw_docblock_to_md(source_class.doc).lstrip("\n").lstrip(" ")
34
68
  )
@@ -12,21 +12,44 @@ class SingleClass(Builder):
12
12
  self.additional_attribute_sources = branch.get("additional_attribute_sources", [])
13
13
  self.args_to_additional_attributes_map = branch.get("args_to_additional_attributes_map", {})
14
14
  self.parent = branch.get("parent", False)
15
+ self.grand_parent = branch.get("grand_parent", False)
15
16
 
16
17
  def build(self):
17
- section_name = (
18
- clearskies.functional.string.title_case_to_snake_case(self.parent if self.parent else self.title)
19
- .replace("_", "-")
20
- .replace(" ", "")
21
- )
22
- section_folder_path = self.doc_root / section_name
23
- section_folder_path.mkdir(exist_ok=True)
18
+ # Determine the section folder path based on hierarchy
19
+ if self.grand_parent:
20
+ # Three-level hierarchy: grand_parent/parent/file.md
21
+ grand_parent_snake = (
22
+ clearskies.functional.string.title_case_to_snake_case(self.grand_parent)
23
+ .replace("_", "-")
24
+ .replace(" ", "")
25
+ )
26
+ parent_snake = (
27
+ clearskies.functional.string.title_case_to_snake_case(self.parent).replace("_", "-").replace(" ", "")
28
+ )
29
+ section_name = f"{grand_parent_snake}/{parent_snake}"
30
+ section_folder_path = self.doc_root / grand_parent_snake / parent_snake
31
+ elif self.parent:
32
+ # Two-level hierarchy: parent/file.md
33
+ section_name = (
34
+ clearskies.functional.string.title_case_to_snake_case(self.parent).replace("_", "-").replace(" ", "")
35
+ )
36
+ section_folder_path = self.doc_root / section_name
37
+ else:
38
+ # Top-level: title/index.md
39
+ section_name = (
40
+ clearskies.functional.string.title_case_to_snake_case(self.title).replace("_", "-").replace(" ", "")
41
+ )
42
+ section_folder_path = self.doc_root / section_name
43
+
44
+ section_folder_path.mkdir(parents=True, exist_ok=True)
24
45
  source_class = self.classes.find(f"import_path={self.source}")
25
46
 
26
47
  title_snake_case = clearskies.functional.string.title_case_to_snake_case(self.title.replace(" ", "")).replace(
27
48
  "_", "-"
28
49
  )
29
- class_doc = self.build_header(self.title, title_snake_case, section_name, self.parent, self.nav_order, False)
50
+ class_doc = self.build_header(
51
+ self.title, title_snake_case, section_name, self.parent, self.nav_order, False, self.grand_parent
52
+ )
30
53
  (elevator_pitch, overview) = self.parse_overview_doc(
31
54
  self.raw_docblock_to_md(source_class.doc).lstrip("\n").lstrip(" ")
32
55
  )
@@ -70,10 +93,17 @@ class SingleClass(Builder):
70
93
 
71
94
  class_doc += f"{table_of_contents}\n{main_doc}"
72
95
 
73
- output_file = section_folder_path / (
74
- "index.md"
75
- if not self.parent
76
- else clearskies.functional.string.title_case_to_snake_case(self.title.replace(" ", "")) + ".md"
77
- )
96
+ # Determine output filename based on hierarchy level
97
+ if self.parent or self.grand_parent:
98
+ # Child or grandchild: use title as filename
99
+ output_filename = (
100
+ clearskies.functional.string.title_case_to_snake_case(self.title.replace(" ", "")).replace("_", "-")
101
+ + ".md"
102
+ )
103
+ else:
104
+ # Top-level: use index.md
105
+ output_filename = "index.md"
106
+
107
+ output_file = section_folder_path / output_filename
78
108
  with output_file.open(mode="w") as doc_file:
79
109
  doc_file.write(class_doc)
@@ -146,7 +146,7 @@ wheels = [
146
146
 
147
147
  [[package]]
148
148
  name = "clear-skies-doc-builder"
149
- version = "2.0.6"
149
+ version = "2.0.8"
150
150
  source = { editable = "." }
151
151
  dependencies = [
152
152
  { name = "clear-skies" },
@@ -1,12 +0,0 @@
1
- ## [2.0.6] - 2026-01-28
2
-
3
- ### Added
4
- - Add some basic tests
5
-
6
- ### Changed
7
- - Update to latest copier version
8
- - Update dependencies
9
-
10
- ### Fixed
11
- - Update to latest clear-skies QueryRequest
12
-
@@ -1,40 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: clear-skies-doc-builder
3
- Version: 2.0.6
4
- Summary: The docbuilder for all 'official' clearskies plugins (as well as the main clearskies docs)
5
- Project-URL: repository, https://github.com/clearskies-py/docs
6
- Project-URL: issues, https://github.com/clearskies-py/docs/issues
7
- Project-URL: changelog, https://github.com/clearskies-py/docs/blob/main/CHANGELOG.md
8
- Author-email: Conor Mancone <cmancone@gmail.com>
9
- License-Expression: MIT
10
- License-File: LICENSE
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Programming Language :: Python :: 3
15
- Requires-Python: <4.0,>=3.11
16
- Requires-Dist: clear-skies<3.0.0,>=2.0.0
17
- Provides-Extra: dev
18
- Requires-Dist: types-requests>=2.32.4; extra == 'dev'
19
- Description-Content-Type: text/markdown
20
-
21
- # docs
22
-
23
- The documentation builder for clearskies and related plugins
24
-
25
- ## Overview
26
-
27
- Each "official" clearskies module (including the core clearskies library itself) has the documentation primarily written in the codebase as docblocks. The documentation site is then built by extracting these docblocks and stitching them together. To be clear, this isn't about the low-level "API" documentation that describes every single class/method in the framework. Rather, this is about the primary documentation site itself (clearskies.info) which is focused on high-level use cases and examples of the primary configuration options. As a result, it's not a simple matter of just iterating over the classes/methods and building documentation. To build a coherent documentation site, each plugin has a configuration file that basically outlines the final "structure" or organization of the resulting documentation, as well as the name of a builder class that will combine that configuration information with the codebase itself to create the actual docs.
28
-
29
- The docs themselves (in the source code) are all written with markdown. This documentation builder then takes that markdwon and adds the necessary headers/etc so to make them valid files for [Jekyll](https://jekyllrb.com/), the builder for the current documentation site. The site itself is hosted in S3, so building an actual documentation site means:
30
-
31
- 1. Properly documenting everything inside of the source code via markdown.
32
- 2. Creating a config file (`docs/python/config.json`) to map source code docs to Jekyll files.
33
- 3. Creating a skeleton of a Jekyll site in the `doc/jekyll` folder of the plugin.
34
- 4. Installing this doc builder via `poetry add clear-skies-doc-builder`.
35
- 5. Run the doc builder.
36
- 6. Build with Jekyll.
37
- 7. Push to the appropriate subfolder via S3.
38
- 8. (Only once) Update the main clearskies doc site to know about the new subfolder for this plugin.
39
-
40
- Of course, we want the Jekyll sites to be consistent with eachother in terms of style/look. In the long run we'll probably have this doc builder also bootstrap the Jekyll site, but for now you just have to manually setup the Jekyll build using the main clearskies repo as a template.
@@ -1,20 +0,0 @@
1
- # docs
2
-
3
- The documentation builder for clearskies and related plugins
4
-
5
- ## Overview
6
-
7
- Each "official" clearskies module (including the core clearskies library itself) has the documentation primarily written in the codebase as docblocks. The documentation site is then built by extracting these docblocks and stitching them together. To be clear, this isn't about the low-level "API" documentation that describes every single class/method in the framework. Rather, this is about the primary documentation site itself (clearskies.info) which is focused on high-level use cases and examples of the primary configuration options. As a result, it's not a simple matter of just iterating over the classes/methods and building documentation. To build a coherent documentation site, each plugin has a configuration file that basically outlines the final "structure" or organization of the resulting documentation, as well as the name of a builder class that will combine that configuration information with the codebase itself to create the actual docs.
8
-
9
- The docs themselves (in the source code) are all written with markdown. This documentation builder then takes that markdwon and adds the necessary headers/etc so to make them valid files for [Jekyll](https://jekyllrb.com/), the builder for the current documentation site. The site itself is hosted in S3, so building an actual documentation site means:
10
-
11
- 1. Properly documenting everything inside of the source code via markdown.
12
- 2. Creating a config file (`docs/python/config.json`) to map source code docs to Jekyll files.
13
- 3. Creating a skeleton of a Jekyll site in the `doc/jekyll` folder of the plugin.
14
- 4. Installing this doc builder via `poetry add clear-skies-doc-builder`.
15
- 5. Run the doc builder.
16
- 6. Build with Jekyll.
17
- 7. Push to the appropriate subfolder via S3.
18
- 8. (Only once) Update the main clearskies doc site to know about the new subfolder for this plugin.
19
-
20
- Of course, we want the Jekyll sites to be consistent with eachother in terms of style/look. In the long run we'll probably have this doc builder also bootstrap the Jekyll site, but for now you just have to manually setup the Jekyll build using the main clearskies repo as a template.
@@ -1,24 +0,0 @@
1
- from typing import Any
2
-
3
- from clearskies_doc_builder import models
4
- from clearskies_doc_builder.prepare_doc_space import prepare_doc_space
5
-
6
-
7
- def build_callable(modules: models.Module, classes: models.Class, config: dict[str, Any], project_root: str):
8
- doc_root = prepare_doc_space(project_root)
9
- nav_order_parent_count = {}
10
-
11
- for index, branch in enumerate(config["tree"]):
12
- nav_order_title_tracker = branch.get("parent", branch["title"])
13
- if nav_order_title_tracker not in nav_order_parent_count:
14
- nav_order_parent_count[nav_order_title_tracker] = 0
15
- nav_order_parent_count[nav_order_title_tracker] += 1
16
- builder_class = classes.find("import_path=" + branch["builder"]).type
17
- builder = builder_class(
18
- branch,
19
- modules,
20
- classes,
21
- doc_root,
22
- nav_order=nav_order_parent_count[nav_order_title_tracker] if branch.get("parent") else index + 2,
23
- )
24
- builder.build()