On Thu, Feb 20, 2020 at 9:29 PM Matt Turner <matts...@gentoo.org> wrote: > > I found the original code to be nearly incomprehensible. Instead of > populating a dict of potential binpkgs to remove and then removing from > the to-be-removed list, just selectively add to-be-removed packages. > > Signed-off-by: Matt Turner <matts...@gentoo.org> > --- > I switched from tabs to spaces in the process. I can revert back if > desired. > > pym/gentoolkit/eclean/search.py | 189 ++++++++++++++++---------------- > 1 file changed, 94 insertions(+), 95 deletions(-) > > diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py > index 58bd97e..831ba39 100644 > --- a/pym/gentoolkit/eclean/search.py > +++ b/pym/gentoolkit/eclean/search.py > @@ -489,98 +489,97 @@ class DistfilesSearch(object): > > > def findPackages( > - options, > - exclude=None, > - destructive=False, > - time_limit=0, > - package_names=False, > - pkgdir=None, > - port_dbapi=portage.db[portage.root]["porttree"].dbapi, > - var_dbapi=portage.db[portage.root]["vartree"].dbapi > - ): > - """Find all obsolete binary packages. > - > - XXX: packages are found only by symlinks. > - Maybe i should also return .tbz2 files from All/ that have > - no corresponding symlinks. > - > - @param options: dict of options determined at runtime > - @param exclude: an exclusion dict as defined in > - exclude.parseExcludeFile class. > - @param destructive: boolean, defaults to False > - @param time_limit: integer time value as returned by parseTime() > - @param package_names: boolean, defaults to False. > - used only if destructive=True > - @param pkgdir: path to the binary package dir being checked > - @param port_dbapi: defaults to > portage.db[portage.root]["porttree"].dbapi > - can be overridden for tests. > - @param var_dbapi: defaults to > portage.db[portage.root]["vartree"].dbapi > - can be overridden for tests. > - > - @rtype: dict > - @return clean_me i.e. {'cat/pkg-ver.tbz2': [filepath],} > - """ > - if exclude is None: > - exclude = {} > - clean_me = {} > - # create a full package dictionary > - > - # now do an access test, os.walk does not error for "no read > permission" > - try: > - test = os.listdir(pkgdir) > - del test > - except EnvironmentError as er: > - if options['ignore-failure']: > - exit(0) > - print( pp.error("Error accessing PKGDIR." ), file=sys.stderr) > - 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) > - > - # 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 > - # 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()) > - else: > - cp_all = {} > - for cpv in list(clean_me): > - if exclDictMatchCP(exclude,portage.cpv_getkey(cpv)): > - # exclusion because of the exclude file > - del clean_me[cpv] > - continue > - if not destructive and port_dbapi.cpv_exists(cpv): > - # exclusion because pkg still exists (in porttree) > - del clean_me[cpv] > - continue > - if destructive and var_dbapi.cpv_exists(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 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] > - continue > - if portage.cpv_getkey(cpv) in cp_all and > port_dbapi.cpv_exists(cpv): > - # exclusion 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 > + options, > + exclude=None, > + destructive=False, > + time_limit=0, > + package_names=False, > + pkgdir=None, > + port_dbapi=portage.db[portage.root]["porttree"].dbapi, > + var_dbapi=portage.db[portage.root]["vartree"].dbapi > + ): > + """Find obsolete binary packages. > + > + @param options: dict of options determined at runtime > + @type options: dict > + @param exclude: exclusion dict (as defined in the > exclude.parseExcludeFile class) > + @type exclude: dict, optional > + @param destructive: binpkg is obsolete if not installed (default: > `False`) > + @type destructive: bool, optional > + @param time_limit: binpkg is obsolete if older than time value as > returned by parseTime() > + @type time_limit: int, optional > + @param package_names: exclude all binpkg versions if package is installed > + (used with `destructive=True`) (default: `False`) > + @type package_names: bool, optional > + @param pkgdir: path to the binpkg cache (PKGDIR) > + @type pkgdir: str > + @param port_dbapi: defaults to portage.db[portage.root]["porttree"].dbapi > + Can be overridden for tests. > + @param var_dbapi: defaults to portage.db[portage.root]["vartree"].dbapi > + Can be overridden for tests. > + > + @return binary packages to remove. e.g. {'cat/pkg-ver': [filepath]} > + @rtype: dict > + """ > + if exclude is None: > + exclude = {} > + > + # Access test, os.walk does not error for "no read permission" > + try: > + test = os.listdir(pkgdir) > + del test > + except EnvironmentError as er: > + if options['ignore-failure']: > + exit(0) > + print(pp.error("Error accessing PKGDIR."), file=sys.stderr) > + 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) > + > + # Create a dictionary of all installed packages > + if destructive and package_names: > + installed = dict.fromkeys(var_dbapi.cp_all()) > + else: > + installed = {} > + > + # Dictionary of binary packages to clean. Organized as cpv->[pkgs] in > order > + # to support FEATURES=binpkg-multi-instance. > + dead_binpkgs = {} > + > + # Create a dictionary of all binary packages whose mtime is older than > + # time_limit, if set. These packages will be considered for removal.
Naturally immediately after I press send I recognize that this comment should be removed. Fixed locally. > + bin_dbapi = portage.binarytree(pkgdir=pkgdir, > settings=var_dbapi.settings).dbapi > + for cpv in bin_dbapi.cpv_all(): > + cp = portage.cpv_getkey(cpv) > + > + # Exclude per --exclude-file=... > + if exclDictMatchCP(exclude, cp): > + continue > + > + # Exclude if binpkg is obsolete per --time-limit=... > + if time_limit: > + mtime = int(bin_dbapi.aux_get(cpv, ['_mtime_'])) > + if mtime >= time_limit: > + continue > + > + # Exclude if binpkg exists in the porttree and not --deep > + if not destructive and port_dbapi.cpv_exists(cpv): > + continue > + > + if destructive and var_dbapi.cpv_exists(cpv): > + # Exclude if an instance of the package is installed due to > + # the --package-names option. > + if cp in installed and port_dbapi.cpv_exists(cpv): > + continue > + > + # Exclude if BUILD_TIME of binpkg is same as vartree > + buildtime = var_dbapi.aux_get(cpv, ['BUILD_TIME'])[0] > + if buildtime == bin_dbapi.aux_get(cpv, ['BUILD_TIME'])[0]: > + continue > + > + binpkg_path = bin_dbapi.bintree.getname(cpv) > + dead_binpkgs.setdefault(cpv, []).append(binpkg_path) > + > + return dead_binpkgs > + > +# vim: set ts=4 sw=4 tw=79: > -- > 2.24.1 >