| | |
| | | from enum import Enum |
| | | from pathlib import Path |
| | | from concurrent.futures import ProcessPoolExecutor |
| | | from typing import Any |
| | | from typing import Any, TYPE_CHECKING |
| | | if TYPE_CHECKING: |
| | | from archrepobuild.repo import RepoManager |
| | | |
| | | from archrepobuild.aur import AURClient |
| | | from archrepobuild.config import Config, PackageOverride |
| | |
| | | self, |
| | | config: Config, |
| | | aur_client: AURClient, |
| | | repo: RepoManager | None = None, |
| | | ): |
| | | """Initialize builder. |
| | | |
| | | Args: |
| | | config: Application configuration |
| | | aur_client: AUR client for package info |
| | | repo: Optional repository manager for incremental registration |
| | | """ |
| | | self.config = config |
| | | self.aur_client = aur_client |
| | | self.repo = repo |
| | | self.resolver = DependencyResolver(aur_client) |
| | | self._lock_dir = config.repository.build_dir / ".locks" |
| | | self._executor: ProcessPoolExecutor | None = None |
| | |
| | | error=str(e), |
| | | ) |
| | | |
| | | async def add_package(self, package: str) -> BuildResult: |
| | | async def add_package(self, package: str, include_repo: bool = False) -> BuildResult: |
| | | """Add and build (or download) a new package with dependencies. |
| | | |
| | | Args: |
| | | package: Package name |
| | | include_repo: Whether to check the managed repository for existing packages |
| | | |
| | | Returns: |
| | | BuildResult for the main package |
| | |
| | | logger.info(f"Adding package: {package}") |
| | | |
| | | # Resolve dependencies |
| | | build_order = await self.resolver.resolve([package]) |
| | | exclude_repo = None if include_repo else self.config.repository.name |
| | | build_order = await self.resolver.resolve([package], exclude_repo=exclude_repo) |
| | | |
| | | # Filter build order: skip managed repo, download others, build AUR |
| | | final_results: list[BuildResult] = [] |
| | |
| | | repo = self.resolver.is_in_repos(pkg_name) |
| | | |
| | | if repo == self.config.repository.name: |
| | | logger.info(f"Package {pkg_name} already in managed repository, skipping") |
| | | if pkg_name == package: |
| | | return BuildResult(package=package, status=BuildStatus.SKIPPED) |
| | | continue |
| | | if include_repo: |
| | | logger.info(f"Package {pkg_name} already in managed repository, skipping") |
| | | if pkg_name == package: |
| | | return BuildResult(package=package, status=BuildStatus.SKIPPED) |
| | | continue |
| | | else: |
| | | # Treat as not in repo to force rebuild from AUR |
| | | repo = None |
| | | |
| | | if repo: |
| | | logger.info(f"Package {pkg_name} found in {repo}, downloading...") |
| | |
| | | |
| | | final_results.append(result) |
| | | |
| | | if result.status == BuildStatus.FAILED: |
| | | if result.status == BuildStatus.SUCCESS: |
| | | if self.repo: |
| | | added = self.repo.add_packages(result) |
| | | if added: |
| | | logger.info(f"Added to repository: {', '.join(added)}") |
| | | # Refresh resolver cache to recognize the newly added packages |
| | | self.resolver._refresh_pacman_cache(sync=True) |
| | | elif result.status == BuildStatus.FAILED: |
| | | logger.error(f"Failed to process {pkg_name}, aborting") |
| | | if pkg_name == package: |
| | | return result |