cc-os/plugins/os-status/hooks/state.py

86 lines
2.8 KiB
Python
Raw Normal View History

"""Per-project state for os-status (deep module).
Owns the gitignored .cc-os/ directory contract: key=value config, per-check
once-per-day snooze stamps (snooze-<check>), and permanent suppress markers
(suppress-<check>). State only, never code; nothing here writes outside
.cc-os/. Fail-open throughout: unreadable state reads as unset.
"""
from __future__ import annotations
from datetime import date
from pathlib import Path
from typing import Optional
def find_project_root(cwd: Path) -> Optional[Path]:
"""Nearest ancestor (including cwd) containing .git, else None."""
for candidate in [cwd, *cwd.parents]:
if (candidate / ".git").exists():
return candidate
return None
def read_config(root: Path) -> dict:
"""Parse .cc-os/config as '#'-commented key = value lines."""
config = {}
try:
text = (root / ".cc-os" / "config").read_text()
except Exception:
return config
for line in text.splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
config[key.strip()] = value.strip()
return config
def write_config_value(root: Path, key: str, value: str) -> None:
"""Set key=value in .cc-os/config, preserving every other line
(comments included) and appending the key if absent. Used by
/os-status:fix to stamp the config 'version' key."""
config_path = root / ".cc-os" / "config"
try:
lines = config_path.read_text().splitlines()
except Exception:
lines = []
found = False
out = []
for line in lines:
stripped = line.strip()
if stripped and not stripped.startswith("#") and "=" in stripped:
existing_key = stripped.split("=", 1)[0].strip()
if existing_key == key:
out.append(f"{key} = {value}")
found = True
continue
out.append(line)
if not found:
out.append(f"{key} = {value}")
config_path.parent.mkdir(exist_ok=True)
config_path.write_text("\n".join(out) + "\n")
class StateDir:
"""The gitignored per-project .cc-os/ state directory."""
def __init__(self, root: Path) -> None:
self._dir = root / ".cc-os"
def suppressed(self, check: str) -> bool:
return (self._dir / f"suppress-{check}").exists()
def snoozed(self, check: str, today: date) -> bool:
try:
stamped = date.fromisoformat(
(self._dir / f"snooze-{check}").read_text().strip()
)
except Exception:
return False
return stamped == today
def stamp(self, check: str, today: date) -> None:
self._dir.mkdir(exist_ok=True)
(self._dir / f"snooze-{check}").write_text(today.isoformat())