"""Entry point for the review agent: loads its configuration, checks its access, and reviews until told to stop.""" import os import signal import sys from pathlib import Path from types import FrameType from nisse_core.config import ConfigError from nisse_core.envfile import load_env_file from nisse_core.gitea import GiteaError from nisse_review.access import AccessRefused from nisse_review.build import StartupError, build from nisse_review.config import ReviewConfig def main() -> int: load_env_file(Path(os.environ.get("NISSE_ENV", ".env")).expanduser()) try: config = ReviewConfig.load() built = build(config) except (ConfigError, StartupError, GiteaError) as exc: print(f"nisse-review: {exc}", file=sys.stderr) return 2 def shutdown(_signum: int, _frame: FrameType | None) -> None: print("nisse-review: stopping", file=sys.stderr) built.stop() signal.signal(signal.SIGINT, shutdown) signal.signal(signal.SIGTERM, shutdown) print( f"nisse-review: ready as {built.account}, reading " + (", ".join(built.repositories) or "no repositories"), file=sys.stderr, ) try: built.scheduler.run_forever() except AccessRefused as exc: # R3: a grant made while it ran. It stops rather than review on. print(f"nisse-review: stopping: {exc}", file=sys.stderr) return 3 finally: built.close() return 0 if __name__ == "__main__": sys.exit(main())