Coverage for src / openenv / docker / builder.py: 100.00%
23 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 13:36 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 13:36 +0000
1"""Docker image build helpers."""
3from __future__ import annotations
5import subprocess
6import tempfile
7from pathlib import Path
9from openenv.core.errors import CommandError
10from openenv.core.utils import slugify_name
13def default_image_tag(project_name: str, version: str) -> str:
14 """Compute the default docker tag for a project."""
15 return f"openclawenv/{slugify_name(project_name)}:{version}"
18def build_image(dockerfile_text: str, tag: str) -> None:
19 """Build a Docker image from a rendered Dockerfile."""
20 build_image_with_args(dockerfile_text, tag, build_args=None)
23def build_image_with_args(
24 dockerfile_text: str,
25 tag: str,
26 *,
27 build_args: dict[str, str] | None,
28) -> None:
29 """Build a Docker image from a rendered Dockerfile with optional build args."""
30 with tempfile.TemporaryDirectory(prefix="openclawenv-build-") as temp_dir:
31 dockerfile_path = Path(temp_dir) / "Dockerfile"
32 dockerfile_path.write_text(dockerfile_text, encoding="utf-8")
33 command = [
34 "docker",
35 "build",
36 "--tag",
37 tag,
38 "--file",
39 str(dockerfile_path),
40 temp_dir,
41 ]
42 for key, value in sorted((build_args or {}).items()):
43 command.extend(["--build-arg", f"{key}={value}"])
44 try:
45 subprocess.run(command, check=True)
46 except OSError as exc:
47 raise CommandError("Docker is not available on PATH.") from exc
48 except subprocess.CalledProcessError as exc:
49 raise CommandError(
50 f"Docker build failed for tag {tag} with exit code {exc.returncode}."
51 ) from exc