Repository: gabrieldemarmiesse/python-on-whales (language: python)

Issue:
Missing docker compose --env-file option
Hello,
I haven't the .env file in the same location of the compose .yml configurations, so that I need to specify a custom .env path location but currently python on whales does not support this option

I did some tests on my local copy and this is working for me:

https://github.com/mdantonio/python-on-whales/commit/1bcf7962a41ce91bfbe1128fbcdb3112fa09d400

Of course I can send a PR, but tests are missing there


Discussion / hints:

Fix patch:
diff --git a/python_on_whales/client_config.py b/python_on_whales/client_config.py
index d2cd6c46..454940a9 100644
--- a/python_on_whales/client_config.py
+++ b/python_on_whales/client_config.py
@@ -51,6 +51,7 @@ class ClientConfig:
     tlsverify: Optional[bool] = None
     client_binary_path: Optional[ValidPath] = None
     compose_files: List[ValidPath] = field(default_factory=list)
+    compose_env_file: Optional[ValidPath] = None
 
     def get_docker_path(self) -> ValidPath:
         if self.client_binary_path is None:
@@ -119,6 +120,8 @@ def docker_cmd(self) -> Command:
     def docker_compose_cmd(self) -> Command:
         base_cmd = self.docker_cmd + ["compose"]
         base_cmd.add_args_list("--file", self.compose_files)
+        base_cmd.add_simple_arg("--env-file", self.compose_env_file)
+
         return base_cmd
 
 
diff --git a/python_on_whales/docker_client.py b/python_on_whales/docker_client.py
index 82dc9b01..5d2aab81 100644
--- a/python_on_whales/docker_client.py
+++ b/python_on_whales/docker_client.py
@@ -50,6 +50,9 @@ class DockerClient(DockerCLICaller):
            (default "info")
         tls:  Use TLS; implied by `tlsverify`
         tlscacert: Trust certs signed only by this CA (default "~/.docker/ca.pem")
+        compose_files: Docker compose yaml file
+        compose_env_file: .env file containing the environments variables to inject
+            into the compose project. By default, it uses `./.env`.
     """
 
     def __init__(
@@ -66,6 +69,7 @@ def __init__(
         tlsverify: Optional[bool] = None,
         client_config: Optional[ClientConfig] = None,
         compose_files: List[ValidPath] = [],
+        compose_env_file: Optional[ValidPath] = None,
     ):
 
         if client_config is None:
@@ -81,6 +85,7 @@ def __init__(
                 tlskey=tlskey,
                 tlsverify=tlsverify,
                 compose_files=compose_files,
+                compose_env_file=compose_env_file,
             )
         super().__init__(client_config)
 


Test patch:
diff --git a/tests/python_on_whales/components/dummy_compose_ends_quickly.yml b/tests/python_on_whales/components/dummy_compose_ends_quickly.yml
index e8d375fa..78e7a77d 100644
--- a/tests/python_on_whales/components/dummy_compose_ends_quickly.yml
+++ b/tests/python_on_whales/components/dummy_compose_ends_quickly.yml
@@ -21,3 +21,4 @@ services:
     environment:
      - DD_API_KEY=__your_datadog_api_key_here__
      - POSTGRES_HOST_AUTH_METHOD=trust
+     - SOME_VARIABLE=${SOME_VARIABLE_TO_INSERT}
diff --git a/tests/python_on_whales/components/test_compose.py b/tests/python_on_whales/components/test_compose.py
index 0386e909..06cc16f5 100644
--- a/tests/python_on_whales/components/test_compose.py
+++ b/tests/python_on_whales/components/test_compose.py
@@ -1,4 +1,5 @@
 from datetime import timedelta
+from pathlib import Path
 
 import pytest
 
@@ -157,3 +158,18 @@ def test_docker_compose_up_abort_on_container_exit():
     for container in docker.compose.ps():
         assert not container.state.running
     docker.compose.down()
+
+
+def test_passing_env_files(tmp_path: Path):
+    compose_env_file = tmp_path / "dodo.env"
+    compose_env_file.write_text("SOME_VARIABLE_TO_INSERT=hello\n")
+    docker = DockerClient(
+        compose_files=[
+            PROJECT_ROOT
+            / "tests/python_on_whales/components/dummy_compose_ends_quickly.yml"
+        ],
+        compose_env_file=compose_env_file,
+    )
+    output = docker.compose.config()
+
+    assert output.services["alpine"].environment["SOME_VARIABLE"] == "hello"