import os import asyncio from .pkgbuild import PKGBUILD from asyncio import subprocess from async_property import async_cached_property class PackageException(Exception): pass class Package(object): def __init__(self, repo, config): self.repo = repo self.config = config async def _exec(self, *args, check=True): p = await asyncio.create_subprocess_exec(*args, cwd=self.path, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, stderr = await p.communicate() if check and p.returncode: raise PackageException(stdout.decode("utf-8")) return p.returncode, stdout async def _execAll(self, *tasks, check=True): output = "" for args in tasks: code, stdout = await self._exec(*args, check=False) output += stdout.decode('utf-8') if code: if check: print(output) break return code, output async def _git(self, *args, check=True): return await self._exec('git', *args, check=check) async def _gitAll(self, *tasks, check=True): for args in tasks: args.insert(0, 'git') return await self._execAll(*tasks, check=check) async def _clone(self): if not os.path.exists(self.path): os.makedirs(self.path) return await self._gitAll( ["init"], ["remote", "add", "origin", self.url], ["fetch", "origin"], ["checkout", "master"]) @property def name(self): return self.config["name"] @property def url(self): return self.config.get("url") or "https://aur.archlinux.org/{}.git".format( self.name) @property def path(self): return os.path.join(self.repo.config.config['cachedir'], self.name) @async_cached_property async def PKGBUILD(self): if not os.path.exists(self.path): await self._clone() if not os.path.exists(os.path.join(self.path, "PKGBUILD")): await self.update() if not hasattr(self, '_PKGBUILD'): self._PKGBUILD = PKGBUILD(os.path.join(self.path, 'PKGBUILD')) return self._PKGBUILD async def update(self): if not os.path.exists(os.path.join(self.path, '.git')): return await self._clone(check=False) else: return await self._gitAll( ["remote", "set-url", "origin", self.url], ["checkout", "-f"], ["fetch", "--prune", "origin"], ["checkout", "-B", "master", "origin/master"], check=False) async def makepkg(self, force=False): if force: return await self._exec("makepkg", "-f", check=False) else: return await self._exec("makepkg", check=False) class Repo(object): def __init__(self, config): self.config = config self.packages = [] for package in self.config["packages"]: if isinstance(package, str): self.packages.append(Package(self, dict(name=package))) else: self.packages.append(Package(self, package)) @property def name(self): return self.config.name @property def id(self): return self.config.id