repo.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import os
  2. import asyncio
  3. from .pkgbuild import PKGBUILD
  4. from asyncio import subprocess
  5. from async_property import async_cached_property
  6. class PackageException(Exception):
  7. pass
  8. class Package(object):
  9. def __init__(self, repo, config):
  10. self.repo = repo
  11. self.config = config
  12. async def _exec(self, *args, check=True):
  13. p = await asyncio.create_subprocess_exec(*args,
  14. cwd=self.path,
  15. stdout=subprocess.PIPE,
  16. stderr=subprocess.STDOUT)
  17. stdout, stderr = await p.communicate()
  18. if check and p.returncode:
  19. raise PackageException(stdout.decode("utf-8"))
  20. return p.returncode, stdout
  21. async def _execAll(self, *tasks, check=True):
  22. output = ""
  23. for args in tasks:
  24. code, stdout = await self._exec(*args, check=False)
  25. output += stdout.decode('utf-8')
  26. if code:
  27. if check:
  28. print(output)
  29. break
  30. return code, output
  31. async def _git(self, *args, check=True):
  32. return await self._exec('git', *args, check=check)
  33. async def _gitAll(self, *tasks, check=True):
  34. for args in tasks:
  35. args.insert(0, 'git')
  36. return await self._execAll(*tasks, check=check)
  37. async def _clone(self):
  38. if not os.path.exists(self.path):
  39. os.makedirs(self.path)
  40. return await self._gitAll(
  41. ["init"],
  42. ["remote", "add", "origin", self.url],
  43. ["fetch", "origin"],
  44. ["checkout", "master"])
  45. @property
  46. def name(self):
  47. return self.config["name"]
  48. @property
  49. def url(self):
  50. return self.config.get("url") or "https://aur.archlinux.org/{}.git".format(
  51. self.name)
  52. @property
  53. def path(self):
  54. return os.path.join(self.repo.config.config['cachedir'], self.name)
  55. @async_cached_property
  56. async def PKGBUILD(self):
  57. if not os.path.exists(self.path):
  58. await self._clone()
  59. if not os.path.exists(os.path.join(self.path, "PKGBUILD")):
  60. await self.update()
  61. if not hasattr(self, '_PKGBUILD'):
  62. self._PKGBUILD = PKGBUILD(os.path.join(self.path, 'PKGBUILD'))
  63. return self._PKGBUILD
  64. async def update(self):
  65. if not os.path.exists(os.path.join(self.path, '.git')):
  66. return await self._clone(check=False)
  67. else:
  68. return await self._gitAll(
  69. ["remote", "set-url", "origin", self.url],
  70. ["checkout", "-f"],
  71. ["fetch", "--prune", "origin"],
  72. ["checkout", "-B", "master", "origin/master"],
  73. check=False)
  74. async def makepkg(self, force=False):
  75. if force:
  76. return await self._exec("makepkg", "-f", check=False)
  77. else:
  78. return await self._exec("makepkg", check=False)
  79. class Repo(object):
  80. def __init__(self, config):
  81. self.config = config
  82. self.packages = []
  83. for package in self.config["packages"]:
  84. if isinstance(package, str):
  85. self.packages.append(Package(self, dict(name=package)))
  86. else:
  87. self.packages.append(Package(self, package))
  88. @property
  89. def name(self):
  90. return self.config.name
  91. @property
  92. def id(self):
  93. return self.config.id