Skip to content

Commit 6a0dd0b

Browse files
rd4398claude
andcommitted
fix(bootstrap): improve logging and graph cleanup
1. **Fix logging condition for multiple-versions mode** - Change from `if len(results) > 1` to `if self.multiple_versions` - Now logs version count whenever multiple-versions mode is requested, not just when we get more than 1 result - Helps users understand what happened even when 0 or 1 versions match - Applied in both resolve_and_add_top_level() and bootstrap() 2. **Fix dangling parent references in dependency graph** - Problem: remove_dependency() only cleaned up forward edges (children) but not back-references (parents), leaving dangling references - Solution: Before deleting node, iterate children and remove the back-references from each child's parents list - Prevents issues in graph traversals like _collect_dependents() - Updated docstring to document both cleanup operations All 447 unit tests pass. All graph-related e2e tests pass. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Signed-off-by: Rohan Devasthale <rdevasth@redhat.com>
1 parent 321a95f commit 6a0dd0b

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

src/fromager/bootstrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def resolve_and_add_top_level(
162162
req_type=RequirementType.TOP_LEVEL,
163163
return_all_versions=self.multiple_versions,
164164
)
165-
if len(results) > 1:
165+
if self.multiple_versions:
166166
logger.info(f"resolved {len(results)} version(s) for {req}")
167167

168168
# Add all resolved versions to the graph
@@ -289,7 +289,7 @@ def bootstrap(self, req: Requirement, req_type: RequirementType) -> None:
289289
req_type=req_type,
290290
return_all_versions=self.multiple_versions,
291291
)
292-
if len(resolved_versions) > 1:
292+
if self.multiple_versions:
293293
logger.info(f"resolved {len(resolved_versions)} version(s) for {req}")
294294
except Exception as err:
295295
if not self.test_mode:

src/fromager/dependency_graph.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ def remove_dependency(
343343
) -> None:
344344
"""Remove a dependency node from the graph.
345345
346-
Removes the node and all edges pointing to it from parent nodes.
346+
Removes the node and all edges pointing to it. This includes:
347+
- Back-references in child nodes' parents lists
348+
- Forward edges in parent nodes' children lists
347349
Child nodes of the removed node are kept if referenced elsewhere.
348350
349351
Args:
@@ -357,11 +359,21 @@ def remove_dependency(
357359

358360
logger.debug(f"Removing failed dependency {key} from graph")
359361

362+
deleted_node = self.nodes[key]
363+
364+
# Clean up back-references (parents) in nodes that were children of the removed node
365+
for child_edge in deleted_node.children:
366+
child_node = child_edge.destination_node
367+
filtered_parents = [
368+
edge for edge in child_node.parents if edge.destination_node.key != key
369+
]
370+
child_node.parents.clear()
371+
child_node.parents.extend(filtered_parents)
372+
360373
# Remove the node itself
361374
del self.nodes[key]
362375

363-
# Remove all edges pointing to this node from parent nodes
364-
# Use list comprehension to filter, then clear and re-add
376+
# Remove forward edges from any node whose children pointed to the removed node
365377
for node in self.nodes.values():
366378
filtered_children = [
367379
edge for edge in node.children if edge.destination_node.key != key

0 commit comments

Comments
 (0)