Skip to content

Commit 7bce87e

Browse files
committed
refactor: reduce cognitive complexity in edge builders
1 parent e6b1137 commit 7bce87e

5 files changed

Lines changed: 349 additions & 272 deletions

File tree

src/treemapper/diffctx/edges/config/build.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ def _extract_cmake_refs(content: str) -> tuple[set[str], set[str]]:
8888
return targets, file_refs
8989

9090

91+
def _collect_build_refs(make_files: list[Path], cmake_files: list[Path]) -> set[str]:
92+
refs: set[str] = set()
93+
94+
for mf in make_files:
95+
try:
96+
content = mf.read_text(encoding="utf-8")
97+
_, file_refs = _extract_make_refs(content)
98+
refs.update(file_refs)
99+
except (OSError, UnicodeDecodeError):
100+
continue
101+
102+
for cf in cmake_files:
103+
try:
104+
content = cf.read_text(encoding="utf-8")
105+
_, file_refs = _extract_cmake_refs(content)
106+
refs.update(file_refs)
107+
except (OSError, UnicodeDecodeError):
108+
continue
109+
110+
return refs
111+
112+
91113
class BuildSystemEdgeBuilder(EdgeBuilder):
92114
weight = 0.55
93115
target_weight = 0.50
@@ -106,24 +128,7 @@ def discover_related_files(
106128
if not make_files and not cmake_files:
107129
return []
108130

109-
refs: set[str] = set()
110-
111-
for mf in make_files:
112-
try:
113-
content = mf.read_text(encoding="utf-8")
114-
_, file_refs = _extract_make_refs(content)
115-
refs.update(file_refs)
116-
except (OSError, UnicodeDecodeError):
117-
continue
118-
119-
for cf in cmake_files:
120-
try:
121-
content = cf.read_text(encoding="utf-8")
122-
_, file_refs = _extract_cmake_refs(content)
123-
refs.update(file_refs)
124-
except (OSError, UnicodeDecodeError):
125-
continue
126-
131+
refs = _collect_build_refs(make_files, cmake_files)
127132
return discover_files_by_refs(refs, changed_files, all_candidate_files)
128133

129134
def build(self, fragments: list[Fragment], repo_root: Path | None = None) -> EdgeDict:
@@ -137,27 +142,33 @@ def build(self, fragments: list[Fragment], repo_root: Path | None = None) -> Edg
137142
idx = FragmentIndex(fragments, repo_root)
138143

139144
for mf in make_frags:
140-
_targets, file_refs = _extract_make_refs(mf.content)
145+
self._add_makefile_edges(mf, cmake_frags, idx, edges)
146+
147+
for cf in cmake_frags:
148+
self._add_cmake_edges(cf, fragments, idx, edges)
141149

142-
for ref in file_refs:
143-
self._link_ref(mf.id, ref, idx, edges)
150+
return edges
151+
152+
def _add_makefile_edges(self, mf: Fragment, cmake_frags: list[Fragment], idx: FragmentIndex, edges: EdgeDict) -> None:
153+
_, file_refs = _extract_make_refs(mf.content)
144154

145-
for cf in cmake_frags:
146-
if cf.path.parent == mf.path.parent:
147-
self.add_edge(edges, mf.id, cf.id, self.weight * 0.7)
155+
for ref in file_refs:
156+
self._link_ref(mf.id, ref, idx, edges)
148157

149158
for cf in cmake_frags:
150-
_targets, file_refs = _extract_cmake_refs(cf.content)
159+
if cf.path.parent == mf.path.parent:
160+
self.add_edge(edges, mf.id, cf.id, self.weight * 0.7)
151161

152-
for ref in file_refs:
153-
self._link_ref(cf.id, ref, idx, edges)
162+
def _add_cmake_edges(self, cf: Fragment, fragments: list[Fragment], idx: FragmentIndex, edges: EdgeDict) -> None:
163+
_, file_refs = _extract_cmake_refs(cf.content)
154164

155-
parent_cmake = cf.path.parent.parent / "CMakeLists.txt"
156-
for f in fragments:
157-
if f.path == parent_cmake:
158-
self.add_edge(edges, cf.id, f.id, self.weight * 0.6)
165+
for ref in file_refs:
166+
self._link_ref(cf.id, ref, idx, edges)
159167

160-
return edges
168+
parent_cmake = cf.path.parent.parent / "CMakeLists.txt"
169+
for f in fragments:
170+
if f.path == parent_cmake:
171+
self.add_edge(edges, cf.id, f.id, self.weight * 0.6)
161172

162173
def _link_ref(
163174
self,

src/treemapper/diffctx/edges/config/helm.py

Lines changed: 97 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@ def _get_chart_root(path: Path) -> Path | None:
6363
return None
6464

6565

66+
def _collect_chart_roots(paths: list[Path]) -> set[Path]:
67+
roots: set[Path] = set()
68+
for p in paths:
69+
root = _get_chart_root(p)
70+
if root:
71+
roots.add(root)
72+
return roots
73+
74+
75+
def _is_in_chart(candidate: Path, chart_roots: set[Path]) -> bool:
76+
for chart_root in chart_roots:
77+
try:
78+
if candidate.is_relative_to(chart_root):
79+
return True
80+
except (ValueError, TypeError):
81+
continue
82+
return False
83+
84+
6685
class HelmEdgeBuilder(EdgeBuilder):
6786
weight = 0.70
6887
reverse_weight_factor = 0.45
@@ -79,34 +98,20 @@ def discover_related_files(
7998
if not templates and not values:
8099
return []
81100

82-
chart_roots: set[Path] = set()
83-
for t in templates:
84-
root = _get_chart_root(t)
85-
if root:
86-
chart_roots.add(root)
87-
for v in values:
88-
root = _get_chart_root(v)
89-
if root:
90-
chart_roots.add(root)
91-
101+
chart_roots = _collect_chart_roots(templates + values)
92102
if not chart_roots:
93103
return []
94104

95-
discovered: list[Path] = []
96105
changed_set = set(changed_files)
106+
discovered: list[Path] = []
97107

98108
for candidate in all_candidate_files:
99109
if candidate in changed_set:
100110
continue
101-
102-
for chart_root in chart_roots:
103-
try:
104-
if candidate.is_relative_to(chart_root):
105-
if _is_helm_template(candidate) or _is_helm_values(candidate) or _is_chart_yaml(candidate):
106-
discovered.append(candidate)
107-
break
108-
except (ValueError, TypeError):
109-
continue
111+
if not (_is_helm_template(candidate) or _is_helm_values(candidate) or _is_chart_yaml(candidate)):
112+
continue
113+
if _is_in_chart(candidate, chart_roots):
114+
discovered.append(candidate)
110115

111116
return discovered
112117

@@ -119,50 +124,82 @@ def build(self, fragments: list[Fragment], repo_root: Path | None = None) -> Edg
119124
return {}
120125

121126
edges: EdgeDict = {}
127+
values_idx = self._build_values_index(values_files)
128+
define_defs = self._build_define_index(templates)
122129

123-
values_keys_by_chart: dict[Path, dict[str, list[FragmentId]]] = defaultdict(lambda: defaultdict(list))
130+
for tmpl in templates:
131+
self._add_template_edges(tmpl, values_idx, define_defs, chart_files, edges)
132+
133+
return edges
134+
135+
def _build_values_index(self, values_files: list[Fragment]) -> dict[Path, dict[str, list[FragmentId]]]:
136+
idx: dict[Path, dict[str, list[FragmentId]]] = defaultdict(lambda: defaultdict(list))
124137
for vf in values_files:
125138
chart_root = _get_chart_root(vf.path) or vf.path.parent
126-
keys = _extract_yaml_keys(vf.content)
127-
for key in keys:
128-
values_keys_by_chart[chart_root][key].append(vf.id)
139+
for key in _extract_yaml_keys(vf.content):
140+
idx[chart_root][key].append(vf.id)
141+
return idx
129142

130-
define_defs: dict[str, list[FragmentId]] = defaultdict(list)
143+
def _build_define_index(self, templates: list[Fragment]) -> dict[str, list[FragmentId]]:
144+
defs: dict[str, list[FragmentId]] = defaultdict(list)
131145
for tmpl in templates:
132146
for match in _HELM_DEFINE_RE.finditer(tmpl.content):
133-
define_name = match.group(1)
134-
define_defs[define_name].append(tmpl.id)
135-
136-
for tmpl in templates:
137-
chart_root = _get_chart_root(tmpl.path) or tmpl.path.parent.parent
138-
values_keys = values_keys_by_chart.get(chart_root, {})
139-
140-
for match in _HELM_VALUES_RE.finditer(tmpl.content):
141-
value_path = match.group(1)
142-
parts = value_path.split(".")
143-
144-
for i in range(len(parts), 0, -1):
145-
partial = ".".join(parts[:i])
146-
for values_id in values_keys.get(partial, []):
147-
self.add_edge(edges, tmpl.id, values_id, self.weight)
148-
break
149-
else:
150-
continue
151-
break
152-
153-
if parts[0] in values_keys:
154-
for values_id in values_keys[parts[0]]:
155-
self.add_edge(edges, tmpl.id, values_id, self.weight * 0.8)
156-
157-
for match in _HELM_INCLUDE_RE.finditer(tmpl.content):
158-
include_name = match.group(1)
159-
for def_id in define_defs.get(include_name, []):
160-
if def_id != tmpl.id:
161-
self.add_edge(edges, tmpl.id, def_id, self.weight * 0.9)
162-
163-
for cf in chart_files:
164-
cf_chart_root = _get_chart_root(cf.path) or cf.path.parent
165-
if cf_chart_root == chart_root:
166-
self.add_edge(edges, tmpl.id, cf.id, self.weight * 0.5)
147+
defs[match.group(1)].append(tmpl.id)
148+
return defs
167149

168-
return edges
150+
def _add_template_edges(
151+
self,
152+
tmpl: Fragment,
153+
values_idx: dict[Path, dict[str, list[FragmentId]]],
154+
define_defs: dict[str, list[FragmentId]],
155+
chart_files: list[Fragment],
156+
edges: EdgeDict,
157+
) -> None:
158+
chart_root = _get_chart_root(tmpl.path) or tmpl.path.parent.parent
159+
values_keys = values_idx.get(chart_root, {})
160+
161+
self._add_values_ref_edges(tmpl, values_keys, edges)
162+
self._add_include_edges(tmpl, define_defs, edges)
163+
self._add_chart_file_edges(tmpl, chart_root, chart_files, edges)
164+
165+
def _add_values_ref_edges(self, tmpl: Fragment, values_keys: dict[str, list[FragmentId]], edges: EdgeDict) -> None:
166+
for match in _HELM_VALUES_RE.finditer(tmpl.content):
167+
parts = match.group(1).split(".")
168+
self._link_longest_match(tmpl.id, parts, values_keys, edges)
169+
self._link_root_key(tmpl.id, parts[0], values_keys, edges)
170+
171+
def _link_longest_match(
172+
self,
173+
tmpl_id: FragmentId,
174+
parts: list[str],
175+
values_keys: dict[str, list[FragmentId]],
176+
edges: EdgeDict,
177+
) -> None:
178+
for i in range(len(parts), 0, -1):
179+
partial = ".".join(parts[:i])
180+
values_ids = values_keys.get(partial, [])
181+
if values_ids:
182+
self.add_edge(edges, tmpl_id, values_ids[0], self.weight)
183+
return
184+
185+
def _link_root_key(
186+
self,
187+
tmpl_id: FragmentId,
188+
root_key: str,
189+
values_keys: dict[str, list[FragmentId]],
190+
edges: EdgeDict,
191+
) -> None:
192+
for values_id in values_keys.get(root_key, []):
193+
self.add_edge(edges, tmpl_id, values_id, self.weight * 0.8)
194+
195+
def _add_include_edges(self, tmpl: Fragment, define_defs: dict[str, list[FragmentId]], edges: EdgeDict) -> None:
196+
for match in _HELM_INCLUDE_RE.finditer(tmpl.content):
197+
for def_id in define_defs.get(match.group(1), []):
198+
if def_id != tmpl.id:
199+
self.add_edge(edges, tmpl.id, def_id, self.weight * 0.9)
200+
201+
def _add_chart_file_edges(self, tmpl: Fragment, chart_root: Path, chart_files: list[Fragment], edges: EdgeDict) -> None:
202+
for cf in chart_files:
203+
cf_root = _get_chart_root(cf.path) or cf.path.parent
204+
if cf_root == chart_root:
205+
self.add_edge(edges, tmpl.id, cf.id, self.weight * 0.5)

0 commit comments

Comments
 (0)