Skip to content

Commit 3847770

Browse files
rd4398claude
andcommitted
fix(bootstrapper): always process highest version for dependency discovery
When all versions are cached, keep the highest version in the work stack so new transitive dependencies are still discovered. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Rohan Devasthale <rdevasth@redhat.com>
1 parent 4d0b03a commit 3847770

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/fromager/bootstrapper.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,10 +1328,15 @@ def _phase_resolve(self, item: WorkItem) -> list[WorkItem]:
13281328
else:
13291329
filtered.append((source_url, version))
13301330
if not filtered:
1331+
# Always process the highest version (first in
1332+
# resolved_versions) so new transitive dependencies
1333+
# are discovered even when every wheel is cached.
13311334
logger.info(
1332-
f"all versions of {item.req.name} already cached, nothing to do"
1335+
f"all versions of {item.req.name} already cached, "
1336+
f"keeping highest version {resolved_versions[0][1]} "
1337+
f"for dependency discovery"
13331338
)
1334-
return []
1339+
filtered.append(resolved_versions[0])
13351340
resolved_versions = filtered
13361341

13371342
# Build list so highest version ends up on top of the stack

tests/test_bootstrapper_iterative.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,16 +307,22 @@ def mock_cache(req: Requirement, version: Version) -> tuple:
307307
versions = {str(it.resolved_version) for it in result}
308308
assert versions == {"1.0", "3.0"}
309309

310-
def test_all_cached_returns_empty(self, tmp_context: WorkContext) -> None:
311-
"""If all versions are cached, returns empty list."""
310+
def test_all_cached_keeps_highest_version(
311+
self, tmp_context: WorkContext
312+
) -> None:
313+
"""If all versions are cached, keeps the highest for dependency discovery."""
312314
bt = bootstrapper.Bootstrapper(tmp_context, multiple_versions=True)
313315
item = _make_resolve_item()
314316

315317
with (
316318
patch.object(
317319
bt,
318320
"resolve_versions",
319-
return_value=[("url-1.0", Version("1.0"))],
321+
return_value=[
322+
("url-3.0", Version("3.0")),
323+
("url-2.0", Version("2.0")),
324+
("url-1.0", Version("1.0")),
325+
],
320326
),
321327
patch.object(
322328
bt,
@@ -326,7 +332,8 @@ def test_all_cached_returns_empty(self, tmp_context: WorkContext) -> None:
326332
):
327333
result = bt._phase_resolve(item)
328334

329-
assert result == []
335+
assert len(result) == 1
336+
assert result[0].resolved_version == Version("3.0")
330337

331338
def test_no_filtering_in_single_version_mode(
332339
self, tmp_context: WorkContext

0 commit comments

Comments
 (0)