import argparse import os from pathlib import Path from minio import Minio from minio.error import S3Error from main import ( ConfigurationError, _create_minio_client, _ensure_bucket, _parse_publish_targets, ) REPO_PREFIX = "arch/x86_64" DATABASE_NAME = "gitty.db.tar.gz" def _targets(): bucket_name = (os.environ.get("S3_BUCKET") or "gitty").lower() app_dir = (os.environ.get("APP_DIR") or "gitty").strip("/") return _parse_publish_targets(bucket_name, app_dir) def download_database(client: Minio, output: Path) -> None: target = _targets()[0] object_name = f"{REPO_PREFIX}/{DATABASE_NAME}" output.parent.mkdir(parents=True, exist_ok=True) try: client.fget_object(target.bucket_name, object_name, str(output)) print(f"Downloaded s3://{target.bucket_name}/{object_name} -> {output}") except S3Error as exc: if exc.code in {"NoSuchKey", "NoSuchObject"}: print("No existing Arch repository database found; creating a new one.") return raise def publish_repository(client: Minio, packages_dir: Path, repo_dir: Path) -> None: packages = sorted(packages_dir.glob("*.pkg.tar.zst")) if not packages: raise FileNotFoundError(f"No .pkg.tar.zst package found in {packages_dir}") repository_files = [ path for path in repo_dir.iterdir() if path.is_file() and path.name.startswith("gitty.") ] if not any(path.name == DATABASE_NAME for path in repository_files): raise FileNotFoundError(f"Missing repository database: {repo_dir / DATABASE_NAME}") for target in _targets(): _ensure_bucket(client, target.bucket_name) for path in [*packages, *repository_files]: object_name = f"{REPO_PREFIX}/{path.name}" client.fput_object(target.bucket_name, object_name, str(path)) print(f"Uploaded {path.name} -> s3://{target.bucket_name}/{object_name}") def main() -> None: parser = argparse.ArgumentParser(description="Manage the Gitty pacman repository on MinIO.") subparsers = parser.add_subparsers(dest="command", required=True) download_parser = subparsers.add_parser("download-db") download_parser.add_argument("--output", type=Path, required=True) publish_parser = subparsers.add_parser("publish") publish_parser.add_argument("--packages-dir", type=Path, required=True) publish_parser.add_argument("--repo-dir", type=Path, required=True) args = parser.parse_args() client = _create_minio_client() if args.command == "download-db": download_database(client, args.output) else: publish_repository(client, args.packages_dir, args.repo_dir) if __name__ == "__main__": try: main() except (ConfigurationError, FileNotFoundError, S3Error) as exc: raise SystemExit(f"Arch repository operation failed: {exc}") from exc