Files
project-manager/project_manager/common/template.py
T
shmyga b459eef34b
test / test (push) Successful in 2m20s
feat(preset): add gitea preset
2026-10-03 16:34:32 +03:00

114 lines
3.3 KiB
Python

import json
import re
import tomllib
from pathlib import Path
from typing import Any
import dotenv
from jinja2 import Environment
from ..preset.model import Variables
from .util import get_environ
def do_bool(data: str | None) -> bool:
if data is None:
return False
if not isinstance(data, str):
data = str(data)
return data.lower() not in ["false", "null", "none", "0", ""]
def do_not(value: Any | None) -> bool:
return not do_bool(str(value))
def _build_env(basepath: Path) -> Environment:
env = Environment()
def do_file(filename: str) -> Path | None:
if not filename:
return None
result = Path(filename)
if not result.is_absolute():
result = basepath / result
if result.exists():
return result
return None
def do_read(filename: str) -> dict | None:
path = do_file(filename)
if path:
if path.suffix == ".toml":
return tomllib.loads(path.read_text())
if path.suffix == ".json":
return json.loads(path.read_text())
if path.suffix == ".env" or path.name == ".env":
return dotenv.dotenv_values(path)
return None
def do_get(data: dict | None, keypath: str) -> str | None:
if not data:
return None
path = keypath.split(".")
result = data.get(path[0])
for key in path[1:]:
if result:
result = result.get(key)
return result
def do_search(data: str | None, pattern: str, position: int = 1) -> str | None:
if not data:
return None
matched = re.compile(pattern).search(data)
if matched:
return matched.group(position)
return None
def do_key(data: dict | None, keyindex: int = 0) -> str | None:
if not data:
return None
keys = list(data.keys())
return keys[keyindex]
env_data = get_environ(basepath)
def do_env(key: str, default: str | None = None) -> str | None:
return env_data.get(key.upper(), default)
env.filters["file"] = do_file
env.filters["read"] = do_read
env.filters["get"] = do_get
env.filters["search"] = do_search
env.filters["key"] = do_key
env.filters["bool"] = do_bool
env.filters["env"] = do_env
env.filters["not"] = do_not
return env
class PathTemplate:
def __init__(self, basepath: Path):
self._basepath = basepath
self._env = _build_env(basepath)
def update_variables(self, templates: Variables, variables: Variables):
for k, v in templates.items():
if isinstance(v, dict):
variables[k] = {
kk: self._env.from_string(vv).render(**variables)
for kk, vv in v.items()
}
else:
variables[k] = self._env.from_string(v).render(**variables)
def fill_template(self, template: str, variables: Variables) -> str:
return self._env.from_string(template).render(**variables)
def check_conditions(self, templates: list[str], variables: Variables) -> bool:
for template in templates:
value = self.fill_template(template, variables)
if not do_bool(value):
return False
return True