Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/fix_extends_dependency_merge.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix extending services with dependents failing while merging internal dependency metadata.
9 changes: 5 additions & 4 deletions podman_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -2333,12 +2333,13 @@ def resolve_extends(
normalize_service(from_service, subdirectory)
else:
from_service = services.get(from_service_name, {}).copy()
try:
del from_service["_deps"]
except KeyError as e:
if DependField.DEPENDENCIES not in from_service:
raise KeyError(
f"{from_service_name} not found at services.{name}.extends definition"
) from e
)
# These fields are computed again after all extends references are resolved.
for field in DependField:
from_service.pop(field, None)
try:
del from_service["extends"]
except KeyError:
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/test_rec_merge_depends_on.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

from parameterized import parameterized

from podman_compose import flat_deps
from podman_compose import rec_merge
from podman_compose import resolve_extends


class TestRecMergeDependsOn(unittest.TestCase):
Expand Down Expand Up @@ -90,3 +92,26 @@ def test_three_way_mixed_depends_on(self) -> None:
"environment": {"FOO": "bar"},
},
)

def test_extends_services_with_dependents(self) -> None:
services: dict[str, dict[str, Any]] = {
"base": {"image": "base"},
"child": {"extends": {"service": "base"}, "command": ["run"]},
"base_consumer": {
"depends_on": {"base": {"condition": "service_started"}},
},
"child_consumer": {
"depends_on": {"child": {"condition": "service_started"}},
},
}

flat_deps(services, with_extends=True)
service_names = sorted((len(service["_deps"]), name) for name, service in services.items())
resolve_extends(services, [name for _, name in service_names], {})

self.assertEqual(services["child"]["image"], "base")
self.assertEqual(services["child"]["command"], ["run"])
self.assertEqual(
{dependency.name for dependency in services["child"]["_dependents"]},
{"child_consumer"},
)