"""Vault file IO shared by the markdown frontend and its mirror.""" from __future__ import annotations import contextlib import os import tempfile from typing import TYPE_CHECKING, Any import aiofile import frontmatter if TYPE_CHECKING: from pathlib import Path __all__ = ["read_or_empty", "reattach_frontmatter", "write_atomic"] async def read_or_empty(path: Path) -> str: if not path.exists(): # noqa: ASYNC240 return "" async with aiofile.async_open(path, "r", encoding="utf-8") as f: return await f.read() async def write_atomic(path: Path, content: str) -> None: """Write via tmp + ``os.replace`` in the same directory: no torn reads.""" path.parent.mkdir(parents=True, exist_ok=True) fd, tmp_path = tempfile.mkstemp( prefix=f".{path.name}.", suffix=".tmp", dir=str(path.parent) ) try: async with aiofile.async_open(tmp_path, "w", encoding="utf-8") as f: await f.write(content) os.close(fd) os.replace(tmp_path, path) # noqa: PTH105 except BaseException: with contextlib.suppress(OSError): os.close(fd) with contextlib.suppress(OSError): os.unlink(tmp_path) # noqa: PTH108 raise def reattach_frontmatter(metadata: dict[str, Any], body: str) -> str: """Re-emit a ``.md`` with YAML frontmatter; no block at all for empty metadata.""" if not metadata: return body if body.endswith("\n") else body + "\n" post = frontmatter.Post(content=body, **metadata) return frontmatter.dumps(post) + "\n"