6.NUR/ci/nur/update.py
2026-01-29 22:20:54 -08:00

79 lines
2.6 KiB
Python

import asyncio
import logging
from argparse import Namespace
from typing import List, Optional, Tuple
from .eval import EvalError, eval_repo
from .manifest import LockedVersion, Repo, load_manifest, update_lock_file
from .path import LOCK_PATH, MANIFEST_PATH
from .prefetch import prefetcher_for
logger = logging.getLogger(__name__)
async def update(repo: Repo) -> Repo:
prefetcher = prefetcher_for(repo)
latest_commit = await prefetcher.latest_commit()
if repo.locked_version is not None and repo.locked_version.rev == latest_commit:
return repo
sha256, repo_path = await prefetcher.prefetch(latest_commit)
await eval_repo(repo, repo_path)
repo.locked_version = LockedVersion(
repo.url, latest_commit, sha256, repo.submodules
)
return repo
async def update_command(args: Namespace) -> None:
logging.basicConfig(level=logging.INFO)
manifest = load_manifest(MANIFEST_PATH, LOCK_PATH)
log_lock = asyncio.Lock() # serialize success/error output
results: List[Tuple[int, Optional[Repo], Optional[BaseException]]] = []
async def run_one(i: int, repo: Repo) -> None:
try:
updated = await update(repo)
results.append((i, updated, None))
async with log_lock:
if updated.locked_version is not None:
logger.info(
f"Updated repository {repo.name} -> {updated.locked_version.rev}"
)
else:
logger.info(f"Updated repository {repo.name}")
except BaseException as e:
results.append((i, None, e))
async with log_lock:
if isinstance(e, EvalError) and repo.locked_version is None:
logger.error(
f"repository {repo.name} failed to evaluate: {e}. "
"This repo is not yet in our lock file!!!!"
)
elif isinstance(e, EvalError):
logger.error(f"repository {repo.name} failed to evaluate: {e}")
else:
logger.exception(
f"Failed to update repository {repo.name}", exc_info=e
)
tasks = [
asyncio.create_task(run_one(i, repo)) for i, repo in enumerate(manifest.repos)
]
await asyncio.gather(*tasks)
updated_repos: List[Repo] = list(manifest.repos)
for i, updated, err in results:
if err is None and updated is not None:
updated_repos[i] = updated
update_lock_file(updated_repos, LOCK_PATH)