Browse Source

Begin converting to async

Nathaniel van Diepen 3 years ago
parent
commit
4bfc70e700
3 changed files with 46 additions and 34 deletions
  1. 14 6
      pacman_repo/__init__.py
  2. 31 28
      pacman_repo/repo.py
  3. 1 0
      requirements.txt

+ 14 - 6
pacman_repo/__init__.py

@@ -1,4 +1,5 @@
 import sys
+import asyncio
 import argparse
 
 from .config import Config
@@ -7,17 +8,24 @@ from .repo import Repo
 from . import server
 
 
-def update(args, config):
+async def _update(package, args):
+    print("  {0}: {1}".format(package.name, package.url))
+    await package.update()
+    await package.makepkg(args.force)
+
+
+async def update(args, config):
     for repo in config.repos:
         repo = Repo(repo)
         print("Repo: {}".format(repo.name))
+        tasks = []
         for package in repo.packages:
-            package.update()
-            print("  {0}: {1}".format(package.name, package.url))
-            package.makepkg(args.force)
+            tasks.append(_update(package, args))
+
+        await asyncio.gather(*tasks)
 
 
-def webserver(args, config):
+async def webserver(args, config):
     server.start()
 
 
@@ -53,7 +61,7 @@ def main(argv):
     args = parser.parse_args(argv)
     try:
         config = Config(args.config)
-        args.func(args, config)
+        asyncio.run(args.func(args, config))
 
     except Exception:
         from traceback import format_exc

+ 31 - 28
pacman_repo/repo.py

@@ -1,7 +1,9 @@
 import os
-import subprocess
+import asyncio
 
 from .pkgbuild import PKGBUILD
+from asyncio import subprocess
+from async_property import async_cached_property
 
 
 class Package(object):
@@ -9,25 +11,26 @@ class Package(object):
         self.repo = repo
         self.config = config
 
-    def _exec(self, *args):
-        try:
-            subprocess.run(args, cwd=self.path, capture_output=True, check=True,
-                    text=True)
+    async def _exec(self, *args):
+        p = await asyncio.create_subprocess_exec(*args,
+                cwd=self.path,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT)
+        stdout, stderr = await p.communicate()
+        if p.returncode:
+            print(stdout.decode("utf-8"))
 
-        except subprocess.CalledProcessError as e:
-            print("\n".join([e.stdout, e.stderr]))
+    async def _git(self, *args):
+        await self._exec('git', *args)
 
-    def _git(self, *args):
-        self._exec('git', *args)
-
-    def _clone(self):
+    async def _clone(self):
         if not os.path.exists(self.path):
             os.makedirs(self.path)
 
-        self._git("init")
-        self._git("remote", "add", "origin", self.url)
-        self._git("fetch", "origin")
-        self._git("checkout", "master")
+        await self._git("init")
+        await self._git("remote", "add", "origin", self.url)
+        await self._git("fetch", "origin")
+        await self._git("checkout", "master")
 
     @property
     def name(self):
@@ -42,34 +45,34 @@ class Package(object):
     def path(self):
         return os.path.join(self.repo.config.config['cachedir'], self.name)
 
-    @property
-    def PKGBUILD(self):
+    @async_cached_property
+    async def PKGBUILD(self):
         if not os.path.exists(self.path):
-            self._clone()
+            await self._clone()
 
         if not os.path.exists(os.path.join(self.path, "PKGBUILD")):
-            self.update()
+            await self.update()
 
         if not hasattr(self, '_PKGBUILD'):
             self._PKGBUILD = PKGBUILD(os.path.join(self.path, 'PKGBUILD'))
 
         return self._PKGBUILD
 
-    def update(self):
+    async def update(self):
         if not os.path.exists(os.path.join(self.path, '.git')):
-            self._clone()
+            await self._clone()
 
         else:
-            self._git("remote", "set-url", "origin", self.url)
-            self._git("checkout", "-f")
-            self._git("fetch", "--prune", "origin")
-            self._git("checkout", "-B", "master", "origin/master")
+            await self._git("remote", "set-url", "origin", self.url)
+            await self._git("checkout", "-f")
+            await self._git("fetch", "--prune", "origin")
+            await self._git("checkout", "-B", "master", "origin/master")
 
-    def makepkg(self, force=False):
+    async def makepkg(self, force=False):
         if force:
-            self._exec("makepkg", "-f")
+            await self._exec("makepkg", "-f")
         else:
-            self._exec("makepkg")
+            await self._exec("makepkg")
 
 
 class Repo(object):

+ 1 - 0
requirements.txt

@@ -7,3 +7,4 @@ aiohttp==3.6.2
 cchardet==2.1.6
 aiodns==2.0.0
 brotlipy==0.7.0
+async-property==0.2.1