plating 0.0.0.dev0__tar.gz → 0.0.1000.post0__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 (77) hide show
  1. {plating-0.0.0.dev0/src/plating.egg-info → plating-0.0.1000.post0}/PKG-INFO +16 -23
  2. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/README.md +8 -8
  3. plating-0.0.1000.post0/VERSION +1 -0
  4. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/pyproject.toml +24 -25
  5. plating-0.0.1000.post0/src/plating/__init__.py +152 -0
  6. plating-0.0.1000.post0/src/plating/_version.py +12 -0
  7. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/adorner/__init__.py +3 -1
  8. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/adorner/adorner.py +43 -29
  9. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/adorner/api.py +2 -2
  10. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/adorner/finder.py +2 -1
  11. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/adorner/templates.py +6 -10
  12. plating-0.0.1000.post0/src/plating/async_template_engine.py +162 -0
  13. plating-0.0.1000.post0/src/plating/bundles/__init__.py +11 -0
  14. plating-0.0.1000.post0/src/plating/bundles/base.py +116 -0
  15. plating-0.0.1000.post0/src/plating/bundles/function.py +26 -0
  16. plating-0.0.1000.post0/src/plating/cli.py +340 -0
  17. plating-0.0.1000.post0/src/plating/config/__init__.py +10 -0
  18. plating-0.0.1000.post0/src/plating/config/defaults.py +77 -0
  19. plating-0.0.0.dev0/src/plating/config.py → plating-0.0.1000.post0/src/plating/config/runtime.py +56 -23
  20. plating-0.0.1000.post0/src/plating/core/__init__.py +8 -0
  21. plating-0.0.1000.post0/src/plating/core/doc_generator.py +244 -0
  22. plating-0.0.1000.post0/src/plating/core/project_utils.py +66 -0
  23. plating-0.0.1000.post0/src/plating/core/schema_helpers.py +146 -0
  24. plating-0.0.1000.post0/src/plating/decorators.py +257 -0
  25. plating-0.0.1000.post0/src/plating/discovery/__init__.py +11 -0
  26. plating-0.0.1000.post0/src/plating/discovery/finder.py +121 -0
  27. plating-0.0.1000.post0/src/plating/discovery/templates.py +188 -0
  28. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/error_handling.py +11 -26
  29. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/errors.py +13 -9
  30. plating-0.0.1000.post0/src/plating/example_compiler.py +512 -0
  31. plating-0.0.1000.post0/src/plating/generation/__init__.py +12 -0
  32. plating-0.0.1000.post0/src/plating/generation/adorner.py +96 -0
  33. plating-0.0.1000.post0/src/plating/generation/plater.py +111 -0
  34. plating-0.0.1000.post0/src/plating/generation/renderer.py +58 -0
  35. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/linting.py +44 -22
  36. plating-0.0.1000.post0/src/plating/markdown_validator.py +229 -0
  37. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/models.py +1 -1
  38. plating-0.0.1000.post0/src/plating/plating.py +311 -0
  39. plating-0.0.1000.post0/src/plating/registry.py +237 -0
  40. plating-0.0.1000.post0/src/plating/schema.py +343 -0
  41. plating-0.0.1000.post0/src/plating/schema_utils/__init__.py +8 -0
  42. plating-0.0.1000.post0/src/plating/schema_utils/formatters.py +221 -0
  43. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/template_filters.py +9 -27
  44. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/template_functions.py +9 -12
  45. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating/templates.py +4 -11
  46. plating-0.0.1000.post0/src/plating/types.py +483 -0
  47. {plating-0.0.0.dev0 → plating-0.0.1000.post0/src/plating.egg-info}/PKG-INFO +16 -23
  48. plating-0.0.1000.post0/src/plating.egg-info/SOURCES.txt +58 -0
  49. plating-0.0.1000.post0/src/plating.egg-info/requires.txt +6 -0
  50. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/tests/test_adorner.py +147 -156
  51. plating-0.0.1000.post0/tests/test_foundation_integration.py +359 -0
  52. plating-0.0.1000.post0/tests/test_modern_api.py +363 -0
  53. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/tests/test_plating_bundle.py +59 -132
  54. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/tests/test_plating_discovery.py +73 -74
  55. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/tests/test_schema.py +152 -182
  56. plating-0.0.0.dev0/VERSION +0 -1
  57. plating-0.0.0.dev0/src/plating/__init__.py +0 -27
  58. plating-0.0.0.dev0/src/plating/_version.py +0 -53
  59. plating-0.0.0.dev0/src/plating/cli.py +0 -317
  60. plating-0.0.0.dev0/src/plating/generator.py +0 -192
  61. plating-0.0.0.dev0/src/plating/plater.py +0 -487
  62. plating-0.0.0.dev0/src/plating/plating.py +0 -207
  63. plating-0.0.0.dev0/src/plating/schema.py +0 -502
  64. plating-0.0.0.dev0/src/plating/test_runner.py +0 -1005
  65. plating-0.0.0.dev0/src/plating/types.py +0 -71
  66. plating-0.0.0.dev0/src/plating.egg-info/SOURCES.txt +0 -41
  67. plating-0.0.0.dev0/src/plating.egg-info/requires.txt +0 -13
  68. plating-0.0.0.dev0/tests/test_cli.py +0 -71
  69. plating-0.0.0.dev0/tests/test_end_to_end.py +0 -438
  70. plating-0.0.0.dev0/tests/test_integration.py +0 -363
  71. plating-0.0.0.dev0/tests/test_plater.py +0 -701
  72. plating-0.0.0.dev0/tests/test_stir_migration.py +0 -676
  73. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/LICENSE +0 -0
  74. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/setup.cfg +0 -0
  75. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating.egg-info/dependency_links.txt +0 -0
  76. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating.egg-info/entry_points.txt +0 -0
  77. {plating-0.0.0.dev0 → plating-0.0.1000.post0}/src/plating.egg-info/top_level.txt +0 -0
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plating
3
- Version: 0.0.0.dev0
3
+ Version: 0.0.1000.post0
4
4
  Summary: Documentation generation system for Terraform/OpenTofu providers
