py/facett_demo/buildinfo.py
"""Version + git-hash stamp (build-version-githash LAW).
Every binary/app in the suite embeds its version + git-hash, SHOWS it in the app
(here: the sidebar) and answers a ``--version``/about query. We resolve the hash
in three tiers, most-authoritative first:
1. a baked ``_buildinfo.py`` (written by ``scripts/stamp.py`` at build/commit time);
2. a live ``git rev-parse`` of the checkout the package sits in (dev runs);
3. the literal ``"unknown"`` — an HONEST fallback, never a fake hash.
"""
from __future__ import annotations
import subprocess
from importlib import metadata as _metadata
from pathlib import Path
#: The package version, read from the INSTALLED distribution's own metadata — the
#: ONE writer is py/pyproject.toml (held to facett-build-thing's PYPI_VERSION by
#: xtask/tests/python_versions_track_the_workspace.rs). A source checkout that was
#: never installed answers `0+unknown` rather than a plausible-looking stale literal
#: (the components package learned that the hard way: 0.1.15 inside a 0.1.19 wheel).
try:
__version__ = _metadata.version("facett-demo")
except _metadata.PackageNotFoundError: # pragma: no cover - source checkout only
__version__ = "0+unknown"
_UNKNOWN = "unknown"
def _baked() -> tuple[str, str] | None:
"""Return (git_hash, build_time) baked at build time, or None."""
try:
from . import _buildinfo # type: ignore
return (
getattr(_buildinfo, "GIT_HASH", _UNKNOWN),
getattr(_buildinfo, "BUILD_TIME", _UNKNOWN),
)
except Exception:
return None
def _live_git_hash() -> str:
"""Best-effort short hash of the checkout this file lives in."""
try:
out = subprocess.run(
["git", "rev-parse", "--short", "HEAD"],
cwd=str(Path(__file__).resolve().parent),
capture_output=True,
text=True,
timeout=3,
)
if out.returncode == 0:
h = out.stdout.strip()
if h:
return h
except Exception:
pass
return _UNKNOWN
def build_info() -> dict[str, str]:
"""Resolve {version, git_hash, build_time, source} for display + --version."""
baked = _baked()
if baked is not None and baked[0] != _UNKNOWN:
git_hash, build_time = baked
source = "baked"
else:
git_hash = _live_git_hash()
build_time = _UNKNOWN
source = "live-git" if git_hash != _UNKNOWN else "none"
return {
"version": __version__,
"git_hash": git_hash,
"build_time": build_time,
"source": source,
}
def version_string() -> str:
"""A one-line version banner, mirroring facett's ``<ver> (<hash>)`` form."""
bi = build_info()
return f"facett-demo {bi['version']} ({bi['git_hash']})"