commit:     1952ecb9f2912968dd2f4487089fa50ed3d3bad1
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 25 23:55:33 2016 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Fri Jul  1 06:18:27 2016 +0000
URL:        https://gitweb.gentoo.org/proj/gentoolkit.git/commit/?id=1952ecb9

eclean: optimize binpkg-multi-instance support from bug 586658

Use the portage binarytree API to optimize binary package access,
so that metadata is read from $PKGDIR/Packages instead of from the
individual binary packages. Symlinks will now be ignored, since
portage hasn't used symlinks for years, and there's no harm
in ignoring them now. The APIs used are compatible with very old
portage, though they internally support binpkg-multi-instance
in recent versions of portage.

X-Gentoo-bug: 586658
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=586658

 pym/gentoolkit/eclean/search.py | 47 +++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py
index ce796f5..b9d111a 100644
--- a/pym/gentoolkit/eclean/search.py
+++ b/pym/gentoolkit/eclean/search.py
@@ -538,29 +538,20 @@ def findPackages(
                print( pp.error("(Check your make.conf file and 
environment)."), file=sys.stderr)
                print( pp.error("Error: %s" %str(er)), file=sys.stderr)
                exit(1)
-       for root, dirs, files in os.walk(pkgdir):
-               if root[-3:] == 'All':
+
+       # if portage supports FEATURES=binpkg-multi-instance, then
+       # cpv_all can return multiple instances per cpv, where
+       # instances are distinguishable by some extra attributes
+       # provided by portage's _pkg_str class
+       bin_dbapi = portage.binarytree(pkgdir=pkgdir, 
settings=var_dbapi.settings).dbapi
+       for cpv in bin_dbapi.cpv_all():
+               mtime = int(bin_dbapi.aux_get(cpv, ['_mtime_'])[0])
+               if time_limit and mtime >= time_limit:
+                       # time-limit exclusion
                        continue
-               for file in files:
-                       if file[-5:] == ".tbz2":
-                               category = os.path.basename(root)
-                               cpv = category+"/"+file[:-5]
-                       elif file[-5:] == ".xpak":
-                               category = 
os.path.basename(os.path.dirname(root))
-                               cpv = category+"/"+file.rpartition('-')[0]
-                       else:
-                               # ignore other files
-                               continue
-                       path = os.path.join(root, file)
-                       st = os.lstat(path)
-                       if time_limit and (st[stat.ST_MTIME] >= time_limit):
-                               # time-limit exclusion
-                               continue
-                       # dict is cpv->[files] (2 files in general, because of 
symlink)
-                       clean_me.setdefault(cpv,[]).append(path)
-                       #if os.path.islink(path):
-                       if stat.S_ISLNK(st[stat.ST_MODE]):
-                               clean_me[cpv].append(os.path.realpath(path))
+               # dict is cpv->[pkgs] (supports binpkg-multi-instance)
+               clean_me.setdefault(cpv, []).append(cpv)
+
        # keep only obsolete ones
        if destructive and package_names:
                cp_all = dict.fromkeys(var_dbapi.cp_all())
@@ -576,10 +567,10 @@ def findPackages(
                        del clean_me[cpv]
                        continue
                if destructive and var_dbapi.cpv_exists(cpv):
-                       buildtime = var_dbapi.aux_get(cpv, 
['BUILD_TIME'])[0].encode('utf-8').strip()
-                       clean_me[cpv] = [path for path in clean_me[cpv]
+                       buildtime = var_dbapi.aux_get(cpv, ['BUILD_TIME'])[0]
+                       clean_me[cpv] = [pkg for pkg in clean_me[cpv]
                                # only keep path if BUILD_TIME is identical 
with vartree
-                               if 
portage.xpak.tbz2(path).getfile('BUILD_TIME').strip() != buildtime]
+                               if bin_dbapi.aux_get(pkg, ['BUILD_TIME'])[0] != 
buildtime]
                        if not clean_me[cpv]:
                                # nothing we can clean for this package
                                del clean_me[cpv]
@@ -588,4 +579,10 @@ def findPackages(
                        # exlusion because of --package-names
                        del clean_me[cpv]
 
+       # the getname method correctly supports FEATURES=binpkg-multi-instance,
+       # allowing for multiple paths per cpv (the API used here is also 
compatible
+       # with older portage which does not support binpkg-multi-instance)
+       for cpv, pkgs in clean_me.items():
+               clean_me[cpv] = [bin_dbapi.bintree.getname(pkg) for pkg in pkgs]
+
        return clean_me

Reply via email to