Resolve the m2pack-secure binary via M2PACK_BINARY env var or PATH, raising ValidationError(m2pack_not_found) when neither works.
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Resolve the m2pack binary for the m2pack wrapper subcommands.
|
|
|
|
Resolution order:
|
|
|
|
1. ``M2PACK_BINARY`` environment variable, if set, non-empty, and points at
|
|
an existing file.
|
|
2. :func:`shutil.which` on ``m2pack``.
|
|
|
|
If neither works we raise :class:`~metin_release.errors.ValidationError` so
|
|
the CLI exits 1 with a clear, actionable message. Import of this module
|
|
must never trigger filesystem access — all discovery is runtime.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
from .errors import ValidationError
|
|
|
|
|
|
ENV_VAR = "M2PACK_BINARY"
|
|
|
|
_NOT_FOUND_HINT = (
|
|
"m2pack binary not found. Set the M2PACK_BINARY environment variable to "
|
|
"an absolute path, or make `m2pack` available on PATH. Build it from "
|
|
"https://gitea.jakubkadlec.dev/metin-server/m2pack-secure (see its "
|
|
"CMakeLists.txt)."
|
|
)
|
|
|
|
|
|
def resolve_m2pack_binary(env: dict[str, str] | None = None) -> Path:
|
|
"""Return the resolved path to the m2pack binary or raise ValidationError."""
|
|
environ = env if env is not None else os.environ
|
|
override = (environ.get(ENV_VAR) or "").strip()
|
|
if override:
|
|
candidate = Path(override).expanduser()
|
|
if candidate.is_file():
|
|
return candidate.resolve()
|
|
raise ValidationError(
|
|
f"{ENV_VAR}={override!r} does not point at an existing file. "
|
|
f"{_NOT_FOUND_HINT}",
|
|
error_code="m2pack_not_found",
|
|
)
|
|
|
|
which = shutil.which("m2pack")
|
|
if which:
|
|
return Path(which).resolve()
|
|
|
|
raise ValidationError(_NOT_FOUND_HINT, error_code="m2pack_not_found")
|