5
5
  Author-email: Tim Perkins <code@tim.life>
6
6
  Maintainer-email: "provide.io" <code@provide.io>
7
- License: Apache-2.0
7
+ License-Expression: Apache-2.0
8
8
  Classifier: Development Status :: 3 - Alpha
9
9
  Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: Apache Software License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Classifier: Programming Language :: Python :: 3
13
12
  Classifier: Programming Language :: Python :: 3.11
@@ -17,18 +16,12 @@ Classifier: Typing :: Typed
17
16
  Requires-Python: >=3.11
18
17
  Description-Content-Type: text/markdown
19
18
  License-File: LICENSE
20
- Requires-Dist: jinja2>=3.1.6
21
- Requires-Dist: rich>=13.0.0
22
- Requires-Dist: pyvider>=0.0.0.post0
23
- Requires-Dist: pyvider-hcl>=0.0.113
24
- Requires-Dist: pyvider-cty>=0.0.111
25
- Requires-Dist: provide-foundation>=0.0.0.dev3
26
- Provides-Extra: dev
27
- Requires-Dist: pytest>=8.0.0; extra == "dev"
28
- Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
29
- Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
30
- Requires-Dist: mypy>=1.10.0; extra == "dev"
31
- Requires-Dist: ruff>=0.2.0; extra == "dev"
19
+ Requires-Dist: jinja2<4.0.0,>=3.1.6
20
+ Requires-Dist: rich<14.0.0,>=13.0.0
21
+ Requires-Dist: pyvider-cty>=0.0.1000
22
+ Requires-Dist: provide-foundation[all]>=0.0.1000
23
+ Requires-Dist: pymarkdownlnt>=0.9.32
24
+ Requires-Dist: mkdocs-material>=9.6.20
32
25
  Dynamic: license-file
