[PATCH gentoolkit] eclean: Add --changed-iuse flag
Matt Turner <[email protected]> Sat, 2 Jan 2021 19:08:40 -0500
| Newsgroups | gmane.linux.gentoo.portage.devel |
|---|---|
| Message-ID | <[email protected]> |
Allows binpkgs to be deleted if they are not usable due to IUSE changes.
---
Just kind of spitballing. I'm not sure about what USE flags we should
ignore or whether it should be configurable, etc. On one hand, deleting
binpkgs that don't have a newly added PYTHON_TARGET option might make
sense if your binhost is configured to rebuild the package. On the
other, you probably don't want to throw out amd64 binpkgs because
abi_riscv_* was added.
pym/gentoolkit/eclean/cli.py | 8 ++++-
pym/gentoolkit/eclean/search.py | 62 +++++++++++++++++++++++++--------
2 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/pym/gentoolkit/eclean/cli.py b/pym/gentoolkit/eclean/cli.py
index e31fde9..910296b 100644
--- a/pym/gentoolkit/eclean/cli.py
+++ b/pym/gentoolkit/eclean/cli.py
@@ -146,6 +146,8 @@ def printUsage(_error=None, help=None):
green("packages"),"action:", file=out)
print( yellow(" --changed-deps")+
" - delete packages for which ebuild dependencies have changed", file=out)
+ print( yellow(" --changed-iuse")+
+ " - delete packages for which IUSE have changed", file=out)
print( yellow(" -i, --ignore-failure")+
" - ignore failure to locate PKGDIR", file=out)
print( file=out)
@@ -264,6 +266,8 @@ def parseArgs(options={}):
options['verbose'] = True
elif o in ("--changed-deps"):
options['changed-deps'] = True
+ elif o in ("--changed-iuse"):
+ options['changed-iuse'] = True
elif o in ("-i", "--ignore-failure"):
options['ignore-failure'] = True
else:
@@ -291,7 +295,8 @@ 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",
+ "changed-iuse"]
# set default options, except 'nocolor', which is set in main()
options['interactive'] = False
options['pretend'] = False
@@ -305,6 +310,7 @@ def parseArgs(options={}):
options['size-limit'] = 0
options['verbose'] = False
options['changed-deps'] = False
+ options['changed-iuse'] = False
options['ignore-failure'] = False
# if called by a well-named symlink, set the action accordingly:
action = None
diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py
index 8f6e52f..8344e15 100644
--- a/pym/gentoolkit/eclean/search.py
+++ b/pym/gentoolkit/eclean/search.py
@@ -498,6 +498,47 @@ def _deps_equal(deps_a, eapi_a, deps_b, eapi_b, uselist=None):
return deps_a == deps_b
+def _changed_deps(cpv, options, port_dbapi, bin_dbapi):
+ if not options['changed-deps']:
+ return False
+
+ dep_keys = ('RDEPEND', 'PDEPEND')
+ keys = ('EAPI', 'USE') + dep_keys
+ binpkg_metadata = dict(zip(keys, bin_dbapi.aux_get(cpv, keys)))
+ ebuild_metadata = dict(zip(keys, port_dbapi.aux_get(cpv, keys)))
+
+ return _deps_equal(' '.join(binpkg_metadata[key] for key in dep_keys),
+ binpkg_metadata['EAPI'], ' '.join(ebuild_metadata[key] for key in dep_keys),
+ ebuild_metadata['EAPI'],
+ frozenset(binpkg_metadata['USE'].split()))
+
+
+# IUSE flags to be ignored for purposes of invalidating binpkgs
+def ignore(iuse):
+ return iuse.startswith('abi_')
+
+
+# Prune the + characters from USE flags (e.g. '+cxx' -> 'cxx')
+def prune_plus(iuse):
+ if iuse.startswith('+'):
+ return iuse[1:]
+ return iuse
+
+
+def _changed_iuse(cpv, options, port_dbapi, bin_dbapi):
+ if not options['changed-iuse']:
+ return False
+
+ keys = ('IUSE',)
+ binpkg_metadata = [prune_plus(x) for x in bin_dbapi.aux_get(cpv, keys)[0].split(' ') if not ignore(x)]
+ ebuild_metadata = [prune_plus(x) for x in port_dbapi.aux_get(cpv, keys)[0].split(' ') if not ignore(x)]
+
+ if binpkg_metadata == ['']: binpkg_metadata = []
+ if ebuild_metadata == ['']: ebuild_metadata = []
+
+ return binpkg_metadata != ebuild_metadata
+
+
def findPackages(
options,
exclude=None,
@@ -570,21 +611,6 @@ def findPackages(
if mtime >= time_limit:
continue
- # Exclude if binpkg exists in the porttree and not --deep
- if not destructive and port_dbapi.cpv_exists(cpv):
- if not options['changed-deps']:
- continue
-
- dep_keys = ('RDEPEND', 'PDEPEND')
- keys = ('EAPI', 'USE') + dep_keys
- binpkg_metadata = dict(zip(keys, bin_dbapi.aux_get(cpv, keys)))
- ebuild_metadata = dict(zip(keys, port_dbapi.aux_get(cpv, keys)))
-
- if _deps_equal(' '.join(binpkg_metadata[key] for key in dep_keys), binpkg_metadata['EAPI'],
- ' '.join(ebuild_metadata[key] for key in dep_keys), ebuild_metadata['EAPI'],
- frozenset(binpkg_metadata['USE'].split())):
- continue
-
if destructive and var_dbapi.cpv_exists(cpv):
# Exclude if an instance of the package is installed due to
# the --package-names option.
@@ -596,6 +622,12 @@ def findPackages(
if buildtime == bin_dbapi.aux_get(cpv, ['BUILD_TIME'])[0]:
continue
+ # Exclude if binpkg exists in the porttree and not --deep
+ if not destructive and port_dbapi.cpv_exists(cpv):
+ if not _changed_deps(cpv, options, port_dbapi, bin_dbapi) and \
+ not _changed_iuse(cpv, options, port_dbapi, bin_dbapi):
+ continue
+
binpkg_path = bin_dbapi.bintree.getname(cpv)
dead_binpkgs.setdefault(cpv, []).append(binpkg_path)
--
2.26.2