aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Holubakha <hilobakho@gmail.com>2017-06-13 04:53:20 +0300
committerMykyta Holubakha <hilobakho@gmail.com>2017-06-13 04:53:20 +0300
commitf2f58bcef9f8ee5594f0dfaba55c6a62f25daaa5 (patch)
tree855fdac7a0a3150296e766ebf27d4a176dae40e1
parentRepository logic and import fixes (diff)
downloadpomu-f2f58bcef9f8ee5594f0dfaba55c6a62f25daaa5.tar.gz
pomu-f2f58bcef9f8ee5594f0dfaba55c6a62f25daaa5.tar.bz2
pomu-f2f58bcef9f8ee5594f0dfaba55c6a62f25daaa5.zip
Portage package source module
implemented package description parsing, repository lookup started work on finding best package versions
-rw-r--r--pomu/source/portage.py114
-rw-r--r--pomu/util/result.py4
-rw-r--r--pomu/util/str.py2
3 files changed, 118 insertions, 2 deletions
diff --git a/pomu/source/portage.py b/pomu/source/portage.py
new file mode 100644
index 0000000..ded09c9
--- /dev/null
+++ b/pomu/source/portage.py
@@ -0,0 +1,114 @@
+"""
+A package source module to import packages from configured portage repositories
+"""
+import os
+import re
+
+from os import path
+
+from pomu.repo.repo import portage_repos
+from pomu.source import dispatcher
+from pomu.util import Result
+from pomu.util.str import pivot
+
+class PortagePackage():
+ """A class to represent a portage package"""
+ def __init__(self, repo, category, name, version, slot='0'):
+ self.repo = repo
+ self.category = category
+ self.name = name
+ self.version = version
+ self.slot = slot
+
+suffixes = ['alpha', 'beta', 'pre', 'rc', 'p']
+misc_dirs = ['profiles', 'licenses', 'eclass', 'metadata', 'distfiles', 'packages', 'scripts'. '.git']
+
+@dispatcher.source
+class PortageSource():
+ @dispatcher.handler()
+ def parse_full(uri):
+ # portage/gentoo:dev-libs/openssl-0.9.8z_p8-r100:0.9.8::gentoo
+ if not uri.startswith('portage')
+ return Result.Err()
+ uri = uri[len('portage'):]
+ # gentoo:dev-libs/openssl-0.9.8z_p8-r100:0.9.8::gentoo
+ if uri.startswith('/'): # repo may be omitted
+ repo, _, uri_ = uri[1:].partition(':')
+ if uri_ == uri[1:]:
+ return Result.Err()
+ uri = uri_
+ elif uri.startswith(':'):
+ repo = None
+ uri = uri[1:]
+ # dev-libs/openssl-0.9.8z_p8-r100:0.9.8::gentoo
+ pkg, _, repo_ = uri.partition('::') # portage repo may be specified on the rhs as well
+ if repo_:
+ repo = repo
+ # dev-libs/openssl-0.9.8z_p8-r100:0.9.8
+ pkg, _, slot = uri.partition(':') # slot may be omitted
+ if not slot:
+ slot = None
+ # dev-libs/openssl-0.9.8z_p8-r100
+ category, _, pkg = pkg.rpartition('/') # category may be omitted
+ # openssl-0.9.8z_p8-r100
+ m = re.search(r'-r\d+$', pkg) # revision is optional
+ if m:
+ pkg, rev = pivot(pkg, m.start(0))
+ else:
+ rev = None
+ # openssl-0.9.8z_p8
+ m = re.search(r'_({})(\d*)$'.format('|'.join(suffixes)))
+ if m:
+ pkg, suff = pivot(pkg, m.start(0))
+ else:
+ suff = None
+ # openssl-0.9.8z
+ m = re.search(r'-(\d+(\.\d+)*)([a-z])?$')
+ if m:
+ pkg, vernum = pivot(pkg, m.start(0))
+ else:
+ vernum = None
+ # openssl
+ name = pkg
+
+ def sanity_check(repo, category, name, vernum, suff, rev, slot):
+ if not name:
+ return False
+ if repo and repo not in list(portage_repos()):
+ return False
+ if (rev or suff) and not vernum:
+ return False
+ if vernum:
+ ver = vernum + (suff if suff else '') + (rev if rev else '')
+ else:
+ ver = None
+ if not repo_pkgs(repo, category, name, ver, slot):
+ return False
+
+ # TODO: vvv
+ def pkg_slot(repo, category, name, ver):
+
+ def best_ver(repo, category, name, ver, slot):
+ """Gets the best (newest) version of a package matching slot in the repo"""
+ ebuilds = [x[:-6] for x in
+ os.listdir(path.join(portage_repo_path(repo)), category, name)
+ if x.endswith('.ebuild')]
+
+ def repo_pkgs(repo, category, name, ver, slot):
+ """List of package occurences in the repo"""
+ if not repo:
+ res = []
+ for r in portage_repos():
+ res.extend(has_pkg(r, category, name))
+ return res
+ if category:
+ if path.exists(path.join(portage_repo_path(repo), category, name)):
+ return [(repo, category, name)]
+ return []
+ rpath = portage_repo_path(repo)
+ dirs = set(os.listdir(rpath)) - set(misc_dirs)
+ res = []
+ for d in dirs:
+ if path.isdir(path.join(rpath, d, name)):
+ res.append(repo, d, name)
+ return res
diff --git a/pomu/util/result.py b/pomu/util/result.py
index 1d5092f..a5dae3b 100644
--- a/pomu/util/result.py
+++ b/pomu/util/result.py
@@ -10,13 +10,13 @@ class Result():
self._is_val = is_val
@classmethod
- def Ok(cls, val):
+ def Ok(cls, val=None):
res = cls(True)
res._val = val
return res
@classmethod
- def Err(cls, val):
+ def Err(cls, val=None):
res = cls(False)
res._val = val
return res
diff --git a/pomu/util/str.py b/pomu/util/str.py
new file mode 100644
index 0000000..4fcd4ac
--- /dev/null
+++ b/pomu/util/str.py
@@ -0,0 +1,2 @@
+def pivot(string, idx):
+ return (string[:idx], string[idx:])