mirror of
https://github.com/dredx/prole.git
synced 2026-09-27 09:04:30 +00:00
- 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>
67 lines
1.8 KiB
Python
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,
|
|
)
|