33
26
 
34
27
  # 🍽️ Plating
@@ -40,7 +33,7 @@ Plating is a powerful documentation system that brings culinary elegance to tech
40
33
  ## ✨ Features
41
34
 
42
35
  - **🎯 Automatic Documentation Generation** - Generate comprehensive docs from your provider code
43
- - **👗 Smart Component Dressing** - Automatically create documentation templates for undocumented components
36
+ - **✨ Smart Component Adorning** - Automatically create documentation templates for undocumented components
44
37
  - **🍽️ Beautiful Plating** - Render documentation with examples, schemas, and rich formatting
45
38
  - **🔍 Component Discovery** - Automatically find and document resources, data sources, and functions
46
39
  - **📝 Jinja2 Templates** - Flexible templating with custom functions and filters
@@ -74,8 +67,8 @@ uv self update
74
67
 
75
68
  ```bash
76
69
  # Clone the repository
77
- git clone https://github.com/provide-io/plating.git
78
- cd plating
70
+ git clone https://github.com/provide-io/garnish.git
71
+ cd garnish
79
72
 
80
73
  # Create virtual environment
81
74
  uv venv
@@ -106,11 +99,11 @@ uv add git+https://github.com/provide-io/plating.git
106
99
  First, create `.plating` bundles for your undocumented components:
107
100
 
108
101
  ```bash
109
- # Dress all missing components
110
- plating dress
102
+ # Adorn all missing components
103
+ plating adorn
111
104
 
112
- # Dress only resources
113
- plating dress --component-type resource
105
+ # Adorn only resources
106
+ plating adorn --component-type resource
114
107
  ```
115
108
 
116
109
  ### 2. Customize Templates
@@ -197,7 +190,7 @@ Plating follows a modular architecture:
197
190
 
198
191
  - **PlatingBundle** - Represents documentation bundles
199
192
  - **PlatingPlater** - Renders documentation
200
- - **PlatingDresser** - Creates documentation templates
193
+ - **PlatingAdorner** - Creates documentation templates
201
194
  - **PlatingDiscovery** - Finds components and bundles
202
195
  - **SchemaProcessor** - Extracts provider schemas
203
196
 
@@ -7,7 +7,7 @@ Plating is a powerful documentation system that brings culinary elegance to tech
7
7
  ## ✨ Features
8
8
 
9
9
  - **🎯 Automatic Documentation Generation** - Generate comprehensive docs from your provider code
10
- - **👗 Smart Component Dressing** - Automatically create documentation templates for undocumented components
10
+ - **✨ Smart Component Adorning** - Automatically create documentation templates for undocumented components
11
11
  - **🍽️ Beautiful Plating** - Render documentation with examples, schemas, and rich formatting
12
12
  - **🔍 Component Discovery** - Automatically find and document resources, data sources, and functions
13
13
  - **📝 Jinja2 Templates** - Flexible templating with custom functions and filters
@@ -41,8 +41,8 @@ uv self update
41
41
 
42
42
  ```bash
43
43
  # Clone the repository
44
- git clone https://github.com/provide-io/plating.git
45
- cd plating
44
+ git clone https://github.com/provide-io/garnish.git
45
+ cd garnish
46
46
 
47
47
  # Create virtual environment
48
48
  uv venv
@@ -73,11 +73,11 @@ uv add git+https://github.com/provide-io/plating.git
73
73
  First, create `.plating` bundles for your undocumented components:
74
74
 
75
75
  ```bash
76
- # Dress all missing components
77
- plating dress
76
+ # Adorn all missing components
77
+ plating adorn
78
78
 
79
- # Dress only resources
80
- plating dress --component-type resource
79
+ # Adorn only resources
80
+ plating adorn --component-type resource
81
81
  ```
82
82
 
83
83
  ### 2. Customize Templates
@@ -164,7 +164,7 @@ Plating follows a modular architecture:
164
164
 
