81 lines
1.8 KiB
Python
81 lines
1.8 KiB
Python
import os
|
|
import json
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
|
|
# Resolve cache directory with graceful fallbacks for unprivileged environments
|
|
def _resolve_cache_dir() -> Path:
|
|
env = os.environ.get("FESTER_CACHE_DIR")
|
|
if env:
|
|
p = Path(env)
|
|
p.mkdir(parents=True, exist_ok=True)
|
|
return p
|
|
for c in [
|
|
Path("/var/lib/fester/cache"),
|
|
Path.home() / ".fester" / "cache",
|
|
Path("/tmp/fester_cache"),
|
|
]:
|
|
try:
|
|
c.mkdir(parents=True, exist_ok=True)
|
|
return c
|
|
except (OSError, PermissionError):
|
|
continue
|
|
# Last-resort in-memory (caller must handle None)
|
|
return None
|
|
|
|
|
|
CACHE_DIR = _resolve_cache_dir()
|
|
|
|
|
|
def hash_dict(d):
|
|
raw = json.dumps(d, sort_keys=True).encode()
|
|
return hashlib.sha256(raw).hexdigest()
|
|
|
|
|
|
def make_build_key(snapshot_hash, target, env):
|
|
return hashlib.sha256(
|
|
f"{snapshot_hash}:{target}:{hash_dict(env)}".encode()
|
|
).hexdigest()
|
|
|
|
|
|
def cache_hit(key):
|
|
if CACHE_DIR is None:
|
|
return False
|
|
return (CACHE_DIR / key / "done").exists()
|
|
|
|
|
|
def cache_store(key, log):
|
|
if CACHE_DIR is None:
|
|
return False
|
|
base = CACHE_DIR / key
|
|
base.mkdir(parents=True, exist_ok=True)
|
|
|
|
(base / "done").write_text("1")
|
|
(base / "log.txt").write_text(log)
|
|
return True
|
|
|
|
|
|
def cache_log(key):
|
|
if CACHE_DIR is None:
|
|
return None
|
|
p = CACHE_DIR / key / "log.txt"
|
|
return p.read_text() if p.exists() else None
|
|
|
|
|
|
# ----------------------------
|
|
# ccache health probe
|
|
# ----------------------------
|
|
def ccache_stats():
|
|
try:
|
|
import subprocess
|
|
|
|
out = subprocess.check_output(
|
|
["ccache", "-s"],
|
|
stderr=subprocess.STDOUT
|
|
).decode()
|
|
|
|
return out
|
|
except:
|
|
return "ccache not available"
|