diff --git a/newsfragments/split_command_entrypoint_after_interpolation.bugfix b/newsfragments/split_command_entrypoint_after_interpolation.bugfix new file mode 100644 index 00000000..9befd360 --- /dev/null +++ b/newsfragments/split_command_entrypoint_after_interpolation.bugfix @@ -0,0 +1 @@ +Split string command and entrypoint values into argument lists after interpolation, matching Compose semantics. diff --git a/podman_compose.py b/podman_compose.py index 307804b9..4b6ca4f3 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2208,6 +2208,9 @@ def normalize_service_final(service: dict[str, Any], project_dir: str) -> dict[s if not isinstance(service["build"], dict): service["build"] = {} service["build"]["context"] = context + for key in ("command", "entrypoint"): + if isinstance(service.get(key), str): + service[key] = shlex.split(service[key]) return service diff --git a/tests/integration/compose_file_from_env/test_podman_compose_compose_file_from_env.py b/tests/integration/compose_file_from_env/test_podman_compose_compose_file_from_env.py index f6c99dc3..9de07d74 100644 --- a/tests/integration/compose_file_from_env/test_podman_compose_compose_file_from_env.py +++ b/tests/integration/compose_file_from_env/test_podman_compose_compose_file_from_env.py @@ -25,7 +25,9 @@ def test_compose_file_from_dotenv(self) -> None: out.decode("utf-8"), 'services:\n' ' dotenv-service:\n' - ' command: echo "from-dotenv"\n' + ' command:\n' + ' - echo\n' + ' - from-dotenv\n' ' image: nopush/podman-compose-test\n' '\n', ) @@ -47,7 +49,9 @@ def test_compose_file_from_explicit_env_file(self) -> None: out.decode("utf-8"), 'services:\n' ' explicit-env-service:\n' - ' command: echo "from-explicit-env"\n' + ' command:\n' + ' - echo\n' + ' - from-explicit-env\n' ' image: nopush/podman-compose-test\n' '\n', ) @@ -70,7 +74,9 @@ def test_explicit_f_overrides_compose_file_from_dotenv(self) -> None: out.decode("utf-8"), 'services:\n' ' explicit-service:\n' - ' command: echo "explicit"\n' + ' command:\n' + ' - echo\n' + ' - explicit\n' ' image: nopush/podman-compose-test\n' '\n', ) @@ -88,7 +94,9 @@ def test_env_var_compose_file_takes_precedence_over_dotenv(self) -> None: out.decode("utf-8"), 'services:\n' ' var-service:\n' - ' command: echo "var"\n' + ' command:\n' + ' - echo\n' + ' - var\n' ' image: nopush/podman-compose-test\n' '\n', ) diff --git a/tests/unit/test_normalize_final_build.py b/tests/unit/test_normalize_final_build.py index e93a78db..5ad4a902 100644 --- a/tests/unit/test_normalize_final_build.py +++ b/tests/unit/test_normalize_final_build.py @@ -104,6 +104,20 @@ def test_normalize_service_final_returns_absolute_path_in_context(self, input, e project_dir = cwd self.assertEqual(normalize_service_final(input, project_dir), expected) + @parameterized.expand([ + ({"image": "busybox", "command": "sleep infinity"}, ["sleep", "infinity"], None), + ({"image": "busybox", "command": ["sleep", "infinity"]}, ["sleep", "infinity"], None), + ({"image": "busybox", "entrypoint": "/bin/sh -c"}, None, ["/bin/sh", "-c"]), + ]) + def test_normalize_service_final_splits_string_command( + self, input, expected_command, expected_entrypoint + ): + # Tests that string [service.command] and [service.entrypoint] are split into + # lists after variable interpolation + actual = normalize_service_final(input, cwd) + self.assertEqual(actual.get("command"), expected_command) + self.assertEqual(actual.get("entrypoint"), expected_entrypoint) + @parameterized.expand(cases_simple_normalization) def test_normalize_returns_absolute_path_in_context(self, input, expected): project_dir = cwd