165
165
  - **PlatingBundle** - Represents documentation bundles
166
166
  - **PlatingPlater** - Renders documentation
167
- - **PlatingDresser** - Creates documentation templates
167
+ - **PlatingAdorner** - Creates documentation templates
168
168
  - **PlatingDiscovery** - Finds components and bundles
169
169
  - **SchemaProcessor** - Extracts provider schemas
170
170
 
@@ -0,0 +1 @@
1
+ 0.0.1000-0
@@ -4,7 +4,7 @@ dynamic = ["version"]
4
4
  description = "Documentation generation system for Terraform/OpenTofu providers"
5
5
  requires-python = ">=3.11"
6
6
  readme = "README.md"
7
- license = { text = "Apache-2.0" }
7
+ license = "Apache-2.0"
8
8
  authors = [
9
9
  { name = "Tim Perkins", email = "code@tim.life" },
10
10
  ]
@@ -14,7 +14,6 @@ maintainers = [
14
14
  classifiers = [
15
15
  "Development Status :: 3 - Alpha",
16
16
  "Intended Audience :: Developers",
17
- "License :: OSI Approved :: Apache Software License",
18
17
  "Operating System :: OS Independent",
19
18
  "Programming Language :: Python :: 3",
20
19
  "Programming Language :: Python :: 3.11",
@@ -23,21 +22,20 @@ classifiers = [
23
22
  "Typing :: Typed",
24
23
  ]
25
24
  dependencies = [
26
- "jinja2>=3.1.6",
27
- "rich>=13.0.0",
28
- "pyvider>=0.0.0.post0",
29
- "pyvider-hcl>=0.0.113",
30
- "pyvider-cty>=0.0.111",
31
- "provide-foundation>=0.0.0.dev3",
25
+ "jinja2>=3.1.6,<4.0.0",
26
+ "rich>=13.0.0,<14.0.0",
27
+ "pyvider-cty>=0.0.1000",
28
+ "provide-foundation[all]>=0.0.1000",
29
+ "pymarkdownlnt>=0.9.32",
30
+ "mkdocs-material>=9.6.20",
32
31
  ]
33
32
 
34
- [project.optional-dependencies]
33
+ [dependency-groups]
35
34
  dev = [
36
- "pytest>=8.0.0",
37
- "pytest-asyncio>=0.21.0",
38
- "pytest-cov>=6.0.0",
39
- "mypy>=1.10.0",
40
- "ruff>=0.2.0",
35
+ "provide-testkit[standard,build]>=0.0.1000",
36
+ ]
37
+ docs = [
38
+ "provide-testkit[docs]>=0.0.1000",
41
39
  ]
42
40
 
43
41
  [project.scripts]
@@ -46,6 +44,7 @@ plating = "plating.cli:main"
46
44
  [tool.uv]
47
45
  package = true
48
46
 
47
+
49
48
  [tool.setuptools.packages.find]
50
49
  where = ["src"]
51
50
  include = ["plating*"]
@@ -61,15 +60,19 @@ asyncio_mode = "auto"
61
60
  pythonpath = ["src", "."]
62
61
  testpaths = ["tests"]
63
62
  python_files = ["test_*.py", "*_test.py"]
63
+ filterwarnings = [
64
+ "ignore::RuntimeWarning:threading",
65
+ "ignore:coroutine.*was never awaited:RuntimeWarning",
66
+ ]
64
67
 
65
68
  [tool.ruff]
66
- line-length = 88
69
+ line-length = 111
67
70
  indent-width = 4
68
71
  target-version = "py311"
69
72
 
70
73
  [tool.ruff.lint]
71
- select = ["E", "F", "W", "I", "UP"]
72
- ignore = ["E501"]
74
+ select = ["E", "F", "W", "I", "UP", "ANN", "B", "C90", "SIM", "PTH", "RUF"]
75
+ ignore = ["ANN401", "B008", "E501"]
73
76
 
74
77
  [tool.ruff.lint.isort]
75
78
  known-first-party = ["plating"]
@@ -93,23 +96,19 @@ warn_unused_ignores = true
93
96
  warn_unused_configs = true
94
97
  disallow_untyped_decorators = false
95
98
 
99
+ # Exclude .plating directories from mypy checking
100
+ exclude = [".*\\.plating/.*"]
101
+
96
102
  [[tool.mypy.overrides]]
97
- module = ["pyvider.*", "jinja2.*", "rich.*", "click.*", "attrs.*"]
103
+ module = ["pyvider.*", "jinja2.*", "rich.*", "click.*", "attrs.*", "provide.*"]
98
104
  ignore_missing_imports = true
99
105
 
100
106
  [tool.coverage.run]
101
107
  source = ["plating"]
102
108
  branch = true
103
- parallel = true
104
109
 
105
110
  [tool.coverage.report]
106
111
  show_missing = true
107
112
  skip_covered = true
108
113
  exclude_lines = ["pragma: no cover", "raise NotImplementedError", "if __name__ == .__main__.:", "if TYPE_CHECKING:", "def __repr__", "def __str__", "pass"]
109
114
 
110
- [dependency-groups]
111
- dev = [
112
- "pytest-asyncio>=1.1.0",
113
- "pytest-xdist>=3.8.0",
114
- "ruff>=0.12.9",
115
- ]
@@ -0,0 +1,152 @@
1
+ #
2
+ # plating/__init__.py
3
+ #
4
+ """Modern async documentation generation with full foundation integration.
5
+
6
+ A clean, type-safe API for generating high-quality documentation with
7
+ multi-domain support via foundation patterns.
8
+
9
+ Key Features:
10
+ - Type-safe async-first API
11
+ - Full foundation integration (retry, metrics, circuit breakers)
12
+ - Registry-based component discovery with multi-domain support
13
+ - Integrated markdown validation with configurable rules
14
+ - Context-aware template rendering with Jinja2
15
+ - Extensible beyond Terraform to any domain (Kubernetes, CloudFormation, API docs, etc.)
16
+
17
+ Example Usage:
18
+ ```python
19
+ import asyncio
20
+ from pathlib import Path
21
+ from plating import Plating, ComponentType, PlatingContext
22
+
23
+ async def main():
24
+ # Initialize with foundation context
25
+ context = PlatingContext(
26
+ provider_name="my_provider",
27
+ log_level="INFO",
28
+ no_color=False
29
+ )
30
+
31
+ api = Plating(context)
32
+
33
+ # Create missing templates
34
+ adorn_result = await api.adorn(component_types=[ComponentType.RESOURCE])
35
+ print(f"Created {adorn_result.templates_generated} templates")
36
+
37
+ # Generate docs with validation
38
+ plate_result = await api.plate(
39
+ Path("docs"),
40
+ component_types=[ComponentType.RESOURCE],
41
+ validate_markdown=True,
42
+ force=True
43
+ )
44
+
45
+ if plate_result.success:
46
+ print(f"Generated {len(plate_result.output_files)} files")
47
+
48
+ # Validate existing documentation
49
+ validation_result = await api.validate()
50
+ print(f"Validation: {validation_result.passed}/{validation_result.total} passed")
51
+
52
+ # Run the async main
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ CLI Usage:
57
+ ```bash
58
+ # Create missing templates
59
+ plating adorn --component-type resource --provider-name my_provider
60
+
61
+ # Generate documentation
62
+ plating plate --output-dir docs --validate
63
+
64
+ # Validate existing docs
65
+ plating validate --output-dir docs
66
+
67
+ # Show registry info
68
+ plating info --provider-name my_provider
69
+ ```
70
+ """
71
+
72
+ from plating._version import __version__
73
+
74
+ # Old PlatingAPI removed - use Plating class directly
75
+
76
+ # Template engine
77
+ from plating.async_template_engine import AsyncTemplateEngine, template_engine
78
+
79
+ # New modular components
80
+ from plating.bundles import FunctionPlatingBundle, PlatingBundle as ModularPlatingBundle
81
+
82
+ # Foundation decorators and utilities
83
+ from plating.decorators import (
84
+ plating_metrics,
85
+ with_circuit_breaker,
86
+ with_metrics,
87
+ with_retry,
88
+ with_timing,
89
+ )
90
+ from plating.discovery import PlatingDiscovery as ModularPlatingDiscovery, TemplateMetadataExtractor
91
+ from plating.generation import DocumentationAdorner, DocumentationPlater, TemplateRenderer
92
+
93
+ # from plating.markdown_validator import MarkdownValidator, get_markdown_validator, reset_markdown_validator
94
+ # Core async API
95
+ from plating.plating import Plating, plating
96
+
97
+ # Registry and validation
98
+ from plating.registry import PlatingRegistry, get_plating_registry, reset_plating_registry
99
+
100
+ # Type-safe data structures
101
+ from plating.types import (
102
+ AdornResult,
103
+ ArgumentInfo,
104
+ ComponentType,
105
+ PlateResult,
106
+ PlatingContext,
107
+ SchemaInfo,
108
+ ValidationResult,
109
+ )
110
+
111
+ __all__ = [
112
+ "AdornResult",
113
+ "ArgumentInfo",
114
+ # Template engine
115
+ "AsyncTemplateEngine",
116
+ # Type-safe structures
117
+ "ComponentType",
118
+ "DocumentationAdorner",
119
+ "DocumentationPlater",
120
+ # New modular components
121
+ "FunctionPlatingBundle",
122
+ "MarkdownValidator",
123
+ "ModularPlatingBundle",
124
+ "ModularPlatingDiscovery",
125
+ "PlateResult",
126
+ # Core API
127
+ "Plating",
128
+ "PlatingContext",
129
+ # Registry and validation
130
+ "PlatingRegistry",
131
+ "SchemaInfo",
132
+ "TemplateMetadataExtractor",
133
+ "TemplateRenderer",
134
+ "ValidationResult",
135
+ # Version
136
+ "__version__",
137
+ "get_markdown_validator",
138
+ "get_plating_registry",
139
+ "plating",
140
+ "plating_metrics",
141
+ "reset_markdown_validator",
142
+ "reset_plating_registry",
143
+ "template_engine",
144
+ "with_circuit_breaker",
145
+ "with_metrics",
146
+ # Foundation decorators
147
+ "with_retry",
148
+ "with_timing",
149
+ ]
150
+
151
+
152
+ # 🚀✨🎯🍽️
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from provide.foundation.utils.versioning import get_version
4
+
5
+ """Version handling for plating.
6
+
7
+ This module uses the shared versioning utility from provide-foundation.
8
+ """
9
+
10
+ __version__ = get_version("plating", caller_file=__file__)
11
+
12
+ __all__ = ["__version__"]
@@ -3,11 +3,13 @@
3
3
  #
4
4
  """Adorning system for adding .plating directories to components."""
5
5
 
6
- from plating.adorner.api import adorn_components, adorn_missing_components
7
6
  from plating.adorner.adorner import PlatingAdorner
7
+ from plating.adorner.api import adorn_components, adorn_missing_components
8
+ from plating.adorner.templates import TemplateGenerator
8
9
 
9
10
  __all__ = [
10
11
  "PlatingAdorner",
12
+ "TemplateGenerator",
11
13
  "adorn_components",
12
14
  "adorn_missing_components",
13
15
  ]
@@ -4,23 +4,32 @@
4
4
  """Core adorner implementation."""
5
5
 
6
6
  import asyncio
7
+ from typing import Any
7
8
 
8
- from pyvider.hub import ComponentDiscovery, hub
9
- from provide.foundation import logger, pout, perr
9
+ from provide.foundation import logger, perr, pout
10
+ from provide.foundation.hub import Hub
10
11
 
11
12
  from plating.adorner.finder import ComponentFinder
12
13
  from plating.adorner.templates import TemplateGenerator
14
+ from plating.discovery import PlatingDiscovery
13
15
  from plating.errors import AdorningError, handle_error
14
- from plating.plating import PlatingDiscovery
15
16
 
16
17
 
17
18
  class PlatingAdorner:
18
19
  """Adorns components with .plating directories."""
19
20
 
20
- def __init__(self):
21
- self.plating_discovery = PlatingDiscovery()
21
+ def __init__(self, package_name: str):
22
+ """Initialize adorner with package name.
23
+
24
+ Args:
25
+ package_name: Python package to search for components
26
+ """
27
+ self.package_name = package_name
28
+ self.plating_discovery = PlatingDiscovery(package_name)
22
29
  self.template_generator = TemplateGenerator()
23
30
  self.component_finder = ComponentFinder()
31
+ # Initialize foundation hub for component discovery
32
+ self.hub = Hub()
24
33
 
25
34
  async def adorn_missing(self, component_types: list[str] = None) -> dict[str, int]:
26
35
  """
@@ -28,15 +37,15 @@ class PlatingAdorner:
28
37
 
29
38
  Returns a dictionary with counts of adorned components by type.
30
39
  """
31
- # Discover all components via hub
32
- discovery = ComponentDiscovery(hub)
33
- await discovery.discover_all()
34
- components = hub.list_components()
40
+ # Discover all components via foundation hub
41
+ try:
42
+ self.hub.discover_components(self.package_name)
43
+ except Exception as e:
44
+ logger.error(f"Component discovery failed: {e}")
45
+ return {"resource": 0, "data_source": 0, "function": 0}
35
46
 
36
47
  # Find existing plating bundles
37
- existing_bundles = await asyncio.to_thread(
38
- self.plating_discovery.discover_bundles
39
- )
48
+ existing_bundles = await asyncio.to_thread(self.plating_discovery.discover_bundles)
40
49
  existing_names = {bundle.name for bundle in existing_bundles}
41
50
 
42
51
  # Track adorning results
@@ -47,20 +56,29 @@ class PlatingAdorner:
47
56
 
48
57
  # Adorn missing components
49
58
  for component_type in target_types:
50
- if component_type in components:
51
- for name, component_class in components[component_type].items():
52
- if name not in existing_names:
53
- success = await self._adorn_component(
54
- name, component_type, component_class
55
- )
56
- if success:
57
- adorned[component_type] += 1
59
+ components = self._get_components_by_dimension(component_type)
60
+ for name, component_class in components.items():
61
+ if name not in existing_names:
62
+ success = await self._adorn_component(name, component_type, component_class)
63
+ if success:
64
+ adorned[component_type] += 1
58
65
 
59
66
  return adorned
60
67
 
61
- async def _adorn_component(
62
- self, name: str, component_type: str, component_class
63
- ) -> bool:
68
+ def _get_components_by_dimension(self, dimension: str) -> dict[str, Any]:
69
+ """Get components from foundation hub by dimension."""
70
+ components = {}
71
+ try:
72
+ names = self.hub.list_components(dimension=dimension)
73
+ for name in names:
74
+ component = self.hub.get_component(name, dimension=dimension)
75
+ if component:
76
+ components[name] = component
77
+ except Exception as e:
78
+ logger.warning(f"Failed to get {dimension} components: {e}")
79
+ return components
80
+
81
+ async def _adorn_component(self, name: str, component_type: str, component_class) -> bool:
64
82
  """Adorn a single component with a .plating directory."""
65
83
  try:
66
84
  # Find the component's source file location
@@ -81,9 +99,7 @@ class PlatingAdorner:
81
99
  await asyncio.to_thread(docs_dir.mkdir, parents=True, exist_ok=True)
82
100
  await asyncio.to_thread(examples_dir.mkdir, parents=True, exist_ok=True)
83
101
  except OSError as e:
84
- raise AdorningError(
85
- name, component_type, f"Failed to create directories: {e}"
86
- )
102
+ raise AdorningError(name, component_type, f"Failed to create directories: {e}")
87
103
 
88
104
  # Generate and write template
89
105
  template_content = await self.template_generator.generate_template(
@@ -93,9 +109,7 @@ class PlatingAdorner:
93
109
  await asyncio.to_thread(template_file.write_text, template_content)
94
110
 
95
111
  # Generate and write example
96
- example_content = await self.template_generator.generate_example(
97
- name, component_type
98
- )
112
+ example_content = await self.template_generator.generate_example(name, component_type)
99
113
  example_file = examples_dir / "example.tf"
100
114
  await asyncio.to_thread(example_file.write_text, example_content)
101
115
 
@@ -9,14 +9,14 @@ from plating.adorner.adorner import PlatingAdorner
9
9
 
10
10
 
11
11
  # Async entry point
12
- async def adorn_missing_components(component_types: list[str] = None) -> dict[str, int]:
12
+ async def adorn_missing_components(component_types: list[str] | None = None) -> dict[str, int]:
13
13
  """Adorn components with missing .plating directories."""
14
14
  adorner = PlatingAdorner()
15
15
  return await adorner.adorn_missing(component_types)
16
16
 
17
17
 
18
18
  # Sync entry point
19
- def adorn_components(component_types: list[str] = None) -> dict[str, int]:
19
+ def adorn_components(component_types: list[str] | None = None) -> dict[str, int]:
20
20
  """Sync entry point for adorning components."""
21
21
  return asyncio.run(adorn_missing_components(component_types))
22
22
 
@@ -5,12 +5,13 @@
5
5
 
6
6
  import inspect
7
7
  from pathlib import Path
8
+ from typing import Any
8
9
 
9
10
 
10
11
  class ComponentFinder:
11
12
  """Finds source files for components."""
12
13
 
13
- async def find_source(self, component_class) -> Path | None:
14
+ async def find_source(self, component_class: Any) -> Path | None:
14
15
  """Find the source file for a component class."""
15
16
  try:
16
17
  source_file = inspect.getfile(component_class)
@@ -3,13 +3,13 @@
3
3
  #
4
4
  """Template generation for adorned components."""
5
5
 
6
+ from typing import Any
7
+
6
8
 
7
9
  class TemplateGenerator:
8
10
  """Generates templates and examples for components."""
9
11
 
10
- async def generate_template(
11
- self, name: str, component_type: str, component_class
12
- ) -> str:
12
+ async def generate_template(self, name: str, component_type: str, component_class: Any) -> str:
13
13
  """Generate template content based on component type."""
14
14
  # Get component description if available
15
15
  try:
@@ -20,9 +20,7 @@ class TemplateGenerator:
20
20
  if not doc_stripped.startswith("Create a new `Mock`"):
21
21
  description = doc_stripped.split("\n")[0] # First line only
22
22
  else:
23
- description = (
24
- f"Terraform {component_type.replace('_', ' ')} for {name}"
25
- )
23
+ description = f"Terraform {component_type.replace('_', ' ')} for {name}"
26
24
  else:
27
25
  description = f"Terraform {component_type.replace('_', ' ')} for {name}"
28
26
  except AttributeError:
@@ -128,9 +126,7 @@ description: |-
128
126
  {{% endif %}}
129
127
  """
130
128
 
131
- def _generic_template(
132
- self, name: str, description: str, component_type: str
133
- ) -> str:
129
+ def _generic_template(self, name: str, description: str, component_type: str) -> str:
134
130
  """Generate generic template content."""
135
131
  return f"""---
136
132
  page_title: "{component_type.title()}: {name}"
@@ -184,7 +180,7 @@ output "example_data" {{
184
180
  }}
185
181
 
186
182
  output "function_result" {{
187
- description = "Result of {name} function"
183
+ description = "Result of {name} function"
188
184
  value = local.example_result
189
185
  }}
190
186
  """