Coverage for src / openenv / core / utils.py: 100.00%
22 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"""Utility helpers."""
3from __future__ import annotations
5import base64
6import hashlib
7import json
8import re
9from typing import Any
12_NAME_NORMALIZER = re.compile(r"[^a-z0-9]+")
13_HOME_OPENCLAW_WORKSPACE_PATTERN = re.compile(
14 r"(?:/home/[A-Za-z0-9._-]+|/root|\$HOME|\$\{HOME\}|~)/\.openclaw/workspace(?=(?:/|\b|$))"
15)
16_HOME_OPENCLAW_STATE_PATTERN = re.compile(
17 r"(?:/home/[A-Za-z0-9._-]+|/root|\$HOME|\$\{HOME\}|~)/\.openclaw(?=(?:/|\b|$))"
18)
21def stable_json_dumps(value: Any, *, indent: int | None = None) -> str:
22 """Serialize data deterministically."""
23 return json.dumps(value, indent=indent, sort_keys=True, ensure_ascii=True)
26def sha256_text(text: str) -> str:
27 """Return the SHA-256 digest of UTF-8 text."""
28 return hashlib.sha256(text.encode("utf-8")).hexdigest()
31def slugify_name(value: str) -> str:
32 """Normalize a project name for file and image tags."""
33 normalized = _NAME_NORMALIZER.sub("-", value.strip().lower()).strip("-")
34 return normalized or "openclawenv-agent"
37def encode_payload(value: Any) -> str:
38 """Encode JSON payload as base64 for embedding in Dockerfile."""
39 encoded = stable_json_dumps(value, indent=None).encode("utf-8")
40 return base64.b64encode(encoded).decode("ascii")
43def rewrite_openclaw_home_paths(text: str, *, state_dir: str, workspace: str) -> str:
44 """Rewrite hard-coded home-based OpenClaw paths to runtime-specific directories."""
45 rewritten = _HOME_OPENCLAW_WORKSPACE_PATTERN.sub(workspace, text)
46 return _HOME_OPENCLAW_STATE_PATTERN.sub(state_dir, rewritten)