1818from portage .dep ._slot_operator import strip_slots
1919from portage .dep .libc import find_libc_deps , strip_libc_deps
2020from portage .exception import InvalidDependString
21+ from portage .binrepo .config import BinRepoConfigLoader
2122
2223import gentoolkit .pprinter as pp
2324from gentoolkit .eclean .exclude import (
@@ -659,9 +660,9 @@ def findPackages(
659660 else :
660661 installed = {}
661662
662- # Dictionary of binary packages to clean. Organized as cpv->[pkgs] in order
663- # to support FEATURES=binpkg-multi-instance.
664- dead_binpkgs : dict [str , tuple [str , str | None ]] = {}
663+ # Dictionary of binary packages to clean. Organized as
664+ # { location -> { cpv~build-id -> (binpkg, debugpack) } }
665+ dead_binpkgs : dict [str , dict [ str , tuple [str , str | None ] ]] = {}
665666 keep_binpkgs = {}
666667
667668 def mk_binpkg_key (cpv ):
@@ -672,91 +673,114 @@ def mk_binpkg_key(cpv):
672673 # FEATURES=pkgdir-index-trusted is now on by default which makes Portage's
673674 # invalids inaccessible
674675 settings = var_dbapi .settings
675- bin_dbapi = portage .binarytree (pkgdir = pkgdir , settings = settings ).dbapi
676- populate_kwargs = {}
677- if "invalid_errors" in signature (bin_dbapi .bintree .populate ).parameters :
678- populate_kwargs ["invalid_errors" ] = False
679- if "force_reindex" in signature (bin_dbapi .bintree .populate ).parameters :
680- bin_dbapi .bintree .populate (force_reindex = True , ** populate_kwargs )
681- for cpv in bin_dbapi .cpv_all ():
682- cp = portage .cpv_getkey (cpv )
683- binpkg_key = mk_binpkg_key (cpv )
684-
685- # Exclude per --exclude-file=...
686- if exclDictMatchCP (exclude , cp ):
687- continue
688-
689- # Exclude if binpkg is newer than --time-limit=...
690- if time_limit :
691- mtime = int (bin_dbapi .aux_get (cpv , ["_mtime_" ])[0 ])
692- if mtime >= time_limit :
676+
677+ # Load binrepos.conf if possible, get all cache locations
678+ binrepos_conf_path = os .path .join (
679+ settings ['PORTAGE_CONFIGROOT' ], portage .const .BINREPOS_CONF_FILE
680+ )
681+ binrepos_conf = BinRepoConfigLoader ((binrepos_conf_path ,), settings )
682+ locations = {pkgdir }
683+ if binrepos_conf :
684+ # check for additional cache locations
685+ for v in binrepos_conf .values ():
686+ if v .location :
687+ locations .add (v .location )
688+
689+ invalid_paths = {}
690+ for location in locations :
691+ # Initialize bintree with location
692+ bin_dbapi = portage .binarytree (pkgdir = location , settings = settings ).dbapi
693+ populate_kwargs = {}
694+ if "invalid_errors" in signature (bin_dbapi .bintree .populate ).parameters :
695+ populate_kwargs ["invalid_errors" ] = False
696+ if "force_reindex" in signature (bin_dbapi .bintree .populate ).parameters :
697+ bin_dbapi .bintree .populate (force_reindex = True , ** populate_kwargs )
698+ for cpv in bin_dbapi .cpv_all ():
699+ cp = portage .cpv_getkey (cpv )
700+ binpkg_key = mk_binpkg_key (cpv )
701+
702+ # Exclude per --exclude-file=...
703+ if exclDictMatchCP (exclude , cp ):
693704 continue
694705
695- # Exclude if binpkg has exact same USEs
696- if not destructive and options ["unique-use" ]:
697- keys = ("CPV" , "EAPI" , "USE" )
698- binpkg_metadata = dict (zip (keys , bin_dbapi .aux_get (cpv , keys )))
699- cpv_key = "_" .join (binpkg_metadata [key ] for key in keys )
700- if cpv_key in keep_binpkgs :
701- old_cpv = keep_binpkgs [cpv_key ]
702- # compare BUILD_TIME, keep the new one
703- old_time = int (bin_dbapi .aux_get (old_cpv , ["BUILD_TIME" ])[0 ])
704- new_time = int (bin_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ])
705- drop_cpv = old_cpv if new_time >= old_time else cpv
706-
707- binpkg_key = mk_binpkg_key (drop_cpv )
708- binpkg_path = bin_dbapi .bintree .getname (drop_cpv )
709- debuginfo_path = _find_debuginfo_tarball (drop_cpv , cp )
710- dead_binpkgs [binpkg_key ] = (binpkg_path , debuginfo_path )
711-
712- if new_time < old_time :
706+ # Exclude if binpkg is newer than --time-limit=...
707+ if time_limit :
708+ mtime = int (bin_dbapi .aux_get (cpv , ["_mtime_" ])[0 ])
709+ if mtime >= time_limit :
713710 continue
714- keep_binpkgs [cpv_key ] = cpv
715711
716- # Exclude if binpkg exists in the porttree and not --deep
717- if not destructive and port_dbapi .cpv_exists (cpv ):
718- if not options ["changed-deps" ]:
719- continue
712+ # Exclude if binpkg has exact same USEs
713+ if not destructive and options ["unique-use" ]:
714+ keys = ("EAPI" , "USE" )
715+ binpkg_metadata = dict (zip (keys , bin_dbapi .aux_get (cpv , keys )))
716+ cpv_key = f"{ cpv } _{ '_' .join (binpkg_metadata [key ] for key in keys )} "
717+ if cpv_key in keep_binpkgs :
718+ old_cpv = keep_binpkgs [cpv_key ]
719+ # compare BUILD_TIME, keep the new one
720+ old_time = int (bin_dbapi .aux_get (old_cpv , ["BUILD_TIME" ])[0 ])
721+ new_time = int (bin_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ])
722+ drop_cpv = old_cpv if new_time >= old_time else cpv
723+
724+ binpkg_key = mk_binpkg_key (drop_cpv )
725+ binpkg_path = bin_dbapi .bintree .getname (drop_cpv )
726+ debuginfo_path = _find_debuginfo_tarball (drop_cpv , cp )
727+ dead_binpkgs .setdefault (location , {})[binpkg_key ] = (binpkg_path , debuginfo_path )
728+
729+ if new_time < old_time :
730+ continue
731+ keep_binpkgs [cpv_key ] = cpv
732+
733+ # Exclude if binpkg exists in the porttree and not --deep
734+ if not destructive and port_dbapi .cpv_exists (cpv ):
735+ if not options ["changed-deps" ]:
736+ continue
720737
721- dep_keys = ("RDEPEND" , "PDEPEND" )
722- keys = ("EAPI" , "USE" ) + dep_keys
723- binpkg_metadata = dict (zip (keys , bin_dbapi .aux_get (cpv , keys )))
724- ebuild_metadata = dict (zip (keys , port_dbapi .aux_get (cpv , keys )))
725-
726- deps_binpkg = " " .join (binpkg_metadata [key ] for key in dep_keys )
727- deps_ebuild = " " .join (ebuild_metadata [key ] for key in dep_keys )
728- if _deps_equal (
729- deps_binpkg ,
730- binpkg_metadata ["EAPI" ],
731- deps_ebuild ,
732- ebuild_metadata ["EAPI" ],
733- libc_deps ,
734- frozenset (binpkg_metadata ["USE" ].split ()),
735- cpv ,
736- ):
737- continue
738+ dep_keys = ("RDEPEND" , "PDEPEND" )
739+ keys = ("EAPI" , "USE" ) + dep_keys
740+ binpkg_metadata = dict (zip (keys , bin_dbapi .aux_get (cpv , keys )))
741+ ebuild_metadata = dict (zip (keys , port_dbapi .aux_get (cpv , keys )))
742+
743+ deps_binpkg = " " .join (binpkg_metadata [key ] for key in dep_keys )
744+ deps_ebuild = " " .join (ebuild_metadata [key ] for key in dep_keys )
745+ if _deps_equal (
746+ deps_binpkg ,
747+ binpkg_metadata ["EAPI" ],
748+ deps_ebuild ,
749+ ebuild_metadata ["EAPI" ],
750+ libc_deps ,
751+ frozenset (binpkg_metadata ["USE" ].split ()),
752+ cpv ,
753+ ):
754+ continue
738755
739- if destructive and var_dbapi .cpv_exists (cpv ):
740- # Exclude if an instance of the package is installed due to
741- # the --package-names option.
742- if cp in installed and port_dbapi .cpv_exists (cpv ):
743- continue
756+ if destructive and var_dbapi .cpv_exists (cpv ):
757+ # Exclude if an instance of the package is installed due to
758+ # the --package-names option.
759+ if cp in installed and port_dbapi .cpv_exists (cpv ):
760+ continue
744761
745- # Exclude if BUILD_TIME of binpkg is same as vartree
746- buildtime = var_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ]
747- if buildtime == bin_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ]:
748- continue
762+ # Exclude if BUILD_TIME of binpkg is same as vartree
763+ buildtime = var_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ]
764+ if buildtime == bin_dbapi .aux_get (cpv , ["BUILD_TIME" ])[0 ]:
765+ continue
749766
750- if not destructive and options ["unique-use" ]:
751- del keep_binpkgs [cpv_key ]
767+ if not destructive and options ["unique-use" ]:
768+ del keep_binpkgs [cpv_key ]
752769
753- binpkg_path = bin_dbapi .bintree .getname (cpv )
754- debuginfo_path = _find_debuginfo_tarball (cpv , cp )
755- dead_binpkgs [binpkg_key ] = (binpkg_path , debuginfo_path )
756- try :
757- invalid_paths = bin_dbapi .bintree .invalid_paths
758- except AttributeError :
759- invalid_paths = bin_dbapi .bintree .invalids
770+ binpkg_path = bin_dbapi .bintree .getname (cpv )
771+ debuginfo_path = _find_debuginfo_tarball (cpv , cp )
772+ dead_binpkgs .setdefault (location , {})[binpkg_key ] = (binpkg_path , debuginfo_path )
773+
774+ try :
775+ for f , paths in bin_dbapi .bintree .invalid_paths .items ():
776+ if f in invalid_paths :
777+ invalid_paths [f ].extend (paths )
778+ else :
779+ invalid_paths [f ] = paths
780+ except AttributeError :
781+ # if bintree.invalid_paths was not initialized, this is a
782+ # hard error and we can just return here
783+ return {}, bin_dbapi .bintree .invalids
760784
761785 return dead_binpkgs , invalid_paths
762786
0 commit comments