prole/knoe/core/build_context.py
chrisfu 4ee2b259c9 Checkpoint: rename installer to knoe + harden db build context
- Add build-context helper to copy Docker context safely (ignore runtime data, keep symlinks)

- Update UI and core actions to use ~/.prole/build and shared copy helper

- Add/adjust tests and scripts; introduce knoe ops helpers and update manifests

Co-authored-by: Junie <junie@jetbrains.com>
2026-03-22 01:45:21 -07:00

67 lines
1.8 KiB
Python

"""Helpers for preparing Docker build contexts.
These functions exist to make Docker builds robust when running from:
- a source checkout (may contain runtime artifacts like `prole-db/data/`)
- a packaged distribution (resources extracted to a temp dir)
The Docker build context should only contain source-controlled inputs needed
for the image build. Runtime data directories can contain broken symlinks,
concurrently-mutating files, or large volumes that should never be copied.
"""
from __future__ import annotations
import shutil
from pathlib import Path
from typing import Iterable
DEFAULT_IGNORED_NAMES: tuple[str, ...] = (
# Runtime/stateful artifacts (can be huge and may contain dangling paths)
"data",
# Common VCS/cache noise
".git",
"__pycache__",
".pytest_cache",
)
def copy_build_context_dir(
source_dir: Path,
build_dir: Path,
*,
ignored_names: Iterable[str] = DEFAULT_IGNORED_NAMES,
) -> None:
"""Copy a directory tree into `build_dir` for use as a Docker build context.
- Removes any existing `build_dir` first.
- Preserves symlinks (does not follow them).
- Ignores selected directory/file names anywhere in the tree.
"""
source_dir = Path(source_dir)
build_dir = Path(build_dir)
if source_dir.exists() is False:
return
if source_dir.resolve() == build_dir.resolve():
# Nothing to do; copying onto itself is both pointless and dangerous.
return
ignored_set = set(ignored_names)
def _ignore(_dir: str, names: list[str]) -> set[str]:
return {name for name in names if name in ignored_set}
if build_dir.exists():
shutil.rmtree(build_dir)
shutil.copytree(
source_dir,
build_dir,
symlinks=True,
ignore=_ignore,
ignore_dangling_symlinks=True,
)