Skip to content

Commit ef35d3f

Browse files
committed
feat(model): resolve nested containers with parent pointers and inherited context
- Rebuild container tree setting `parent` on children and inheriting `context` - Populate lookups using `containers_flat` to include nested containers
1 parent 0558632 commit ef35d3f

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

pacta/model/resolver.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
from collections.abc import Mapping
12
from dataclasses import dataclass, replace
23

3-
from pacta.model.types import ArchitectureModel
4+
from pacta.model.types import ArchitectureModel, Container
45

56

67
@dataclass(frozen=True, slots=True)
@@ -12,20 +13,29 @@ class DefaultModelResolver:
1213
- container_to_context
1314
- path_roots
1415
- layer_patterns
16+
17+
For v2 models with nested containers:
18+
- Rebuilds the container tree with ``parent`` set on children
19+
- Children inherit parent ``context`` unless they define their own
20+
- Populates lookups for all containers (including nested, via containers_flat)
1521
"""
1622

1723
def resolve(self, model: ArchitectureModel) -> ArchitectureModel:
24+
# Rebuild container tree with parent pointers and context inheritance
25+
resolved_containers = _resolve_children(model.containers, parent_qualified_id=None, parent_context=None)
26+
27+
model = replace(model, containers=resolved_containers)
28+
1829
container_to_context: dict[str, str] = {}
1930
path_roots: dict[str, tuple[str, ...]] = {}
2031
layer_patterns: dict[str, dict[str, tuple[str, ...]]] = {}
2132

22-
for cid, c in model.containers.items():
33+
for cid, c in model.containers_flat.items():
2334
if c.context:
2435
container_to_context[cid] = c.context
2536

2637
if c.code is not None:
2738
roots = tuple(_norm_path(p) for p in c.code.roots if isinstance(p, str) and p.strip())
28-
# deterministic
2939
path_roots[cid] = tuple(sorted(set(roots)))
3040

3141
layer_map: dict[str, tuple[str, ...]] = {}
@@ -47,6 +57,25 @@ def resolve(self, model: ArchitectureModel) -> ArchitectureModel:
4757
)
4858

4959

60+
def _resolve_children(
61+
containers: Mapping[str, Container],
62+
parent_qualified_id: str | None,
63+
parent_context: str | None,
64+
) -> dict[str, Container]:
65+
"""Recursively rebuild containers with ``parent`` and inherited ``context``."""
66+
out: dict[str, Container] = {}
67+
for cid, c in containers.items():
68+
qualified = f"{parent_qualified_id}.{cid}" if parent_qualified_id else cid
69+
context = c.context if c.context is not None else parent_context
70+
71+
resolved_children: dict[str, Container] = {}
72+
if c.children:
73+
resolved_children = _resolve_children(c.children, parent_qualified_id=qualified, parent_context=context)
74+
75+
out[cid] = replace(c, parent=parent_qualified_id, context=context, children=resolved_children)
76+
return out
77+
78+
5079
def _norm_path(p: str) -> str:
5180
# Keep it simple and stable across OS:
5281
# - use forward slashes

0 commit comments

Comments
 (0)