mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 08:57:12 +00:00
73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Helpers for reading repo files from either the working tree or the git index."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
from typing import Any, Iterable
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
DEFAULT_REPO_ROOT = REPO_ROOT
|
|
|
|
|
|
def git_env() -> dict[str, str]:
|
|
env = os.environ.copy()
|
|
if REPO_ROOT != DEFAULT_REPO_ROOT:
|
|
env.pop("GIT_INDEX_FILE", None)
|
|
return env
|
|
|
|
|
|
def repo_relative_path(path: str | Path) -> str:
|
|
candidate = Path(path)
|
|
if candidate.is_absolute():
|
|
candidate = candidate.relative_to(REPO_ROOT)
|
|
return candidate.as_posix()
|
|
|
|
|
|
def read_repo_text(path: str | Path, *, staged: bool = False, strict_staged: bool = False) -> str:
|
|
rel = repo_relative_path(path)
|
|
if staged:
|
|
try:
|
|
result = subprocess.run(
|
|
["git", "show", f":{rel}"],
|
|
cwd=REPO_ROOT,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
env=git_env(),
|
|
)
|
|
return result.stdout
|
|
except subprocess.CalledProcessError:
|
|
if strict_staged:
|
|
raise FileNotFoundError(f"missing staged index entry for {rel}") from None
|
|
return (REPO_ROOT / rel).read_text(encoding="utf-8")
|
|
|
|
|
|
def staged_path_exists(path: str | Path) -> bool:
|
|
rel = repo_relative_path(path)
|
|
result = subprocess.run(
|
|
["git", "cat-file", "-e", f":{rel}"],
|
|
cwd=REPO_ROOT,
|
|
check=False,
|
|
capture_output=True,
|
|
text=True,
|
|
env=git_env(),
|
|
)
|
|
return result.returncode == 0
|
|
|
|
|
|
def missing_staged_repo_paths(paths: Iterable[str | Path]) -> list[str]:
|
|
missing: list[str] = []
|
|
for path in paths:
|
|
rel = repo_relative_path(path)
|
|
if not staged_path_exists(rel):
|
|
missing.append(rel)
|
|
return missing
|
|
|
|
|
|
def load_repo_json(path: str | Path, *, staged: bool = False, strict_staged: bool = False) -> dict[str, Any]:
|
|
return json.loads(read_repo_text(path, staged=staged, strict_staged=strict_staged))
|