commit:     2fffbd450df2443bbd671f7ec760051ce3c930e9
Author:     Yixun Lan <dlan <AT> gentoo <DOT> org>
AuthorDate: Wed May 25 08:08:09 2022 +0000
Commit:     Yixun Lan <dlan <AT> gentoo <DOT> org>
CommitDate: Sat May 28 15:24:32 2022 +0000
URL:        https://gitweb.gentoo.org/proj/gentoolkit.git/commit/?id=2fffbd45

implement --unique-use option for eclean-pkg

this will help to clean duplicated binpkg which has exact same USEs flags 
enabled,
and it will choose the more recent version according to BUILD_TIME by default

Closes: https://bugs.gentoo.org/727576
Closes: https://github.com/gentoo/gentoolkit/pull/20
Signed-off-by: Yixun Lan <dlan <AT> gentoo.org>

 pym/gentoolkit/eclean/cli.py    | 14 +++++++++++++-
 pym/gentoolkit/eclean/search.py | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/pym/gentoolkit/eclean/cli.py b/pym/gentoolkit/eclean/cli.py
index 2ad2ae9..c129d5e 100644
--- a/pym/gentoolkit/eclean/cli.py
+++ b/pym/gentoolkit/eclean/cli.py
@@ -252,6 +252,11 @@ def printUsage(_error=None, help=None):
             + "             - ignore failure to locate PKGDIR",
             file=out,
         )
+        print(
+            yellow(" -u, --unique-use")
+            + "                 - keep unique packages which have no 
duplicated USE",
+            file=out,
+        )
         print(file=out)
     if _error in ("distfiles-options", "merged-distfiles-options") or help in (
         "all",
@@ -392,6 +397,8 @@ def parseArgs(options={}):
                 options["changed-deps"] = True
             elif o in ("-i", "--ignore-failure"):
                 options["ignore-failure"] = True
+            elif o in ("--unique-use"):
+                options["unique-use"] = True
             else:
                 return_code = False
         # sanity check of --deep only options:
@@ -431,7 +438,11 @@ def parseArgs(options={}):
     getopt_options["short"]["distfiles"] = "fs:"
     getopt_options["long"]["distfiles"] = ["fetch-restricted", "size-limit="]
     getopt_options["short"]["packages"] = "i"
-    getopt_options["long"]["packages"] = ["ignore-failure", "changed-deps"]
+    getopt_options["long"]["packages"] = [
+        "ignore-failure",
+        "changed-deps",
+        "unique-use",
+    ]
     # set default options, except 'nocolor', which is set in main()
     options["interactive"] = False
     options["pretend"] = False
@@ -446,6 +457,7 @@ def parseArgs(options={}):
     options["verbose"] = False
     options["changed-deps"] = False
     options["ignore-failure"] = False
+    options["unique-use"] = False
     # if called by a well-named symlink, set the action accordingly:
     action = None
     # temp print line to ensure it is the svn/branch code running, etc..

diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py
index cb695c0..365970c 100644
--- a/pym/gentoolkit/eclean/search.py
+++ b/pym/gentoolkit/eclean/search.py
@@ -560,6 +560,7 @@ def findPackages(
     # Dictionary of binary packages to clean. Organized as cpv->[pkgs] in order
     # to support FEATURES=binpkg-multi-instance.
     dead_binpkgs = {}
+    keep_binpkgs = {}
 
     bin_dbapi = portage.binarytree(pkgdir=pkgdir, 
settings=var_dbapi.settings).dbapi
     for cpv in bin_dbapi.cpv_all():
@@ -575,6 +576,28 @@ def findPackages(
             if mtime >= time_limit:
                 continue
 
+        # Exclude if binpkg has exact same USEs
+        if not destructive and options["unique-use"]:
+            keys = ("CPV", "EAPI", "USE")
+            binpkg_metadata = dict(zip(keys, bin_dbapi.aux_get(cpv, keys)))
+            cpv_key = "_".join(binpkg_metadata[key] for key in keys)
+            if cpv_key in keep_binpkgs:
+                old_cpv = keep_binpkgs[cpv_key]
+                # compare BUILD_TIME, keep the new one
+                old_time = int(bin_dbapi.aux_get(old_cpv, ["BUILD_TIME"])[0])
+                new_time = int(bin_dbapi.aux_get(cpv, ["BUILD_TIME"])[0])
+                drop_cpv = old_cpv if new_time >= old_time else cpv
+
+                binpkg_path = bin_dbapi.bintree.getname(drop_cpv)
+                dead_binpkgs.setdefault(drop_cpv, []).append(binpkg_path)
+
+                if new_time >= old_time:
+                    keep_binpkgs[cpv_key] = cpv
+                else:
+                    continue
+            else:
+                keep_binpkgs[cpv_key] = cpv
+
         # Exclude if binpkg exists in the porttree and not --deep
         if not destructive and port_dbapi.cpv_exists(cpv):
             if not options["changed-deps"]:
@@ -605,6 +628,9 @@ def findPackages(
             if buildtime == bin_dbapi.aux_get(cpv, ["BUILD_TIME"])[0]:
                 continue
 
+        if not destructive and options["unique-use"]:
+            del keep_binpkgs[cpv_key]
+
         binpkg_path = bin_dbapi.bintree.getname(cpv)
         dead_binpkgs.setdefault(cpv, []).append(binpkg_path)
 

Reply via email to