def _xmatch(self, level, atom): """ This method does not expand old-style virtuals because it is restricted to returning matches for a single ${CATEGORY}/${PN} and old-style virual matches unreliable for that when querying multiple package databases. If necessary, old-style virtuals can be performed on atoms prior to calling this method. """ cp = portage.dep_getkey(atom) if level == "match-all": matches = set() for db in self._dbs: if hasattr(db, "xmatch"): matches.update(db.xmatch(level, atom)) else: matches.update(db.match(atom)) result = list(x for x in matches if portage.cpv_getkey(x) == cp) db._cpv_sort_ascending(result) elif level == "match-visible": matches = set() for db in self._dbs: if hasattr(db, "xmatch"): matches.update(db.xmatch(level, atom)) else: db_keys = list(db._aux_cache_keys) for cpv in db.match(atom): metadata = zip(db_keys, db.aux_get(cpv, db_keys)) if not self._visible(db, cpv, metadata): continue matches.add(cpv) result = list(x for x in matches if portage.cpv_getkey(x) == cp) db._cpv_sort_ascending(result) elif level == "bestmatch-visible": result = None for db in self._dbs: if hasattr(db, "xmatch"): cpv = db.xmatch("bestmatch-visible", atom) if not cpv or portage.cpv_getkey(cpv) != cp: continue if not result or cpv == portage.best([cpv, result]): result = cpv else: db_keys = Package.metadata_keys # break out of this loop with highest visible # match, checked in descending order for cpv in reversed(db.match(atom)): if portage.cpv_getkey(cpv) != cp: continue metadata = zip(db_keys, db.aux_get(cpv, db_keys)) if not self._visible(db, cpv, metadata): continue if not result or cpv == portage.best([cpv, result]): result = cpv break else: raise NotImplementedError(level) return result
def find_best(self, include_keyworded=True, include_masked=True): """Returns the "best" version available. Order of preference: highest available stable => highest available keyworded => highest available masked @rtype: Package object or None @return: best of up to three options @raise errors.GentoolkitInvalidAtom: if query is not valid input """ best = keyworded = masked = None try: best = portage.db[portage.root]["porttree"].dbapi.xmatch( "bestmatch-visible", self.query) except portage.exception.InvalidAtom as err: message = ("query.py: find_best(), bestmatch-visible, " + "query=%s, InvalidAtom=%s" % (self.query, str(err))) raise errors.GentoolkitInvalidAtom(message) # xmatch can return an empty string, so checking for None is not enough if not best: if not (include_keyworded or include_masked): return None try: matches = portage.db[portage.root]["porttree"].dbapi.xmatch( "match-all", self.query) except portage.exception.InvalidAtom as err: message = ( "query.py: find_best(), match-all, query=%s, InvalidAtom=%s" % (self.query, str(err))) raise errors.GentoolkitInvalidAtom(message) masked = portage.best(matches) keywordable = [] for m in matches: status = portage.getmaskingstatus(m) if "package.mask" not in status or "profile" not in status: keywordable.append(m) if matches: keyworded = portage.best(keywordable) else: return Package(best) if include_keyworded and keyworded: return Package(keyworded) if include_masked and masked: return Package(masked) return None
def _check_updates(self): mybestpv = self.emerge_config.target_config.trees[ 'porttree'].dbapi.xmatch("bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM) mypvs = portage.best( self.emerge_config.target_config.trees['vartree'].dbapi.match( portage.const.PORTAGE_PACKAGE_ATOM)) chk_updated_cfg_files( self.emerge_config.target_config.root, portage.util.shlex_split( self.emerge_config.target_config.settings.get( "CONFIG_PROTECT", ""))) msgs = [] if mybestpv != mypvs and "--quiet" not in self.emerge_config.opts: msgs.append('') msgs.append( warn(" * ") + bold("An update to portage is available.") + " It is _highly_ recommended") msgs.append( warn(" * ") + "that you update portage now, before any other packages are updated." ) msgs.append('') msgs.append( warn(" * ") + "To update portage, run 'emerge --oneshot sys-apps/portage' now." ) msgs.append('') return msgs
def _scan(self): """ Internal scan method, executes the actual scan and retuns a raw list of AntiMatterPackage objects. """ vardb, portdb = self._get_dbs() result = [] vardb.lock() try: cpv_all = vardb.cpv_all() cpv_all.sort() for count, package in enumerate(cpv_all): count_str = "[%s of %s]" % ( count, len(cpv_all), ) try: slot, repo = vardb.aux_get(package, ["SLOT", "repository"]) except KeyError: # package vanished, can still # happen even if locked? continue atom = portage.dep.Atom("=%s:%s::%s" % (package, slot, repo), allow_wildcard=True, allow_repo=True) if self._nsargs.verbose: print_warning("%s :: %s" % (count_str, atom), back=True) key_slot = "%s:%s" % (atom.cp, atom.slot) best_visible = portage.best(portdb.match(key_slot)) if not best_visible: # dropped upstream pkg = AntiMatterPackage(vardb, portdb, atom, None, -1) result.append(pkg) if self._nsargs.verbose: print_error(" %s no longer upstream or masked" % (key_slot, )) continue cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_visible), portage.versions.pkgsplit(package)) pkg = AntiMatterPackage(vardb, portdb, atom, best_visible, cmp_res) result.append(pkg) finally: vardb.unlock() if cpv_all and self._nsargs.verbose: print_generic("") return result
def initialize(): q = sys.argv[1] if len(sys.argv) > 1 else '@world' if q == '@world': return World() else: atom = Atom(q) mylist = Portage.porttree().match(atom) return PackageVersion.get(portage.best(mylist))
def find_best(self, include_keyworded=True, include_masked=True): """Returns the "best" version available. Order of preference: highest available stable => highest available keyworded => highest available masked @rtype: Package object or None @return: best of up to three options @raise errors.GentoolkitInvalidAtom: if query is not valid input """ best = keyworded = masked = None try: best = portage.db[portage.root]["porttree"].dbapi.xmatch("bestmatch-visible", self.query) except portage.exception.InvalidAtom as err: message = "query.py: find_best(), bestmatch-visible, " + \ "query=%s, InvalidAtom=%s" %(self.query, str(err)) raise errors.GentoolkitInvalidAtom(message) # xmatch can return an empty string, so checking for None is not enough if not best: if not (include_keyworded or include_masked): return None try: matches = portage.db[portage.root]["porttree"].dbapi.xmatch("match-all", self.query) except portage.exception.InvalidAtom as err: message = "query.py: find_best(), match-all, query=%s, InvalidAtom=%s" %( self.query, str(err)) raise errors.GentoolkitInvalidAtom(message) masked = portage.best(matches) keywordable = [] for m in matches: status = portage.getmaskingstatus(m) if 'package.mask' not in status or 'profile' not in status: keywordable.append(m) if matches: keyworded = portage.best(keywordable) else: return Package(best) if include_keyworded and keyworded: return Package(keyworded) if include_masked and masked: return Package(masked) return None
def get_latest_ebuild(self, include_masked = False): """Return latest ebuild of a package""" # Note: this is slow, see get_versions() # Note: doesn't return hard-masked packages by default, unless in package.unmask # unstable packages however ARE returned. To return the best version for a system, # taking into account keywords and masking, use get_best_ebuild(). if self.full_name == "None": return '' if include_masked: return portage.best(self.get_versions()) if self.latest_ebuild == None: vers = self.get_versions() #dprint("PKGCORE_LIB: get_latest_ebuild; vers = " + str(vers)) for m in self.get_hard_masked(check_unmask = True): while m in vers: vers.remove(m) self.latest_ebuild = portage.best(vers) return self.latest_ebuild
def _check_updates(self): mybestpv = self.emerge_config.target_config.trees[ 'porttree'].dbapi.xmatch("bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM) mypvs = portage.best( self.emerge_config.target_config.trees['vartree'].dbapi.match( portage.const.PORTAGE_PACKAGE_ATOM)) try: old_use = (self.emerge_config.target_config.trees["vartree"].dbapi. aux_get(mypvs, ["USE"])[0].split()) except KeyError: old_use = () chk_updated_cfg_files( self.emerge_config.target_config.root, portage.util.shlex_split( self.emerge_config.target_config.settings.get( "CONFIG_PROTECT", "")), ) msgs = [] if not (mybestpv and mypvs ) or mybestpv == mypvs or "--quiet" in self.emerge_config.opts: return msgs # Suggest to update to the latest available version of portage. # Since changes to PYTHON_TARGETS cause complications, this message # is suppressed if the new version has different PYTHON_TARGETS enabled # than previous version. portdb = self.emerge_config.target_config.trees["porttree"].dbapi portdb.doebuild_settings.setcpv(mybestpv, mydb=portdb) usemask = portdb.doebuild_settings.usemask useforce = portdb.doebuild_settings.useforce new_use = (frozenset(portdb.doebuild_settings["PORTAGE_USE"].split()) | useforce) - usemask new_python_targets = frozenset(x for x in new_use if x.startswith("python_targets_")) old_python_targets = frozenset(x for x in old_use if x.startswith("python_targets_")) if new_python_targets == old_python_targets: msgs.append('') msgs.append( warn(" * ") + bold("An update to portage is available.") + " It is _highly_ recommended") msgs.append( warn(" * ") + "that you update portage now, before any other packages are updated." ) msgs.append('') msgs.append( warn(" * ") + "To update portage, run 'emerge --oneshot sys-apps/portage' now." ) msgs.append('') return msgs
def best_visible(argv): """<root> [<category/package>]+ Returns category/package-version (without .ebuild). """ if (len(argv) < 2): raise Exception("insufficient parameters") try: mylist = portage.db[argv[0]]["porttree"].dbapi.match(argv[1]) return 0, portage.best(mylist) except KeyError: return 1, ""
def get_best_version(atom): ''' Get the best available version accounting for keywords and masking. atom The atom to search for Return the best availalbe version. ''' available = portage.db['/']['porttree'].dbapi.match(atom) return portage.best(available)
def best_version(argv): """<root> <category/package> Returns category/package-version (without .ebuild). """ if (len(argv) < 2): print "ERROR: insufficient parameters!" raise Exception try: mylist = portage.db[argv[0]]["vartree"].dbapi.match(argv[1]) return 0, portage.best(mylist) except KeyError: return 1, ""
def GetStablePackageVersion(atom, installed): """Extracts the current stable version for a given package. args: target, package - the target/package to operate on eg. i686-pc-linux-gnu,gcc installed - Whether we want installed packages or ebuilds returns a string containing the latest version. """ pkgtype = 'vartree' if installed else 'porttree' # pylint: disable=E1101 cpv = portage.best(portage.db['/'][pkgtype].dbapi.match(atom, use_cache=0)) return portage.versions.cpv_getversion(cpv) if cpv else None
def GetStablePackageVersion(atom, installed, root='/'): """Extracts the current stable version for a given package. Args: atom: The target/package to operate on eg. i686-pc-linux-gnu,gcc installed: Whether we want installed packages or ebuilds root: The root to use when querying packages. Returns: A string containing the latest version. """ pkgtype = 'vartree' if installed else 'porttree' cpv = portage.best(PortageTrees(root)[pkgtype].dbapi.match(atom, use_cache=0)) return portage.versions.cpv_getversion(cpv) if cpv else None
def GetStablePackageVersion(atom, installed, root='/'): """Extracts the current stable version for a given package. Args: atom: The target/package to operate on eg. i686-pc-linux-gnu,gcc installed: Whether we want installed packages or ebuilds root: The root to use when querying packages. Returns: A string containing the latest version. """ pkgtype = 'vartree' if installed else 'porttree' # pylint: disable=E1101 cpv = portage.best(PortageTrees(root)[pkgtype].dbapi.match(atom, use_cache=0)) return portage.versions.cpv_getversion(cpv) if cpv else None
def all_best_visible(argv): """<root> Returns all best_visible packages (without .ebuild). """ if (len(argv) < 1): print "ERROR: insufficient parameters!" raise Exception("ERROR: insufficient parameters!") #print portage.db[argv[0]]["porttree"].dbapi.cp_all() s = '' for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all(): mybest = portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg)) if mybest: s += mybest + "\n" return 0, s
def _config_repo_match(repo_name, atoma, atomb): """ Check whether to perform a world change from atoma to atomb. If best vardb match for atoma comes from the same repository as the update file, allow that. Additionally, if portdb still can find a match for old atom name, warn about that. """ matches = vardb.match(atoma) if not matches: matches = vardb.match(atomb) if not matches: return False repository = vardb.aux_get(best(matches), ['repository'])[0] return repository == repo_name or \ (repo_name == master_repo and repository not in repo_map)
def mass_best_visible(argv): """<root> [<category/package>]+ Returns category/package-version (without .ebuild). """ if (len(argv) < 2): print "ERROR: insufficient parameters!" raise Exception try: s = '' for pack in argv[1:]: mylist = portage.db[argv[0]]["porttree"].dbapi.match(pack) s += "%s:%s\n" % (pack, portage.best(mylist)) return 0, s except KeyError: return 1, ''
def _world_repo_match(atoma, atomb): """ Check whether to perform a world change from atoma to atomb. If best vardb match for atoma comes from the same repository as the update file, allow that. Additionally, if portdb still can find a match for old atom name, warn about that. """ matches = vardb.match(atoma) if not matches: matches = vardb.match(atomb) if matches and \ repo_match(vardb.aux_get(best(matches), ['repository'])[0]): if portdb.match(atoma): world_warnings.add((atoma, atomb)) return True return False
def _world_repo_match(atoma, atomb): """ Check whether to perform a world change from atoma to atomb. If best vardb match for atoma comes from the same repository as the update file, allow that. Additionally, if portdb still can find a match for old atom name, warn about that. """ matches = vardb.match(atoma) if not matches: matches = vardb.match(atomb) if matches and \ repo_match(vardb.aux_get(best(matches), ['repository'])[0]): if portdb.match(atoma): world_warnings.add((atoma, atomb)) return True else: return False
def do_normal(pkg, verbose): data = [] if not pkg[4]: installed = "[ Not Installed ]" else: installed = pkg[4] if pkg[2]: masked = red(" [ Masked ]") else: masked = "" data.append("%s %s%s\n %s %s\n %s %s" % \ (green("*"), bold(pkg[1]), masked, darkgreen("Latest version available:"), pkg[3], darkgreen("Latest version installed:"), installed)) if verbose: mpv = best(portdb.xmatch("match-all", pkg[1])) iuse_split, final_use = get_flags(mpv, final_setting=True) iuse = "" use_list = [] for ebuild_iuse in iuse_split: use = ebuild_iuse.lstrip('+-') if use in final_use: use_list.append(red("+" + use) + " ") else: use_list.append(blue("-" + use) + " ") use_list.sort() iuse = ' '.join(use_list) if iuse == "": iuse = "-" data.append(" %s %s\n %s %s" % \ (darkgreen("Unstable version:"), pkg_version(mpv), darkgreen("Use Flags (stable):"), iuse)) data.append(" %s %s\n %s %s\n %s %s\n %s %s\n" % \ (darkgreen("Size of downloaded files:"), pkg[5], darkgreen("Homepage:"), pkg[6], darkgreen("Description:"), pkg[7], darkgreen("License:"), pkg[8])) return data
def getInstallationStatus(self,package): installed_package = self._vardb.match(package) if installed_package: try: self._vardb.match_unordered except AttributeError: installed_package = installed_package[-1] else: installed_package = portage.best(installed_package) else: installed_package = "" result = "" version = self.getVersion(installed_package,search.VERSION_RELEASE) if len(version) > 0: result = darkgreen("Latest version installed:")+" "+version else: result = darkgreen("Latest version installed:")+" [ Not Installed ]" return result
def do_normal(pkg, verbose): data = [] if not pkg[4]: installed = "[ Not Installed ]" else: installed = pkg[4] if pkg[2]: masked = red(" [ Masked ]") else: masked = "" data.append("%s %s%s\n %s %s\n %s %s" % \ (green("*"), bold(pkg[1]), masked, darkgreen("Latest version available:"), pkg[3], darkgreen("Latest version installed:"), installed)) if verbose: mpv = best(portdb.xmatch("match-all", pkg[1])) iuse_split, final_use = get_flags(mpv, final_setting=True) iuse = "" use_list = [] for ebuild_iuse in iuse_split: use = ebuild_iuse.lstrip('+-') if use in final_use: use_list.append(red("+" + use) + " ") else: use_list.append(blue("-" + use) + " ") use_list.sort() iuse = ' '.join(use_list) if iuse == "": iuse = "-" data.append(" %s %s\n %s %s" % \ (darkgreen("Unstable version:"), pkg_version(mpv), darkgreen("Use Flags (stable):"), iuse)) data.append(" %s %s\n %s %s\n %s %s\n %s %s\n" % \ (darkgreen("Size of downloaded files:"), pkg[5], darkgreen("Homepage:"), pkg[6], darkgreen("Description:"), pkg[7], darkgreen("License:"), pkg[8])) return data, False
def _check_updates(self): mybestpv = self.emerge_config.target_config.trees['porttree'].dbapi.xmatch( "bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM) mypvs = portage.best( self.emerge_config.target_config.trees['vartree'].dbapi.match( portage.const.PORTAGE_PACKAGE_ATOM)) chk_updated_cfg_files(self.emerge_config.target_config.root, portage.util.shlex_split( self.emerge_config.target_config.settings.get("CONFIG_PROTECT", ""))) msgs = [] if mybestpv != mypvs and "--quiet" not in self.emerge_config.opts: msgs.append('') msgs.append(warn(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended") msgs.append(warn(" * ")+"that you update portage now, before any other packages are updated.") msgs.append('') msgs.append(warn(" * ")+"To update portage, run 'emerge --oneshot portage' now.") msgs.append('') return msgs
def getInstallationStatus(self, package): installed_package = self._vardb.match(package) if installed_package: try: self._vardb.match_unordered except AttributeError: installed_package = installed_package[-1] else: installed_package = portage.best(installed_package) else: installed_package = "" result = "" version = self.getVersion(installed_package, search.VERSION_RELEASE) if len(version) > 0: result = darkgreen("Latest version installed:") + " " + version else: result = darkgreen( "Latest version installed:") + " [ Not Installed ]" return result
def is_upgradable(self): """Indicates whether an unmasked upgrade/downgrade is available. If portage wants to upgrade the package, returns 1. If portage wants to downgrade the package, returns -1. Else, returns 0. """ if self.full_name == "None": return 0 if self.upgradable == None: best = self.get_best_ebuild() installed = self.get_latest_installed() if not best or not installed: self.upgradable = 0 return self.upgradable better = portage.best([best,installed]) if best == installed: self.upgradable = 0 elif better == best: self.upgradable = 1 elif better == installed: self.upgradable = -1 return self.upgradable
def _post_graph_filters(self, graph, vardb, portdb): """ Execute post-graph generation (dependencies calculation) filters against the package dependencies to see if they're eligible for building. """ # list of _emerge.Package.Package objects package_queue = graph.altlist() allow_soft_blocker = self._params["soft-blocker"] == "yes" if not allow_soft_blocker: blockers = [x for x in package_queue if isinstance(x, Blocker)] if blockers: # sorry, we're not allowed to have soft-blockers print_warning("the following soft-blockers were found:") print_warning("\n ".join([x.atom for x in blockers])) print_warning("but 'soft-blocker: no' in config, aborting") return None # filter out blockers real_queue = [x for x in package_queue if not isinstance( x, Blocker)] # filter out broken or corrupted objects real_queue = [x for x in real_queue if x.cpv] # package_queue can also contain _emerge.Blocker.Blocker objects # not exposing .cpv field (but just .cp). dep_list = [] for pobj in package_queue: if isinstance(pobj, Blocker): # blocker, list full atom dep_list.append(pobj.atom) continue cpv = pobj.cpv repo = pobj.repo if repo: repo = "::" + repo if cpv: dep_list.append(cpv+repo) else: print_warning( "attention, %s has broken cpv: '%s', ignoring" % ( pobj, cpv,)) # calculate dependencies, if --dependencies is not enabled # because we have to validate it if (self._params["dependencies"] == "no") \ and (len(package_queue) > 1): deps = "\n ".join(dep_list) print_warning("dependencies pulled in:") print_warning(deps) print_warning("but 'dependencies: no' in config, aborting") return None # protect against unwanted package unmerges if self._params["unmerge"] == "no": unmerges = [x for x in real_queue if x.operation == "uninstall"] if unmerges: deps = "\n ".join([x.cpv for x in unmerges]) print_warning("found package unmerges:") print_warning(deps) print_warning("but 'unmerge: no' in config, aborting") return None # inspect use flags changes allow_new_useflags = self._params["new-useflags"] == "yes" allow_removed_useflags = \ self._params["removed-useflags"] == "yes" use_flags_give_up = False if (not allow_new_useflags) or (not allow_removed_useflags): # checking for use flag changes for pkg in real_queue: # frozenset enabled_flags = pkg.use.enabled inst_atom = portage.best( vardb.match(pkg.slot_atom, use_cache=0)) if not inst_atom: # new package, ignore check continue installed_flags = frozenset( vardb.aux_get(inst_atom, ["USE"])[0].split()) new_flags = enabled_flags - installed_flags removed_flags = installed_flags - enabled_flags if (not allow_new_useflags) and new_flags: print_warning( "ouch: %s wants these new USE flags: %s" % ( pkg.cpv+"::"+pkg.repo, " ".join(sorted(new_flags)),)) use_flags_give_up = True if (not allow_removed_useflags) and removed_flags: print_warning( "ouch: %s has these USE flags removed: %s" % ( pkg.cpv+"::"+pkg.repo, " ".join(sorted(removed_flags)),)) use_flags_give_up = True if use_flags_give_up: print_warning("cannot continue due to unmet " "USE flags constraint") return None allow_downgrade = self._params["downgrade"] == "yes" # check the whole queue against downgrade directive if not allow_downgrade: allow_downgrade_give_ups = [] for pkg in real_queue: inst_atom = portage.best( vardb.match(pkg.slot_atom, use_cache=0)) cmp_res = -1 if inst_atom: # -1 if inst_atom is older than pkg.cpv # 1 if inst_atom is newer than pkg.cpv # 0 if they are equal cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(inst_atom), portage.versions.pkgsplit(pkg.cpv)) if cmp_res > 0: allow_downgrade_give_ups.append((inst_atom, pkg.cpv)) if allow_downgrade_give_ups: print_warning( "cannot continue due to package " "downgrade not allowed for:") for inst_atom, avail_atom in allow_downgrade_give_ups: print_warning(" installed: %s | wanted: %s" % ( inst_atom, avail_atom,)) return None changing_repo_pkgs = [] for pkg in real_queue: wanted_repo = pkg.repo inst_atom = portage.best( vardb.match(pkg.slot_atom, use_cache=0)) current_repo = vardb.aux_get(inst_atom, ["repository"])[0] if current_repo: if current_repo != wanted_repo: changing_repo_pkgs.append( (pkg.cpv, pkg.slot, current_repo, wanted_repo)) if changing_repo_pkgs: print_warning("") print_warning( "Attention, packages are moving across SPM repositories:") for pkg_atom, pkg_slot, c_repo, w_repo in changing_repo_pkgs: print_warning(" %s:%s [%s->%s]" % (pkg_atom, pkg_slot, c_repo, w_repo,)) print_warning("") allow_spm_repo_change = self._params["spm-repository-change"] \ == "yes" allow_spm_repo_change_if_ups = \ self._params["spm-repository-change-if-upstreamed"] == "yes" if (not allow_spm_repo_change) and allow_spm_repo_change_if_ups: print_info("SPM repository change allowed if the original " "repository does no longer contain " "current packages.") # check if source repository still contains the package # in this case, set allow_spm_repo_change to True _allow = True for pkg_atom, pkg_slot, c_repo, w_repo in changing_repo_pkgs: pkg_key = portage.dep.dep_getkey("=%s" % (pkg_atom,)) pkg_target = "%s:%s::%s" % ( pkg_key, pkg_slot, c_repo) pkg_match = portdb.xmatch("bestmatch-visible", pkg_target) if pkg_match: # package still available in source repo _allow = False print_warning(" %s:%s, still in repo: %s" % ( pkg_atom, pkg_slot, c_repo,)) # do not break, print all the list # break if _allow and changing_repo_pkgs: print_info( "current packages are no longer in their " "original repository, SPM repository change allowed.") allow_spm_repo_change = True if changing_repo_pkgs and (not allow_spm_repo_change): print_warning( "cannot continue due to unmet SPM repository " "change constraint") return None print_info("USE flags constraints are met for all " "the queued packages") return real_queue
def find_best(self, list, only_cpv=False): if only_cpv: return portage.best(list) else: return self.new_package(portage.best(list))
def find_best (self, list, only_cpv = False): if only_cpv: return portage.best(list) else: return self.new_package(portage.best(list))
def _pre_graph_filters(self, package, portdb, vardb): """ Execute basic, pre-graph generation (dependencies calculation) filters against the package dependency to see if it's eligible for the graph. """ allow_rebuild = self._params["rebuild"] == "yes" allow_not_installed = self._params["not-installed"] == "yes" allow_downgrade = self._params["downgrade"] == "yes" accepted = [] # now determine what's the installed version. best_installed = portage.best(vardb.match(package, use_cache=0)) if (not best_installed) and (not allow_not_installed): # package not installed print_error("package not installed: %s, ignoring this one" % ( package,)) self._not_installed_packages.append(package) return accepted if (not best_installed) and allow_not_installed: print_warning( "%s not installed, but 'not-installed: yes' provided" % ( package,)) best_visibles = [] try: best_visibles += portdb.xmatch("match-visible", package) except portage.exception.InvalidAtom: print_error("cannot match: %s, invalid atom" % (package,)) # map all the cpvs to their slots cpv_slot_map = {} for pkg in best_visibles: obj = cpv_slot_map.setdefault(pkg.slot, []) obj.append(pkg) # then pick the best for each slot del best_visibles[:] for slot, pkgs in cpv_slot_map.items(): pkg = portage.best(pkgs) best_visibles.append(pkg) best_visibles.sort() # deterministic is better if not best_visibles: # package not found, return error print_error("cannot match: %s, ignoring this one" % (package,)) self._not_found_packages.append(package) return accepted print_info("matched: %s for %s" % (", ".join(best_visibles), package,)) for best_visible in best_visibles: cp = best_visible.cp slot = best_visible.slot cp_slot = "%s:%s" % (cp, slot) # determine what's the installed version. # we know that among all the best_visibles, there is one that # is installed. The question is whether we got it now. best_installed = portage.best(vardb.match(cp_slot, use_cache=0)) if (not best_installed) and (not allow_not_installed): # package not installed print_warning("%s not installed, skipping" % (cp_slot,)) continue build_only = self._params["build-only"] == "yes" cmp_res = -1 if best_installed: print_info("found installed: %s for %s" % ( best_installed, package,)) # now compare # -1 if best_installed is older than best_visible # 1 if best_installed is newer than best_visible # 0 if they are equal cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_installed), portage.versions.pkgsplit(best_visible)) elif (not best_installed) and build_only: # package is not installed, and build-only # is provided. We assume that the package # is being built and added to repositories directly. # This means that we need to query binpms to know # about the current version. print_info("package is not installed, and 'build-only: yes'. " "Asking the binpms about the package state.") best_available = self._binpms.best_available(cp_slot) print_info("found available: %s for %s" % ( best_available, cp_slot)) if best_available: cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_available), portage.versions.pkgsplit(best_visible)) is_rebuild = cmp_res == 0 if (cmp_res == 1) and (not allow_downgrade): # downgrade in action and downgrade not allowed, aborting! print_warning( "%s would be downgraded, %s to %s, ignoring" % ( cp_slot, best_installed, best_visible,)) continue if is_rebuild and (not allow_rebuild): # rebuild in action and rebuild not allowed, aborting! print_warning( "%s would be rebuilt to %s, ignoring" % ( cp_slot, best_visible,)) continue # at this point we can go ahead accepting package in queue print_info("package: %s [%s], accepted in queue" % ( best_visible, cp_slot,)) accepted.append(best_visible) return accepted
def _unmerge_display(root_config, myopts, unmerge_action, unmerge_files, clean_delay=1, ordered=0, writemsg_level=portage.util.writemsg_level): """ Returns a tuple of (returncode, pkgmap) where returncode is os.EX_OK if no errors occur, and 1 otherwise. """ quiet = "--quiet" in myopts settings = root_config.settings sets = root_config.sets vartree = root_config.trees["vartree"] candidate_catpkgs = [] global_unmerge = 0 out = portage.output.EOutput() pkg_cache = {} db_keys = list(vartree.dbapi._aux_cache_keys) def _pkg(cpv): pkg = pkg_cache.get(cpv) if pkg is None: pkg = Package(built=True, cpv=cpv, installed=True, metadata=zip(db_keys, vartree.dbapi.aux_get(cpv, db_keys)), operation="uninstall", root_config=root_config, type_name="installed") pkg_cache[cpv] = pkg return pkg vdb_path = os.path.join(settings["EROOT"], portage.VDB_PATH) try: # At least the parent needs to exist for the lock file. portage.util.ensure_dirs(vdb_path) except portage.exception.PortageException: pass vdb_lock = None try: if os.access(vdb_path, os.W_OK): vartree.dbapi.lock() vdb_lock = True realsyslist = [] sys_virt_map = {} for x in sets["system"].getAtoms(): for atom in expand_new_virt(vartree.dbapi, x): if not atom.blocker: realsyslist.append(atom) if atom.cp != x.cp: sys_virt_map[atom.cp] = x.cp syslist = [] for x in realsyslist: mycp = x.cp # Since Gentoo stopped using old-style virtuals in # 2011, typically it's possible to avoid getvirtuals() # calls entirely. It will not be triggered here by # new-style virtuals since those are expanded to # non-virtual atoms above by expand_new_virt(). if mycp.startswith("virtual/") and \ mycp in settings.getvirtuals(): providers = [] for provider in settings.getvirtuals()[mycp]: if vartree.dbapi.match(provider): providers.append(provider) if len(providers) == 1: syslist.extend(providers) else: syslist.append(mycp) syslist = frozenset(syslist) if not unmerge_files: if unmerge_action in ["rage-clean", "unmerge"]: print() print( bold("emerge %s" % unmerge_action) + " can only be used with specific package names") print() return 1, {} global_unmerge = 1 # process all arguments and add all # valid db entries to candidate_catpkgs if global_unmerge: if not unmerge_files: candidate_catpkgs.extend(vartree.dbapi.cp_all()) else: #we've got command-line arguments if not unmerge_files: print("\nNo packages to %s have been provided.\n" % unmerge_action) return 1, {} for x in unmerge_files: arg_parts = x.split('/') if x[0] not in [".","/"] and \ arg_parts[-1][-7:] != ".ebuild": #possible cat/pkg or dep; treat as such candidate_catpkgs.append(x) elif unmerge_action in ["prune", "clean"]: print("\n!!! Prune and clean do not accept individual" + \ " ebuilds as arguments;\n skipping.\n") continue else: # it appears that the user is specifying an installed # ebuild and we're in "unmerge" mode, so it's ok. if not os.path.exists(x): print("\n!!! The path '" + x + "' doesn't exist.\n") return 1, {} absx = os.path.abspath(x) sp_absx = absx.split("/") if sp_absx[-1][-7:] == ".ebuild": del sp_absx[-1] absx = "/".join(sp_absx) sp_absx_len = len(sp_absx) vdb_path = os.path.join(settings["EROOT"], portage.VDB_PATH) sp_vdb = vdb_path.split("/") sp_vdb_len = len(sp_vdb) if not os.path.exists(absx + "/CONTENTS"): print("!!! Not a valid db dir: " + str(absx)) return 1, {} if sp_absx_len <= sp_vdb_len: # The Path is shorter... so it can't be inside the vdb. print(sp_absx) print(absx) print("\n!!!",x,"cannot be inside "+ \ vdb_path+"; aborting.\n") return 1, {} for idx in range(0, sp_vdb_len): if idx >= sp_absx_len or sp_vdb[idx] != sp_absx[idx]: print(sp_absx) print(absx) print("\n!!!", x, "is not inside "+\ vdb_path+"; aborting.\n") return 1, {} print("=" + "/".join(sp_absx[sp_vdb_len:])) candidate_catpkgs.append("=" + "/".join(sp_absx[sp_vdb_len:])) newline = "" if not quiet: newline = "\n" if settings["ROOT"] != "/": writemsg_level(darkgreen(newline+ \ ">>> Using system located in ROOT tree %s\n" % \ settings["ROOT"])) if ("--pretend" in myopts or "--ask" in myopts) and not quiet: writemsg_level(darkgreen(newline+\ ">>> These are the packages that would be unmerged:\n")) # Preservation of order is required for --depclean and --prune so # that dependencies are respected. Use all_selected to eliminate # duplicate packages since the same package may be selected by # multiple atoms. pkgmap = [] all_selected = set() for x in candidate_catpkgs: # cycle through all our candidate deps and determine # what will and will not get unmerged try: mymatch = vartree.dbapi.match(x) except portage.exception.AmbiguousPackageName as errpkgs: print("\n\n!!! The short ebuild name \"" + \ x + "\" is ambiguous. Please specify") print("!!! one of the following fully-qualified " + \ "ebuild names instead:\n") for i in errpkgs[0]: print(" " + green(i)) print() sys.exit(1) if not mymatch and x[0] not in "<>=~": mymatch = vartree.dep_match(x) if not mymatch: portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ (x.replace("null/", ""), unmerge_action), noiselevel=-1) continue pkgmap.append({ "protected": set(), "selected": set(), "omitted": set() }) mykey = len(pkgmap) - 1 if unmerge_action in ["rage-clean", "unmerge"]: for y in mymatch: if y not in all_selected: pkgmap[mykey]["selected"].add(y) all_selected.add(y) elif unmerge_action == "prune": if len(mymatch) == 1: continue best_version = mymatch[0] best_slot = vartree.getslot(best_version) best_counter = vartree.dbapi.cpv_counter(best_version) for mypkg in mymatch[1:]: myslot = vartree.getslot(mypkg) mycounter = vartree.dbapi.cpv_counter(mypkg) if (myslot == best_slot and mycounter > best_counter) or \ mypkg == portage.best([mypkg, best_version]): if myslot == best_slot: if mycounter < best_counter: # On slot collision, keep the one with the # highest counter since it is the most # recently installed. continue best_version = mypkg best_slot = myslot best_counter = mycounter pkgmap[mykey]["protected"].add(best_version) pkgmap[mykey]["selected"].update(mypkg for mypkg in mymatch \ if mypkg != best_version and mypkg not in all_selected) all_selected.update(pkgmap[mykey]["selected"]) else: # unmerge_action == "clean" slotmap = {} for mypkg in mymatch: if unmerge_action == "clean": myslot = vartree.getslot(mypkg) else: # since we're pruning, we don't care about slots # and put all the pkgs in together myslot = 0 if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][vartree.dbapi.cpv_counter(mypkg)] = mypkg for mypkg in vartree.dbapi.cp_list( portage.cpv_getkey(mymatch[0])): myslot = vartree.getslot(mypkg) if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][vartree.dbapi.cpv_counter(mypkg)] = mypkg for myslot in slotmap: counterkeys = list(slotmap[myslot]) if not counterkeys: continue counterkeys.sort() pkgmap[mykey]["protected"].add( slotmap[myslot][counterkeys[-1]]) del counterkeys[-1] for counter in counterkeys[:]: mypkg = slotmap[myslot][counter] if mypkg not in mymatch: counterkeys.remove(counter) pkgmap[mykey]["protected"].add( slotmap[myslot][counter]) #be pretty and get them in order of merge: for ckey in counterkeys: mypkg = slotmap[myslot][ckey] if mypkg not in all_selected: pkgmap[mykey]["selected"].add(mypkg) all_selected.add(mypkg) # ok, now the last-merged package # is protected, and the rest are selected numselected = len(all_selected) if global_unmerge and not numselected: portage.writemsg_stdout( "\n>>> No outdated packages were found on your system.\n") return 1, {} if not numselected: portage.writemsg_stdout( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 1, {} finally: if vdb_lock: vartree.dbapi.flush_cache() vartree.dbapi.unlock() # generate a list of package sets that are directly or indirectly listed in "selected", # as there is no persistent list of "installed" sets installed_sets = ["selected"] stop = False pos = 0 while not stop: stop = True pos = len(installed_sets) for s in installed_sets[pos - 1:]: if s not in sets: continue candidates = [ x[len(SETPREFIX):] for x in sets[s].getNonAtoms() if x.startswith(SETPREFIX) ] if candidates: stop = False installed_sets += candidates installed_sets = [ x for x in installed_sets if x not in root_config.setconfig.active ] del stop, pos # we don't want to unmerge packages that are still listed in user-editable package sets # listed in "world" as they would be remerged on the next update of "world" or the # relevant package sets. unknown_sets = set() for cp in range(len(pkgmap)): for cpv in pkgmap[cp]["selected"].copy(): try: pkg = _pkg(cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if unmerge_action != "clean" and root_config.root == "/": skip_pkg = False if portage.match_from_list(portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): msg = ("Not unmerging package %s " "since there is no valid reason for Portage to " "%s itself.") % (pkg.cpv, unmerge_action) skip_pkg = True elif vartree.dbapi._dblink(cpv).isowner( portage._python_interpreter): msg = ("Not unmerging package %s since there is no valid " "reason for Portage to %s currently used Python " "interpreter.") % (pkg.cpv, unmerge_action) skip_pkg = True if skip_pkg: for line in textwrap.wrap(msg, 75): out.eerror(line) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) continue parents = [] for s in installed_sets: # skip sets that the user requested to unmerge, and skip world # user-selected set, since the package will be removed from # that set later on. if s in root_config.setconfig.active or s == "selected": continue if s not in sets: if s in unknown_sets: continue unknown_sets.add(s) out = portage.output.EOutput() out.eerror(("Unknown set '@%s' in %s%s") % \ (s, root_config.settings['EROOT'], portage.const.WORLD_SETS_FILE)) continue # only check instances of EditablePackageSet as other classes are generally used for # special purposes and can be ignored here (and are usually generated dynamically, so the # user can't do much about them anyway) if isinstance(sets[s], EditablePackageSet): # This is derived from a snippet of code in the # depgraph._iter_atoms_for_pkg() method. for atom in sets[s].iterAtomsForPackage(pkg): inst_matches = vartree.dbapi.match(atom) inst_matches.reverse() # descending order higher_slot = None for inst_cpv in inst_matches: try: inst_pkg = _pkg(inst_cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if inst_pkg.cp != atom.cp: continue if pkg >= inst_pkg: # This is descending order, and we're not # interested in any versions <= pkg given. break if pkg.slot_atom != inst_pkg.slot_atom: higher_slot = inst_pkg break if higher_slot is None: parents.append(s) break if parents: print( colorize("WARN", "Package %s is going to be unmerged," % cpv)) print( colorize( "WARN", "but still listed in the following package sets:")) print(" %s\n" % ", ".join(parents)) del installed_sets numselected = len(all_selected) if not numselected: writemsg_level( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 1, {} # Unmerge order only matters in some cases if not ordered: unordered = {} for d in pkgmap: selected = d["selected"] if not selected: continue cp = portage.cpv_getkey(next(iter(selected))) cp_dict = unordered.get(cp) if cp_dict is None: cp_dict = {} unordered[cp] = cp_dict for k in d: cp_dict[k] = set() for k, v in d.items(): cp_dict[k].update(v) pkgmap = [unordered[cp] for cp in sorted(unordered)] # Sort each set of selected packages if ordered: for pkg in pkgmap: pkg["selected"] = sorted(pkg["selected"], key=cpv_sort_key()) for x in range(len(pkgmap)): selected = pkgmap[x]["selected"] if not selected: continue for mytype, mylist in pkgmap[x].items(): if mytype == "selected": continue mylist.difference_update(all_selected) cp = portage.cpv_getkey(next(iter(selected))) for y in vartree.dep_match(cp): if y not in pkgmap[x]["omitted"] and \ y not in pkgmap[x]["selected"] and \ y not in pkgmap[x]["protected"] and \ y not in all_selected: pkgmap[x]["omitted"].add(y) if global_unmerge and not pkgmap[x]["selected"]: #avoid cluttering the preview printout with stuff that isn't getting unmerged continue if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist: virt_cp = sys_virt_map.get(cp) if virt_cp is None: cp_info = "'%s'" % (cp, ) else: cp_info = "'%s' (%s)" % (cp, virt_cp) writemsg_level(colorize("BAD","\n\n!!! " + \ "%s is part of your system profile.\n" % (cp_info,)), level=logging.WARNING, noiselevel=-1) writemsg_level(colorize("WARN","!!! Unmerging it may " + \ "be damaging to your system.\n\n"), level=logging.WARNING, noiselevel=-1) if not quiet: writemsg_level("\n %s\n" % (bold(cp), ), noiselevel=-1) else: writemsg_level(bold(cp) + ": ", noiselevel=-1) for mytype in ["selected", "protected", "omitted"]: if not quiet: writemsg_level((mytype + ": ").rjust(14), noiselevel=-1) if pkgmap[x][mytype]: sorted_pkgs = [] for mypkg in pkgmap[x][mytype]: try: sorted_pkgs.append(mypkg.cpv) except AttributeError: sorted_pkgs.append(_pkg_str(mypkg)) sorted_pkgs.sort(key=cpv_sort_key()) for mypkg in sorted_pkgs: if mytype == "selected": writemsg_level(colorize("UNMERGE_WARN", mypkg.version + " "), noiselevel=-1) else: writemsg_level(colorize("GOOD", mypkg.version + " "), noiselevel=-1) else: writemsg_level("none ", noiselevel=-1) if not quiet: writemsg_level("\n", noiselevel=-1) if quiet: writemsg_level("\n", noiselevel=-1) writemsg_level("\nAll selected packages: %s\n" % " ".join('=%s' % x for x in all_selected), noiselevel=-1) writemsg_level("\n>>> " + colorize("UNMERGE_WARN", "'Selected'") + \ " packages are slated for removal.\n") writemsg_level(">>> " + colorize("GOOD", "'Protected'") + \ " and " + colorize("GOOD", "'omitted'") + \ " packages will not be removed.\n\n") return os.EX_OK, pkgmap
def _pre_graph_filters(self, package, portdb, vardb): """ Execute basic, pre-graph generation (dependencies calculation) filters against the package dependency to see if it's eligible for the graph. """ allow_rebuild = self._params["rebuild"] == "yes" allow_not_installed = self._params["not-installed"] == "yes" allow_downgrade = self._params["downgrade"] == "yes" try: best_visible = portdb.xmatch("bestmatch-visible", package) except portage.exception.InvalidAtom: print_error("cannot match: %s, invalid atom" % (package,)) best_visible = None if not best_visible: # package not found, return error print_error("cannot match: %s, ignoring this one" % (package,)) self._not_found_packages.append(package) return None print_info("matched: %s for %s" % (best_visible, package,)) # now determine what's the installed version. best_installed = portage.best(vardb.match(package)) if (not best_installed) and (not allow_not_installed): # package not installed print_error("package not installed: %s, ignoring this one" % ( package,)) self._not_installed_packages.append(package) return None if (not best_installed) and allow_not_installed: print_warning( "package not installed: " "%s, but 'not-installed: yes' provided" % (package,)) build_only = self._params["build-only"] == "yes" cmp_res = -1 if best_installed: print_info("found installed: %s for %s" % ( best_installed, package,)) # now compare # -1 if best_installed is older than best_visible # 1 if best_installed is newer than best_visible # 0 if they are equal cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_installed), portage.versions.pkgsplit(best_visible)) elif (not best_installed) and build_only: # package is not installed, and build-only # is provided. We assume that the package # is being built and added to repositories directly. # This means that we need to query binpms to know # about the current version. print_info("package is not installed, and 'build-only: yes'. " "Asking the binpms about the package state.") best_available = self._binpms.best_available(package) print_info("found available: %s for %s" % ( best_available, package)) if best_available: cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_available), portage.versions.pkgsplit(best_visible)) is_rebuild = cmp_res == 0 if (cmp_res == 1) and (not allow_downgrade): # downgrade in action and downgrade not allowed, aborting! print_warning( "package: %s, would be downgraded, %s to %s, ignoring" % ( package, best_installed, best_visible,)) return None if is_rebuild and (not allow_rebuild): # rebuild in action and rebuild not allowed, aborting! print_warning( "package: %s, would be rebuilt to %s, ignoring" % ( package, best_visible,)) return None # at this point we can go ahead accepting package in queue print_info("package: %s [%s], accepted in queue" % ( best_visible, package,)) return best_visible
def unmerge(root_config, myopts, unmerge_action, unmerge_files, ldpath_mtimes, autoclean=0, clean_world=1, clean_delay=1, ordered=0, raise_on_error=0, scheduler=None, writemsg_level=portage.util.writemsg_level): if clean_world: clean_world = myopts.get('--deselect') != 'n' quiet = "--quiet" in myopts enter_invalid = '--ask-enter-invalid' in myopts settings = root_config.settings sets = root_config.sets vartree = root_config.trees["vartree"] candidate_catpkgs = [] global_unmerge = 0 xterm_titles = "notitles" not in settings.features out = portage.output.EOutput() pkg_cache = {} db_keys = list(vartree.dbapi._aux_cache_keys) def _pkg(cpv): pkg = pkg_cache.get(cpv) if pkg is None: pkg = Package(cpv=cpv, installed=True, metadata=zip(db_keys, vartree.dbapi.aux_get(cpv, db_keys)), root_config=root_config, type_name="installed") pkg_cache[cpv] = pkg return pkg vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH) try: # At least the parent needs to exist for the lock file. portage.util.ensure_dirs(vdb_path) except portage.exception.PortageException: pass vdb_lock = None try: if os.access(vdb_path, os.W_OK): vdb_lock = portage.locks.lockdir(vdb_path) realsyslist = sets["system"].getAtoms() syslist = [] for x in realsyslist: mycp = portage.dep_getkey(x) if mycp in settings.getvirtuals(): providers = [] for provider in settings.getvirtuals()[mycp]: if vartree.dbapi.match(provider): providers.append(provider) if len(providers) == 1: syslist.extend(providers) else: syslist.append(mycp) mysettings = portage.config(clone=settings) if not unmerge_files: if unmerge_action == "unmerge": print() print( bold("emerge unmerge") + " can only be used with specific package names") print() return 0 else: global_unmerge = 1 localtree = vartree # process all arguments and add all # valid db entries to candidate_catpkgs if global_unmerge: if not unmerge_files: candidate_catpkgs.extend(vartree.dbapi.cp_all()) else: #we've got command-line arguments if not unmerge_files: print("\nNo packages to unmerge have been provided.\n") return 0 for x in unmerge_files: arg_parts = x.split('/') if x[0] not in [".","/"] and \ arg_parts[-1][-7:] != ".ebuild": #possible cat/pkg or dep; treat as such candidate_catpkgs.append(x) elif unmerge_action in ["prune", "clean"]: print("\n!!! Prune and clean do not accept individual" + \ " ebuilds as arguments;\n skipping.\n") continue else: # it appears that the user is specifying an installed # ebuild and we're in "unmerge" mode, so it's ok. if not os.path.exists(x): print("\n!!! The path '" + x + "' doesn't exist.\n") return 0 absx = os.path.abspath(x) sp_absx = absx.split("/") if sp_absx[-1][-7:] == ".ebuild": del sp_absx[-1] absx = "/".join(sp_absx) sp_absx_len = len(sp_absx) vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH) vdb_len = len(vdb_path) sp_vdb = vdb_path.split("/") sp_vdb_len = len(sp_vdb) if not os.path.exists(absx + "/CONTENTS"): print("!!! Not a valid db dir: " + str(absx)) return 0 if sp_absx_len <= sp_vdb_len: # The Path is shorter... so it can't be inside the vdb. print(sp_absx) print(absx) print("\n!!!",x,"cannot be inside "+ \ vdb_path+"; aborting.\n") return 0 for idx in range(0, sp_vdb_len): if idx >= sp_absx_len or sp_vdb[idx] != sp_absx[idx]: print(sp_absx) print(absx) print("\n!!!", x, "is not inside "+\ vdb_path+"; aborting.\n") return 0 print("=" + "/".join(sp_absx[sp_vdb_len:])) candidate_catpkgs.append("=" + "/".join(sp_absx[sp_vdb_len:])) newline = "" if (not "--quiet" in myopts): newline = "\n" if settings["ROOT"] != "/": writemsg_level(darkgreen(newline+ \ ">>> Using system located in ROOT tree %s\n" % \ settings["ROOT"])) if (("--pretend" in myopts) or ("--ask" in myopts)) and \ not ("--quiet" in myopts): writemsg_level(darkgreen(newline+\ ">>> These are the packages that would be unmerged:\n")) # Preservation of order is required for --depclean and --prune so # that dependencies are respected. Use all_selected to eliminate # duplicate packages since the same package may be selected by # multiple atoms. pkgmap = [] all_selected = set() for x in candidate_catpkgs: # cycle through all our candidate deps and determine # what will and will not get unmerged try: mymatch = vartree.dbapi.match(x) except portage.exception.AmbiguousPackageName as errpkgs: print("\n\n!!! The short ebuild name \"" + \ x + "\" is ambiguous. Please specify") print("!!! one of the following fully-qualified " + \ "ebuild names instead:\n") for i in errpkgs[0]: print(" " + green(i)) print() sys.exit(1) if not mymatch and x[0] not in "<>=~": mymatch = localtree.dep_match(x) if not mymatch: portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ (x, unmerge_action), noiselevel=-1) continue pkgmap.append({ "protected": set(), "selected": set(), "omitted": set() }) mykey = len(pkgmap) - 1 if unmerge_action == "unmerge": for y in mymatch: if y not in all_selected: pkgmap[mykey]["selected"].add(y) all_selected.add(y) elif unmerge_action == "prune": if len(mymatch) == 1: continue best_version = mymatch[0] best_slot = vartree.getslot(best_version) best_counter = vartree.dbapi.cpv_counter(best_version) for mypkg in mymatch[1:]: myslot = vartree.getslot(mypkg) mycounter = vartree.dbapi.cpv_counter(mypkg) if (myslot == best_slot and mycounter > best_counter) or \ mypkg == portage.best([mypkg, best_version]): if myslot == best_slot: if mycounter < best_counter: # On slot collision, keep the one with the # highest counter since it is the most # recently installed. continue best_version = mypkg best_slot = myslot best_counter = mycounter pkgmap[mykey]["protected"].add(best_version) pkgmap[mykey]["selected"].update(mypkg for mypkg in mymatch \ if mypkg != best_version and mypkg not in all_selected) all_selected.update(pkgmap[mykey]["selected"]) else: # unmerge_action == "clean" slotmap = {} for mypkg in mymatch: if unmerge_action == "clean": myslot = localtree.getslot(mypkg) else: # since we're pruning, we don't care about slots # and put all the pkgs in together myslot = 0 if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)] = mypkg for mypkg in vartree.dbapi.cp_list( portage.cpv_getkey(mymatch[0])): myslot = vartree.getslot(mypkg) if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][vartree.dbapi.cpv_counter(mypkg)] = mypkg for myslot in slotmap: counterkeys = list(slotmap[myslot]) if not counterkeys: continue counterkeys.sort() pkgmap[mykey]["protected"].add( slotmap[myslot][counterkeys[-1]]) del counterkeys[-1] for counter in counterkeys[:]: mypkg = slotmap[myslot][counter] if mypkg not in mymatch: counterkeys.remove(counter) pkgmap[mykey]["protected"].add( slotmap[myslot][counter]) #be pretty and get them in order of merge: for ckey in counterkeys: mypkg = slotmap[myslot][ckey] if mypkg not in all_selected: pkgmap[mykey]["selected"].add(mypkg) all_selected.add(mypkg) # ok, now the last-merged package # is protected, and the rest are selected numselected = len(all_selected) if global_unmerge and not numselected: portage.writemsg_stdout( "\n>>> No outdated packages were found on your system.\n") return 0 if not numselected: portage.writemsg_stdout( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 0 finally: if vdb_lock: vartree.dbapi.flush_cache() portage.locks.unlockdir(vdb_lock) from portage.sets.base import EditablePackageSet # generate a list of package sets that are directly or indirectly listed in "selected", # as there is no persistent list of "installed" sets installed_sets = ["selected"] stop = False pos = 0 while not stop: stop = True pos = len(installed_sets) for s in installed_sets[pos - 1:]: if s not in sets: continue candidates = [ x[len(SETPREFIX):] for x in sets[s].getNonAtoms() if x.startswith(SETPREFIX) ] if candidates: stop = False installed_sets += candidates installed_sets = [ x for x in installed_sets if x not in root_config.setconfig.active ] del stop, pos # we don't want to unmerge packages that are still listed in user-editable package sets # listed in "world" as they would be remerged on the next update of "world" or the # relevant package sets. unknown_sets = set() for cp in range(len(pkgmap)): for cpv in pkgmap[cp]["selected"].copy(): try: pkg = _pkg(cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if unmerge_action != "clean" and \ root_config.root == "/" and \ portage.match_from_list( portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): msg = ("Not unmerging package %s since there is no valid " + \ "reason for portage to unmerge itself.") % (pkg.cpv,) for line in textwrap.wrap(msg, 75): out.eerror(line) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) continue parents = [] for s in installed_sets: # skip sets that the user requested to unmerge, and skip world # user-selected set, since the package will be removed from # that set later on. if s in root_config.setconfig.active or s == "selected": continue if s not in sets: if s in unknown_sets: continue unknown_sets.add(s) out = portage.output.EOutput() out.eerror(("Unknown set '@%s' in %s%s") % \ (s, root_config.root, portage.const.WORLD_SETS_FILE)) continue # only check instances of EditablePackageSet as other classes are generally used for # special purposes and can be ignored here (and are usually generated dynamically, so the # user can't do much about them anyway) if isinstance(sets[s], EditablePackageSet): # This is derived from a snippet of code in the # depgraph._iter_atoms_for_pkg() method. for atom in sets[s].iterAtomsForPackage(pkg): inst_matches = vartree.dbapi.match(atom) inst_matches.reverse() # descending order higher_slot = None for inst_cpv in inst_matches: try: inst_pkg = _pkg(inst_cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if inst_pkg.cp != atom.cp: continue if pkg >= inst_pkg: # This is descending order, and we're not # interested in any versions <= pkg given. break if pkg.slot_atom != inst_pkg.slot_atom: higher_slot = inst_pkg break if higher_slot is None: parents.append(s) break if parents: #print colorize("WARN", "Package %s is going to be unmerged," % cpv) #print colorize("WARN", "but still listed in the following package sets:") #print " %s\n" % ", ".join(parents) print( colorize("WARN", "Not unmerging package %s as it is" % cpv)) print( colorize( "WARN", "still referenced by the following package sets:")) print(" %s\n" % ", ".join(parents)) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) del installed_sets numselected = len(all_selected) if not numselected: writemsg_level( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 0 # Unmerge order only matters in some cases if not ordered: unordered = {} for d in pkgmap: selected = d["selected"] if not selected: continue cp = portage.cpv_getkey(next(iter(selected))) cp_dict = unordered.get(cp) if cp_dict is None: cp_dict = {} unordered[cp] = cp_dict for k in d: cp_dict[k] = set() for k, v in d.items(): cp_dict[k].update(v) pkgmap = [unordered[cp] for cp in sorted(unordered)] for x in range(len(pkgmap)): selected = pkgmap[x]["selected"] if not selected: continue for mytype, mylist in pkgmap[x].items(): if mytype == "selected": continue mylist.difference_update(all_selected) cp = portage.cpv_getkey(next(iter(selected))) for y in localtree.dep_match(cp): if y not in pkgmap[x]["omitted"] and \ y not in pkgmap[x]["selected"] and \ y not in pkgmap[x]["protected"] and \ y not in all_selected: pkgmap[x]["omitted"].add(y) if global_unmerge and not pkgmap[x]["selected"]: #avoid cluttering the preview printout with stuff that isn't getting unmerged continue if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist: writemsg_level(colorize("BAD","\a\n\n!!! " + \ "'%s' is part of your system profile.\n" % cp), level=logging.WARNING, noiselevel=-1) writemsg_level(colorize("WARN","\a!!! Unmerging it may " + \ "be damaging to your system.\n\n"), level=logging.WARNING, noiselevel=-1) if clean_delay and "--pretend" not in myopts and "--ask" not in myopts: countdown(int(settings["EMERGE_WARNING_DELAY"]), colorize("UNMERGE_WARN", "Press Ctrl-C to Stop")) if not quiet: writemsg_level("\n %s\n" % (bold(cp), ), noiselevel=-1) else: writemsg_level(bold(cp) + ": ", noiselevel=-1) for mytype in ["selected", "protected", "omitted"]: if not quiet: writemsg_level((mytype + ": ").rjust(14), noiselevel=-1) if pkgmap[x][mytype]: sorted_pkgs = [ portage.catpkgsplit(mypkg)[1:] for mypkg in pkgmap[x][mytype] ] sorted_pkgs.sort(key=cmp_sort_key(portage.pkgcmp)) for pn, ver, rev in sorted_pkgs: if rev == "r0": myversion = ver else: myversion = ver + "-" + rev if mytype == "selected": writemsg_level(colorize("UNMERGE_WARN", myversion + " "), noiselevel=-1) else: writemsg_level(colorize("GOOD", myversion + " "), noiselevel=-1) else: writemsg_level("none ", noiselevel=-1) if not quiet: writemsg_level("\n", noiselevel=-1) if quiet: writemsg_level("\n", noiselevel=-1) writemsg_level("\n>>> " + colorize("UNMERGE_WARN", "'Selected'") + \ " packages are slated for removal.\n") writemsg_level(">>> " + colorize("GOOD", "'Protected'") + \ " and " + colorize("GOOD", "'omitted'") + \ " packages will not be removed.\n\n") if "--pretend" in myopts: #we're done... return return 0 if "--ask" in myopts: if userquery("Would you like to unmerge these packages?", enter_invalid) == "No": # enter pretend mode for correct formatting of results myopts["--pretend"] = True print() print("Quitting.") print() return 0 #the real unmerging begins, after a short delay.... if clean_delay and not autoclean: countdown(int(settings["CLEAN_DELAY"]), ">>> Unmerging") for x in range(len(pkgmap)): for y in pkgmap[x]["selected"]: writemsg_level(">>> Unmerging " + y + "...\n", noiselevel=-1) emergelog(xterm_titles, "=== Unmerging... (" + y + ")") mysplit = y.split("/") #unmerge... retval = portage.unmerge(mysplit[0], mysplit[1], settings["ROOT"], mysettings, unmerge_action not in ["clean", "prune"], vartree=vartree, ldpath_mtimes=ldpath_mtimes, scheduler=scheduler) if retval != os.EX_OK: emergelog(xterm_titles, " !!! unmerge FAILURE: " + y) if raise_on_error: raise UninstallFailure(retval) sys.exit(retval) else: if clean_world and hasattr(sets["selected"], "cleanPackage")\ and hasattr(sets["selected"], "lock"): sets["selected"].lock() if hasattr(sets["selected"], "load"): sets["selected"].load() sets["selected"].cleanPackage(vartree.dbapi, y) sets["selected"].unlock() emergelog(xterm_titles, " >>> unmerge success: " + y) if clean_world and hasattr(sets["selected"], "remove")\ and hasattr(sets["selected"], "lock"): sets["selected"].lock() # load is called inside remove() for s in root_config.setconfig.active: sets["selected"].remove(SETPREFIX + s) sets["selected"].unlock() return 1
def bestVersion (versions): bestver = portage.best (["foo-" + version for version in versions]) return bestver[4:]
def output(self): """Outputs the results of the search.""" msg = [] msg.append("\b\b \n[ Results for search key : " + \ bold(self.searchkey) + " ]\n") msg.append("[ Applications found : " + \ bold(str(self.mlen)) + " ]\n\n") vardb = self.vartree.dbapi for mtype in self.matches: for match,masked in self.matches[mtype]: full_package = None if mtype == "pkg": catpack = match full_package = self.portdb.xmatch( "bestmatch-visible", match) if not full_package: #no match found; we don't want to query description masked=1 full_package = portage.best( self.portdb.xmatch("match-all",match)) elif mtype == "desc": full_package = match match = portage.cpv_getkey(match) elif mtype == "set": msg.append(green("*") + " " + bold(match) + "\n") if self.verbose: msg.append(" " + darkgreen("Description:") + \ " " + \ self.sdict[match].getMetadata("DESCRIPTION") \ + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1) if full_package: try: desc, homepage, license = self.portdb.aux_get( full_package, ["DESCRIPTION","HOMEPAGE","LICENSE"]) except KeyError: msg.append("emerge: search: aux_get() failed, skipping\n") continue if masked: msg.append(green("*") + " " + \ white(match) + " " + red("[ Masked ]") + "\n") else: msg.append(green("*") + " " + bold(match) + "\n") myversion = self.getVersion(full_package, search.VERSION_RELEASE) mysum = [0,0] file_size_str = None mycat = match.split("/")[0] mypkg = match.split("/")[1] mycpv = match + "-" + myversion myebuild = self.portdb.findname(mycpv) if myebuild: pkgdir = os.path.dirname(myebuild) from portage import manifest mf = manifest.Manifest( pkgdir, self.settings["DISTDIR"]) try: uri_map = self.portdb.getFetchMap(mycpv) except portage.exception.InvalidDependString as e: file_size_str = "Unknown (%s)" % (e,) del e else: try: mysum[0] = mf.getDistfilesSize(uri_map) except KeyError as e: file_size_str = "Unknown (missing " + \ "digest for %s)" % (e,) del e available = False for db in self._dbs: if db is not vardb and \ db.cpv_exists(mycpv): available = True if not myebuild and hasattr(db, "bintree"): myebuild = db.bintree.getname(mycpv) try: mysum[0] = os.stat(myebuild).st_size except OSError: myebuild = None break if myebuild and file_size_str is None: mystr = str(mysum[0] // 1024) mycount = len(mystr) while (mycount > 3): mycount -= 3 mystr = mystr[:mycount] + "," + mystr[mycount:] file_size_str = mystr + " kB" if self.verbose: if available: msg.append(" %s %s\n" % \ (darkgreen("Latest version available:"), myversion)) msg.append(" %s\n" % \ self.getInstallationStatus(mycat+'/'+mypkg)) if myebuild: msg.append(" %s %s\n" % \ (darkgreen("Size of files:"), file_size_str)) msg.append(" " + darkgreen("Homepage:") + \ " " + homepage + "\n") msg.append(" " + darkgreen("Description:") \ + " " + desc + "\n") msg.append(" " + darkgreen("License:") + \ " " + license + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1)
def unmerge(root_config, myopts, unmerge_action, unmerge_files, ldpath_mtimes, autoclean=0, clean_world=1, clean_delay=1, ordered=0, raise_on_error=0, scheduler=None, writemsg_level=portage.util.writemsg_level): if clean_world: clean_world = myopts.get('--deselect') != 'n' quiet = "--quiet" in myopts enter_invalid = '--ask-enter-invalid' in myopts settings = root_config.settings sets = root_config.sets vartree = root_config.trees["vartree"] candidate_catpkgs=[] global_unmerge=0 xterm_titles = "notitles" not in settings.features out = portage.output.EOutput() pkg_cache = {} db_keys = list(vartree.dbapi._aux_cache_keys) def _pkg(cpv): pkg = pkg_cache.get(cpv) if pkg is None: pkg = Package(built=True, cpv=cpv, installed=True, metadata=zip(db_keys, vartree.dbapi.aux_get(cpv, db_keys)), operation="uninstall", root_config=root_config, type_name="installed") pkg_cache[cpv] = pkg return pkg vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH) try: # At least the parent needs to exist for the lock file. portage.util.ensure_dirs(vdb_path) except portage.exception.PortageException: pass vdb_lock = None try: if os.access(vdb_path, os.W_OK): vdb_lock = portage.locks.lockdir(vdb_path) realsyslist = sets["system"].getAtoms() syslist = [] for x in realsyslist: mycp = portage.dep_getkey(x) if mycp in settings.getvirtuals(): providers = [] for provider in settings.getvirtuals()[mycp]: if vartree.dbapi.match(provider): providers.append(provider) if len(providers) == 1: syslist.extend(providers) else: syslist.append(mycp) mysettings = portage.config(clone=settings) if not unmerge_files: if unmerge_action == "unmerge": print() print(bold("emerge unmerge") + " can only be used with specific package names") print() return 0 else: global_unmerge = 1 localtree = vartree # process all arguments and add all # valid db entries to candidate_catpkgs if global_unmerge: if not unmerge_files: candidate_catpkgs.extend(vartree.dbapi.cp_all()) else: #we've got command-line arguments if not unmerge_files: print("\nNo packages to unmerge have been provided.\n") return 0 for x in unmerge_files: arg_parts = x.split('/') if x[0] not in [".","/"] and \ arg_parts[-1][-7:] != ".ebuild": #possible cat/pkg or dep; treat as such candidate_catpkgs.append(x) elif unmerge_action in ["prune","clean"]: print("\n!!! Prune and clean do not accept individual" + \ " ebuilds as arguments;\n skipping.\n") continue else: # it appears that the user is specifying an installed # ebuild and we're in "unmerge" mode, so it's ok. if not os.path.exists(x): print("\n!!! The path '"+x+"' doesn't exist.\n") return 0 absx = os.path.abspath(x) sp_absx = absx.split("/") if sp_absx[-1][-7:] == ".ebuild": del sp_absx[-1] absx = "/".join(sp_absx) sp_absx_len = len(sp_absx) vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH) vdb_len = len(vdb_path) sp_vdb = vdb_path.split("/") sp_vdb_len = len(sp_vdb) if not os.path.exists(absx+"/CONTENTS"): print("!!! Not a valid db dir: "+str(absx)) return 0 if sp_absx_len <= sp_vdb_len: # The Path is shorter... so it can't be inside the vdb. print(sp_absx) print(absx) print("\n!!!",x,"cannot be inside "+ \ vdb_path+"; aborting.\n") return 0 for idx in range(0,sp_vdb_len): if idx >= sp_absx_len or sp_vdb[idx] != sp_absx[idx]: print(sp_absx) print(absx) print("\n!!!", x, "is not inside "+\ vdb_path+"; aborting.\n") return 0 print("="+"/".join(sp_absx[sp_vdb_len:])) candidate_catpkgs.append( "="+"/".join(sp_absx[sp_vdb_len:])) newline="" if (not "--quiet" in myopts): newline="\n" if settings["ROOT"] != "/": writemsg_level(darkgreen(newline+ \ ">>> Using system located in ROOT tree %s\n" % \ settings["ROOT"])) if (("--pretend" in myopts) or ("--ask" in myopts)) and \ not ("--quiet" in myopts): writemsg_level(darkgreen(newline+\ ">>> These are the packages that would be unmerged:\n")) # Preservation of order is required for --depclean and --prune so # that dependencies are respected. Use all_selected to eliminate # duplicate packages since the same package may be selected by # multiple atoms. pkgmap = [] all_selected = set() for x in candidate_catpkgs: # cycle through all our candidate deps and determine # what will and will not get unmerged try: mymatch = vartree.dbapi.match(x) except portage.exception.AmbiguousPackageName as errpkgs: print("\n\n!!! The short ebuild name \"" + \ x + "\" is ambiguous. Please specify") print("!!! one of the following fully-qualified " + \ "ebuild names instead:\n") for i in errpkgs[0]: print(" " + green(i)) print() sys.exit(1) if not mymatch and x[0] not in "<>=~": mymatch = localtree.dep_match(x) if not mymatch: portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ (x, unmerge_action), noiselevel=-1) continue pkgmap.append( {"protected": set(), "selected": set(), "omitted": set()}) mykey = len(pkgmap) - 1 if unmerge_action=="unmerge": for y in mymatch: if y not in all_selected: pkgmap[mykey]["selected"].add(y) all_selected.add(y) elif unmerge_action == "prune": if len(mymatch) == 1: continue best_version = mymatch[0] best_slot = vartree.getslot(best_version) best_counter = vartree.dbapi.cpv_counter(best_version) for mypkg in mymatch[1:]: myslot = vartree.getslot(mypkg) mycounter = vartree.dbapi.cpv_counter(mypkg) if (myslot == best_slot and mycounter > best_counter) or \ mypkg == portage.best([mypkg, best_version]): if myslot == best_slot: if mycounter < best_counter: # On slot collision, keep the one with the # highest counter since it is the most # recently installed. continue best_version = mypkg best_slot = myslot best_counter = mycounter pkgmap[mykey]["protected"].add(best_version) pkgmap[mykey]["selected"].update(mypkg for mypkg in mymatch \ if mypkg != best_version and mypkg not in all_selected) all_selected.update(pkgmap[mykey]["selected"]) else: # unmerge_action == "clean" slotmap={} for mypkg in mymatch: if unmerge_action == "clean": myslot = localtree.getslot(mypkg) else: # since we're pruning, we don't care about slots # and put all the pkgs in together myslot = 0 if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)] = mypkg for mypkg in vartree.dbapi.cp_list( portage.cpv_getkey(mymatch[0])): myslot = vartree.getslot(mypkg) if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][vartree.dbapi.cpv_counter(mypkg)] = mypkg for myslot in slotmap: counterkeys = list(slotmap[myslot]) if not counterkeys: continue counterkeys.sort() pkgmap[mykey]["protected"].add( slotmap[myslot][counterkeys[-1]]) del counterkeys[-1] for counter in counterkeys[:]: mypkg = slotmap[myslot][counter] if mypkg not in mymatch: counterkeys.remove(counter) pkgmap[mykey]["protected"].add( slotmap[myslot][counter]) #be pretty and get them in order of merge: for ckey in counterkeys: mypkg = slotmap[myslot][ckey] if mypkg not in all_selected: pkgmap[mykey]["selected"].add(mypkg) all_selected.add(mypkg) # ok, now the last-merged package # is protected, and the rest are selected numselected = len(all_selected) if global_unmerge and not numselected: portage.writemsg_stdout("\n>>> No outdated packages were found on your system.\n") return 0 if not numselected: portage.writemsg_stdout( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 0 finally: if vdb_lock: vartree.dbapi.flush_cache() portage.locks.unlockdir(vdb_lock) from portage._sets.base import EditablePackageSet # generate a list of package sets that are directly or indirectly listed in "selected", # as there is no persistent list of "installed" sets installed_sets = ["selected"] stop = False pos = 0 while not stop: stop = True pos = len(installed_sets) for s in installed_sets[pos - 1:]: if s not in sets: continue candidates = [x[len(SETPREFIX):] for x in sets[s].getNonAtoms() if x.startswith(SETPREFIX)] if candidates: stop = False installed_sets += candidates installed_sets = [x for x in installed_sets if x not in root_config.setconfig.active] del stop, pos # we don't want to unmerge packages that are still listed in user-editable package sets # listed in "world" as they would be remerged on the next update of "world" or the # relevant package sets. unknown_sets = set() for cp in range(len(pkgmap)): for cpv in pkgmap[cp]["selected"].copy(): try: pkg = _pkg(cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if unmerge_action != "clean" and \ root_config.root == "/" and \ portage.match_from_list( portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): msg = ("Not unmerging package %s since there is no valid " + \ "reason for portage to unmerge itself.") % (pkg.cpv,) for line in textwrap.wrap(msg, 75): out.eerror(line) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) continue parents = [] for s in installed_sets: # skip sets that the user requested to unmerge, and skip world # user-selected set, since the package will be removed from # that set later on. if s in root_config.setconfig.active or s == "selected": continue if s not in sets: if s in unknown_sets: continue unknown_sets.add(s) out = portage.output.EOutput() out.eerror(("Unknown set '@%s' in %s%s") % \ (s, root_config.root, portage.const.WORLD_SETS_FILE)) continue # only check instances of EditablePackageSet as other classes are generally used for # special purposes and can be ignored here (and are usually generated dynamically, so the # user can't do much about them anyway) if isinstance(sets[s], EditablePackageSet): # This is derived from a snippet of code in the # depgraph._iter_atoms_for_pkg() method. for atom in sets[s].iterAtomsForPackage(pkg): inst_matches = vartree.dbapi.match(atom) inst_matches.reverse() # descending order higher_slot = None for inst_cpv in inst_matches: try: inst_pkg = _pkg(inst_cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if inst_pkg.cp != atom.cp: continue if pkg >= inst_pkg: # This is descending order, and we're not # interested in any versions <= pkg given. break if pkg.slot_atom != inst_pkg.slot_atom: higher_slot = inst_pkg break if higher_slot is None: parents.append(s) break if parents: print(colorize("WARN", "Package %s is going to be unmerged," % cpv)) print(colorize("WARN", "but still listed in the following package sets:")) print(" %s\n" % ", ".join(parents)) del installed_sets numselected = len(all_selected) if not numselected: writemsg_level( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 0 # Unmerge order only matters in some cases if not ordered: unordered = {} for d in pkgmap: selected = d["selected"] if not selected: continue cp = portage.cpv_getkey(next(iter(selected))) cp_dict = unordered.get(cp) if cp_dict is None: cp_dict = {} unordered[cp] = cp_dict for k in d: cp_dict[k] = set() for k, v in d.items(): cp_dict[k].update(v) pkgmap = [unordered[cp] for cp in sorted(unordered)] for x in range(len(pkgmap)): selected = pkgmap[x]["selected"] if not selected: continue for mytype, mylist in pkgmap[x].items(): if mytype == "selected": continue mylist.difference_update(all_selected) cp = portage.cpv_getkey(next(iter(selected))) for y in localtree.dep_match(cp): if y not in pkgmap[x]["omitted"] and \ y not in pkgmap[x]["selected"] and \ y not in pkgmap[x]["protected"] and \ y not in all_selected: pkgmap[x]["omitted"].add(y) if global_unmerge and not pkgmap[x]["selected"]: #avoid cluttering the preview printout with stuff that isn't getting unmerged continue if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist: writemsg_level(colorize("BAD","\a\n\n!!! " + \ "'%s' is part of your system profile.\n" % cp), level=logging.WARNING, noiselevel=-1) writemsg_level(colorize("WARN","\a!!! Unmerging it may " + \ "be damaging to your system.\n\n"), level=logging.WARNING, noiselevel=-1) if clean_delay and "--pretend" not in myopts and "--ask" not in myopts: countdown(int(settings["EMERGE_WARNING_DELAY"]), colorize("UNMERGE_WARN", "Press Ctrl-C to Stop")) if not quiet: writemsg_level("\n %s\n" % (bold(cp),), noiselevel=-1) else: writemsg_level(bold(cp) + ": ", noiselevel=-1) for mytype in ["selected","protected","omitted"]: if not quiet: writemsg_level((mytype + ": ").rjust(14), noiselevel=-1) if pkgmap[x][mytype]: sorted_pkgs = [portage.catpkgsplit(mypkg)[1:] for mypkg in pkgmap[x][mytype]] sorted_pkgs.sort(key=cmp_sort_key(portage.pkgcmp)) for pn, ver, rev in sorted_pkgs: if rev == "r0": myversion = ver else: myversion = ver + "-" + rev if mytype == "selected": writemsg_level( colorize("UNMERGE_WARN", myversion + " "), noiselevel=-1) else: writemsg_level( colorize("GOOD", myversion + " "), noiselevel=-1) else: writemsg_level("none ", noiselevel=-1) if not quiet: writemsg_level("\n", noiselevel=-1) if quiet: writemsg_level("\n", noiselevel=-1) writemsg_level("\nAll selected packages: %s\n" % " ".join(all_selected), noiselevel=-1) writemsg_level("\n>>> " + colorize("UNMERGE_WARN", "'Selected'") + \ " packages are slated for removal.\n") writemsg_level(">>> " + colorize("GOOD", "'Protected'") + \ " and " + colorize("GOOD", "'omitted'") + \ " packages will not be removed.\n\n") if "--pretend" in myopts: #we're done... return return 0 if "--ask" in myopts: if userquery("Would you like to unmerge these packages?", enter_invalid) == "No": # enter pretend mode for correct formatting of results myopts["--pretend"] = True print() print("Quitting.") print() return 0 #the real unmerging begins, after a short delay.... if clean_delay and not autoclean: countdown(int(settings["CLEAN_DELAY"]), ">>> Unmerging") for x in range(len(pkgmap)): for y in pkgmap[x]["selected"]: writemsg_level(">>> Unmerging "+y+"...\n", noiselevel=-1) emergelog(xterm_titles, "=== Unmerging... ("+y+")") mysplit = y.split("/") #unmerge... retval = portage.unmerge(mysplit[0], mysplit[1], settings["ROOT"], mysettings, unmerge_action not in ["clean","prune"], vartree=vartree, ldpath_mtimes=ldpath_mtimes, scheduler=scheduler) if retval != os.EX_OK: emergelog(xterm_titles, " !!! unmerge FAILURE: "+y) if raise_on_error: raise UninstallFailure(retval) sys.exit(retval) else: if clean_world and hasattr(sets["selected"], "cleanPackage")\ and hasattr(sets["selected"], "lock"): sets["selected"].lock() if hasattr(sets["selected"], "load"): sets["selected"].load() sets["selected"].cleanPackage(vartree.dbapi, y) sets["selected"].unlock() emergelog(xterm_titles, " >>> unmerge success: "+y) if clean_world and hasattr(sets["selected"], "remove")\ and hasattr(sets["selected"], "lock"): sets["selected"].lock() # load is called inside remove() for s in root_config.setconfig.active: sets["selected"].remove(SETPREFIX + s) sets["selected"].unlock() return 1
def execute(self,searchkey): """Performs the search for the supplied search key""" match_category = 0 self.searchkey=searchkey self.packagematches = [] if self.searchdesc: self.searchdesc=1 self.matches = {"pkg":[], "desc":[], "set":[]} else: self.searchdesc=0 self.matches = {"pkg":[], "set":[]} print("Searching... ", end=' ') regexsearch = False if self.searchkey.startswith('%'): regexsearch = True self.searchkey = self.searchkey[1:] if self.searchkey.startswith('@'): match_category = 1 self.searchkey = self.searchkey[1:] if regexsearch: self.searchre=re.compile(self.searchkey,re.I) else: self.searchre=re.compile(re.escape(self.searchkey), re.I) for package in self.portdb.cp_all(): self._spinner_update() if match_category: match_string = package[:] else: match_string = package.split("/")[-1] masked=0 if self.searchre.search(match_string): if not self.portdb.xmatch("match-visible", package): masked=1 self.matches["pkg"].append([package,masked]) elif self.searchdesc: # DESCRIPTION searching full_package = self.portdb.xmatch("bestmatch-visible", package) if not full_package: #no match found; we don't want to query description full_package = portage.best( self.portdb.xmatch("match-all", package)) if not full_package: continue else: masked=1 try: full_desc = self.portdb.aux_get( full_package, ["DESCRIPTION"])[0] except KeyError: print("emerge: search: aux_get() failed, skipping") continue if self.searchre.search(full_desc): self.matches["desc"].append([full_package,masked]) self.sdict = self.setconfig.getSets() for setname in self.sdict: self._spinner_update() if match_category: match_string = setname else: match_string = setname.split("/")[-1] if self.searchre.search(match_string): self.matches["set"].append([setname, False]) elif self.searchdesc: if self.searchre.search( self.sdict[setname].getMetadata("DESCRIPTION")): self.matches["set"].append([setname, False]) self.mlen=0 for mtype in self.matches: self.matches[mtype].sort() self.mlen += len(self.matches[mtype])
def _new_scan(self): """ Internal scan method, executes the actual scan and retuns a raw list of AntiMatterPackage objects. """ vardb, portdb = self._get_dbs() new_days_old_secs = self._nsargs.new_days_old * 3600 * 24 not_installed = self._nsargs.not_installed result = [] cp_all = portdb.cp_all() cp_all.sort() root = portdb.porttree_root for count, package in enumerate(cp_all): count_str = "[%s of %s]" % ( count, len(cp_all),) if self._nsargs.verbose: print_warning("%s :: %s" % (count_str, package), back=True) if not not_installed: cp_dir = os.path.join(root, package) try: mtime = os.path.getmtime(cp_dir) except (OSError, IOError): mtime = 0.0 if abs(time.time() - mtime) >= new_days_old_secs: # not new enough continue best_installed = portage.best(vardb.match(package)) if best_installed: # package key is already installed, ignore continue best_visible = portage.best(portdb.match(package)) if not best_visible: # wtf? package masked? continue try: slot, repo = portdb.aux_get( best_visible, ["SLOT", "repository"]) except KeyError: # portage is scrappy continue atom = portage.dep.Atom( "=%s:%s::%s" % (best_visible, slot, repo), allow_wildcard=True, allow_repo=True) pkg = AntiMatterPackage( vardb, portdb, None, atom, 1) result.append(pkg) if cp_all and self._nsargs.verbose: print_generic("") return result
def updatedb(config=None): if not os.access(config['esearchdbdir'], os.W_OK): print( yellow("Warning:"), "You do not have sufficient permissions to save the index file in:", green(config['esearchdbdir']), file=config['stderr']) return False if config['verbose'] != -1 and "ACCEPT_KEYWORDS" in environ: print(yellow("Warning:"), "You have set ACCEPT_KEYWORDS in environment, this will result", file=config['stdout']) print(" in a modified index file", file=config['stdout']) ebuilds = portage.portdb.cp_all() numebuilds = len(ebuilds) if exists(config['tmpfile']): error("there is probably another eupdatedb running already.\n" + " If you're sure there is no other process, remove", config['tmpfile'], fatal=False) return False try: dbfd = open(config['tmpfile'], O_CREAT | O_EXCL | O_WRONLY, 0o600) except OSError: error("Failed to open temporary file.", fatal=False) return False dbfile = fdopen(dbfd, "w") dbfile.write("dbversion = " + str(config['needdbversion']) + "\n") dbfile.write("db = (\n") if not config['verbose']: config['stdout'].write(green(" * ") + "indexing: ") config['stdout'].flush() nr = 0 nrchars = 0 elif config['verbose'] == 1: lastcat = False cattime = time() try: for pkg in ebuilds: masked = False if not config['verbose']: nr += 1 s = str(numebuilds - nr) + " ebuilds to go" config['stdout'].write((nrchars * "\b \b") + s) config['stdout'].flush() nrchars = len(s) pkgv = portage.portdb.xmatch("bestmatch-visible", pkg) if not pkgv: pkgv = portage.best(portage.portdb.xmatch("match-all", pkg)) if not pkgv: continue masked = True if len(pkgv) > 1: try: homepage, description, _license = portage.portdb.aux_get( pkgv, ["HOMEPAGE", "DESCRIPTION", "LICENSE"]) except KeyError: homepage, description, _license = "", "", "" pass if len(pkgv) > 1: filesize = getfetchsize(pkgv) else: filesize = '0' (curcat, pkgname) = pkg.split("/") if config['verbose'] == 1 and curcat != lastcat: if lastcat != False: print(duration(cattime), file=config['stdout']) print(bold(" * " + curcat) + ":", end=' ', file=config['stdout']) cattime = time() lastcat = curcat installed = pkg_version(VARTREE.dep_bestmatch(pkg)) if installed: installed = str(installed) dbfile.write( repr((str(pkgname), str(pkg), masked, str(pkg_version(pkgv)), installed, str(filesize), str(homepage), str(description), str(_license))) + str(",\n")) except KeyboardInterrupt: dbfile.close() unlink(config['tmpfile']) print("", file=config['stdout']) return False print("", file=config['stdout']) dbfile.write(")") dbfile.close() copyfile(config['tmpfile'], os.path.join(config['esearchdbdir'], config['esearchdbfile'])) unlink(config['tmpfile']) sys.path.insert(0, config['esearchdbdir']) import esearchdb # import the file, to generate pyc if exists( os.path.join(config['esearchdbdir'], config['esearchdbfile']) + "c"): config['esearchdbfile'] += "c" print(green(" *"), "esearch-index generated in", duration(start), file=config['stdout']) print(green(" *"), "indexed", bold(str(numebuilds)), "ebuilds", file=config['stdout']) print(green(" *"), "size of esearch-index:", bold( str( int( stat( os.path.join(config['esearchdbdir'], config['esearchdbfile']))[6] / 1024)) + " kB"), file=config['stdout']) return True
def _unmerge_display(root_config, myopts, unmerge_action, unmerge_files, clean_delay=1, ordered=0, writemsg_level=portage.util.writemsg_level): """ Returns a tuple of (returncode, pkgmap) where returncode is os.EX_OK if no errors occur, and 1 otherwise. """ quiet = "--quiet" in myopts settings = root_config.settings sets = root_config.sets vartree = root_config.trees["vartree"] candidate_catpkgs=[] global_unmerge=0 out = portage.output.EOutput() pkg_cache = {} db_keys = list(vartree.dbapi._aux_cache_keys) def _pkg(cpv): pkg = pkg_cache.get(cpv) if pkg is None: pkg = Package(built=True, cpv=cpv, installed=True, metadata=zip(db_keys, vartree.dbapi.aux_get(cpv, db_keys)), operation="uninstall", root_config=root_config, type_name="installed") pkg_cache[cpv] = pkg return pkg vdb_path = os.path.join(settings["EROOT"], portage.VDB_PATH) try: # At least the parent needs to exist for the lock file. portage.util.ensure_dirs(vdb_path) except portage.exception.PortageException: pass vdb_lock = None try: if os.access(vdb_path, os.W_OK): vartree.dbapi.lock() vdb_lock = True realsyslist = [] sys_virt_map = {} for x in sets["system"].getAtoms(): for atom in expand_new_virt(vartree.dbapi, x): if not atom.blocker: realsyslist.append(atom) if atom.cp != x.cp: sys_virt_map[atom.cp] = x.cp syslist = [] for x in realsyslist: mycp = x.cp # Since Gentoo stopped using old-style virtuals in # 2011, typically it's possible to avoid getvirtuals() # calls entirely. It will not be triggered here by # new-style virtuals since those are expanded to # non-virtual atoms above by expand_new_virt(). if mycp.startswith("virtual/") and \ mycp in settings.getvirtuals(): providers = [] for provider in settings.getvirtuals()[mycp]: if vartree.dbapi.match(provider): providers.append(provider) if len(providers) == 1: syslist.extend(providers) else: syslist.append(mycp) syslist = frozenset(syslist) if not unmerge_files: if unmerge_action in ["rage-clean", "unmerge"]: print() print(bold("emerge %s" % unmerge_action) + " can only be used with specific package names") print() return 1, {} else: global_unmerge = 1 localtree = vartree # process all arguments and add all # valid db entries to candidate_catpkgs if global_unmerge: if not unmerge_files: candidate_catpkgs.extend(vartree.dbapi.cp_all()) else: #we've got command-line arguments if not unmerge_files: print("\nNo packages to %s have been provided.\n" % unmerge_action) return 1, {} for x in unmerge_files: arg_parts = x.split('/') if x[0] not in [".","/"] and \ arg_parts[-1][-7:] != ".ebuild": #possible cat/pkg or dep; treat as such candidate_catpkgs.append(x) elif unmerge_action in ["prune","clean"]: print("\n!!! Prune and clean do not accept individual" + \ " ebuilds as arguments;\n skipping.\n") continue else: # it appears that the user is specifying an installed # ebuild and we're in "unmerge" mode, so it's ok. if not os.path.exists(x): print("\n!!! The path '"+x+"' doesn't exist.\n") return 1, {} absx = os.path.abspath(x) sp_absx = absx.split("/") if sp_absx[-1][-7:] == ".ebuild": del sp_absx[-1] absx = "/".join(sp_absx) sp_absx_len = len(sp_absx) vdb_path = os.path.join(settings["EROOT"], portage.VDB_PATH) sp_vdb = vdb_path.split("/") sp_vdb_len = len(sp_vdb) if not os.path.exists(absx+"/CONTENTS"): print("!!! Not a valid db dir: "+str(absx)) return 1, {} if sp_absx_len <= sp_vdb_len: # The Path is shorter... so it can't be inside the vdb. print(sp_absx) print(absx) print("\n!!!",x,"cannot be inside "+ \ vdb_path+"; aborting.\n") return 1, {} for idx in range(0,sp_vdb_len): if idx >= sp_absx_len or sp_vdb[idx] != sp_absx[idx]: print(sp_absx) print(absx) print("\n!!!", x, "is not inside "+\ vdb_path+"; aborting.\n") return 1, {} print("="+"/".join(sp_absx[sp_vdb_len:])) candidate_catpkgs.append( "="+"/".join(sp_absx[sp_vdb_len:])) newline="" if (not "--quiet" in myopts): newline="\n" if settings["ROOT"] != "/": writemsg_level(darkgreen(newline+ \ ">>> Using system located in ROOT tree %s\n" % \ settings["ROOT"])) if (("--pretend" in myopts) or ("--ask" in myopts)) and \ not ("--quiet" in myopts): writemsg_level(darkgreen(newline+\ ">>> These are the packages that would be unmerged:\n")) # Preservation of order is required for --depclean and --prune so # that dependencies are respected. Use all_selected to eliminate # duplicate packages since the same package may be selected by # multiple atoms. pkgmap = [] all_selected = set() for x in candidate_catpkgs: # cycle through all our candidate deps and determine # what will and will not get unmerged try: mymatch = vartree.dbapi.match(x) except portage.exception.AmbiguousPackageName as errpkgs: print("\n\n!!! The short ebuild name \"" + \ x + "\" is ambiguous. Please specify") print("!!! one of the following fully-qualified " + \ "ebuild names instead:\n") for i in errpkgs[0]: print(" " + green(i)) print() sys.exit(1) if not mymatch and x[0] not in "<>=~": mymatch = localtree.dep_match(x) if not mymatch: portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \ (x.replace("null/", ""), unmerge_action), noiselevel=-1) continue pkgmap.append( {"protected": set(), "selected": set(), "omitted": set()}) mykey = len(pkgmap) - 1 if unmerge_action in ["rage-clean", "unmerge"]: for y in mymatch: if y not in all_selected: pkgmap[mykey]["selected"].add(y) all_selected.add(y) elif unmerge_action == "prune": if len(mymatch) == 1: continue best_version = mymatch[0] best_slot = vartree.getslot(best_version) best_counter = vartree.dbapi.cpv_counter(best_version) for mypkg in mymatch[1:]: myslot = vartree.getslot(mypkg) mycounter = vartree.dbapi.cpv_counter(mypkg) if (myslot == best_slot and mycounter > best_counter) or \ mypkg == portage.best([mypkg, best_version]): if myslot == best_slot: if mycounter < best_counter: # On slot collision, keep the one with the # highest counter since it is the most # recently installed. continue best_version = mypkg best_slot = myslot best_counter = mycounter pkgmap[mykey]["protected"].add(best_version) pkgmap[mykey]["selected"].update(mypkg for mypkg in mymatch \ if mypkg != best_version and mypkg not in all_selected) all_selected.update(pkgmap[mykey]["selected"]) else: # unmerge_action == "clean" slotmap={} for mypkg in mymatch: if unmerge_action == "clean": myslot = localtree.getslot(mypkg) else: # since we're pruning, we don't care about slots # and put all the pkgs in together myslot = 0 if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)] = mypkg for mypkg in vartree.dbapi.cp_list( portage.cpv_getkey(mymatch[0])): myslot = vartree.getslot(mypkg) if myslot not in slotmap: slotmap[myslot] = {} slotmap[myslot][vartree.dbapi.cpv_counter(mypkg)] = mypkg for myslot in slotmap: counterkeys = list(slotmap[myslot]) if not counterkeys: continue counterkeys.sort() pkgmap[mykey]["protected"].add( slotmap[myslot][counterkeys[-1]]) del counterkeys[-1] for counter in counterkeys[:]: mypkg = slotmap[myslot][counter] if mypkg not in mymatch: counterkeys.remove(counter) pkgmap[mykey]["protected"].add( slotmap[myslot][counter]) #be pretty and get them in order of merge: for ckey in counterkeys: mypkg = slotmap[myslot][ckey] if mypkg not in all_selected: pkgmap[mykey]["selected"].add(mypkg) all_selected.add(mypkg) # ok, now the last-merged package # is protected, and the rest are selected numselected = len(all_selected) if global_unmerge and not numselected: portage.writemsg_stdout("\n>>> No outdated packages were found on your system.\n") return 1, {} if not numselected: portage.writemsg_stdout( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 1, {} finally: if vdb_lock: vartree.dbapi.flush_cache() vartree.dbapi.unlock() # generate a list of package sets that are directly or indirectly listed in "selected", # as there is no persistent list of "installed" sets installed_sets = ["selected"] stop = False pos = 0 while not stop: stop = True pos = len(installed_sets) for s in installed_sets[pos - 1:]: if s not in sets: continue candidates = [x[len(SETPREFIX):] for x in sets[s].getNonAtoms() if x.startswith(SETPREFIX)] if candidates: stop = False installed_sets += candidates installed_sets = [x for x in installed_sets if x not in root_config.setconfig.active] del stop, pos # we don't want to unmerge packages that are still listed in user-editable package sets # listed in "world" as they would be remerged on the next update of "world" or the # relevant package sets. unknown_sets = set() for cp in range(len(pkgmap)): for cpv in pkgmap[cp]["selected"].copy(): try: pkg = _pkg(cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if unmerge_action != "clean" and root_config.root == "/": skip_pkg = False if portage.match_from_list(portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): msg = ("Not unmerging package %s " "since there is no valid reason for Portage to " "%s itself.") % (pkg.cpv, unmerge_action) skip_pkg = True elif vartree.dbapi._dblink(cpv).isowner( portage._python_interpreter): msg = ("Not unmerging package %s since there is no valid " "reason for Portage to %s currently used Python " "interpreter.") % (pkg.cpv, unmerge_action) skip_pkg = True if skip_pkg: for line in textwrap.wrap(msg, 75): out.eerror(line) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) continue parents = [] for s in installed_sets: # skip sets that the user requested to unmerge, and skip world # user-selected set, since the package will be removed from # that set later on. if s in root_config.setconfig.active or s == "selected": continue if s not in sets: if s in unknown_sets: continue unknown_sets.add(s) out = portage.output.EOutput() out.eerror(("Unknown set '@%s' in %s%s") % \ (s, root_config.settings['EROOT'], portage.const.WORLD_SETS_FILE)) continue # only check instances of EditablePackageSet as other classes are generally used for # special purposes and can be ignored here (and are usually generated dynamically, so the # user can't do much about them anyway) if isinstance(sets[s], EditablePackageSet): # This is derived from a snippet of code in the # depgraph._iter_atoms_for_pkg() method. for atom in sets[s].iterAtomsForPackage(pkg): inst_matches = vartree.dbapi.match(atom) inst_matches.reverse() # descending order higher_slot = None for inst_cpv in inst_matches: try: inst_pkg = _pkg(inst_cpv) except KeyError: # It could have been uninstalled # by a concurrent process. continue if inst_pkg.cp != atom.cp: continue if pkg >= inst_pkg: # This is descending order, and we're not # interested in any versions <= pkg given. break if pkg.slot_atom != inst_pkg.slot_atom: higher_slot = inst_pkg break if higher_slot is None: parents.append(s) break if parents: print(colorize("WARN", "Package %s is going to be unmerged," % cpv)) print(colorize("WARN", "but still listed in the following package sets:")) print(" %s\n" % ", ".join(parents)) del installed_sets numselected = len(all_selected) if not numselected: writemsg_level( "\n>>> No packages selected for removal by " + \ unmerge_action + "\n") return 1, {} # Unmerge order only matters in some cases if not ordered: unordered = {} for d in pkgmap: selected = d["selected"] if not selected: continue cp = portage.cpv_getkey(next(iter(selected))) cp_dict = unordered.get(cp) if cp_dict is None: cp_dict = {} unordered[cp] = cp_dict for k in d: cp_dict[k] = set() for k, v in d.items(): cp_dict[k].update(v) pkgmap = [unordered[cp] for cp in sorted(unordered)] for x in range(len(pkgmap)): selected = pkgmap[x]["selected"] if not selected: continue for mytype, mylist in pkgmap[x].items(): if mytype == "selected": continue mylist.difference_update(all_selected) cp = portage.cpv_getkey(next(iter(selected))) for y in localtree.dep_match(cp): if y not in pkgmap[x]["omitted"] and \ y not in pkgmap[x]["selected"] and \ y not in pkgmap[x]["protected"] and \ y not in all_selected: pkgmap[x]["omitted"].add(y) if global_unmerge and not pkgmap[x]["selected"]: #avoid cluttering the preview printout with stuff that isn't getting unmerged continue if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist: virt_cp = sys_virt_map.get(cp) if virt_cp is None: cp_info = "'%s'" % (cp,) else: cp_info = "'%s' (%s)" % (cp, virt_cp) writemsg_level(colorize("BAD","\n\n!!! " + \ "%s is part of your system profile.\n" % (cp_info,)), level=logging.WARNING, noiselevel=-1) writemsg_level(colorize("WARN","!!! Unmerging it may " + \ "be damaging to your system.\n\n"), level=logging.WARNING, noiselevel=-1) if not quiet: writemsg_level("\n %s\n" % (bold(cp),), noiselevel=-1) else: writemsg_level(bold(cp) + ": ", noiselevel=-1) for mytype in ["selected","protected","omitted"]: if not quiet: writemsg_level((mytype + ": ").rjust(14), noiselevel=-1) if pkgmap[x][mytype]: sorted_pkgs = [] for mypkg in pkgmap[x][mytype]: try: sorted_pkgs.append(mypkg.cpv) except AttributeError: sorted_pkgs.append(_pkg_str(mypkg)) sorted_pkgs.sort(key=cpv_sort_key()) for mypkg in sorted_pkgs: if mytype == "selected": writemsg_level( colorize("UNMERGE_WARN", mypkg.version + " "), noiselevel=-1) else: writemsg_level( colorize("GOOD", mypkg.version + " "), noiselevel=-1) else: writemsg_level("none ", noiselevel=-1) if not quiet: writemsg_level("\n", noiselevel=-1) if quiet: writemsg_level("\n", noiselevel=-1) writemsg_level("\nAll selected packages: %s\n" % " ".join('=%s' % x for x in all_selected), noiselevel=-1) writemsg_level("\n>>> " + colorize("UNMERGE_WARN", "'Selected'") + \ " packages are slated for removal.\n") writemsg_level(">>> " + colorize("GOOD", "'Protected'") + \ " and " + colorize("GOOD", "'omitted'") + \ " packages will not be removed.\n\n") return os.EX_OK, pkgmap
else: print('nil', end=' ') if 'ruby_targets_ruby22' in iuse: print('ruby22', end=' ') else: print('nil', end=' ') print(get_deps(cpv), end=' ') print() PORTTREE = portage.db[portage.root]['porttree'] for cp in PORTTREE.dbapi.cp_all(): slot_dict = {} for cpv in PORTTREE.dbapi.cp_list(cp): slot, iuse = PORTTREE.dbapi.aux_get(cpv, ['SLOT', 'IUSE']) slot_dict.setdefault(slot, {})[cpv] = (iuse) for slot, cpvd in slot_dict.items(): if 'ruby_targets_' in iuse: cpvbs = (PORTTREE.dep_bestmatch(cp)) if cpvbs: slot, iuse, keywords = PORTTREE.dbapi.aux_get(cpvbs, ['SLOT', 'IUSE', 'KEYWORDS']) if '~amd64' not in keywords and 'amd64' in keywords: format_output(cpvbs, slot, iuse, 'amd64') cpvbu = portage.best(list(cpvd)) if cpvbu: slot, iuse, keywords = PORTTREE.dbapi.aux_get(cpvbu, ['SLOT', 'IUSE', 'KEYWORDS']) if '~amd64' in keywords: format_output(cpvbu, slot, iuse, '~amd64')
def updatedb(config=None): if not os.access(config['esearchdbdir'], os.W_OK): print(yellow("Warning:"), "You do not have sufficient permissions to save the index file in:", green(config['esearchdbdir']), file=config['stderr']) return False if config['verbose'] != -1 and "ACCEPT_KEYWORDS" in environ: print(yellow("Warning:"), "You have set ACCEPT_KEYWORDS in environment, this will result", file=config['stdout']) print(" in a modified index file", file=config['stdout']) ebuilds = portage.portdb.cp_all() numebuilds = len(ebuilds) if exists(config['tmpfile']): error("there is probably another eupdatedb running already.\n" + " If you're sure there is no other process, remove", config['tmpfile'], fatal=False) return False try: dbfd = open(config['tmpfile'], O_CREAT | O_EXCL | O_WRONLY, 0o600) except OSError: error("Failed to open temporary file.", fatal=False) return False dbfile = fdopen(dbfd, "w") dbfile.write("dbversion = " + str(config['needdbversion']) + "\n") dbfile.write("db = (\n") if not config['verbose']: config['stdout'].write(green(" * ") + "indexing: ") config['stdout'].flush() nr = 0 nrchars = 0 elif config['verbose'] == 1: lastcat = False cattime = time() try: for pkg in ebuilds: masked = False if not config['verbose']: nr += 1 s = str(numebuilds - nr) + " ebuilds to go" config['stdout'].write((nrchars * "\b \b") + s) config['stdout'].flush() nrchars = len(s) pkgv = portage.portdb.xmatch("bestmatch-visible", pkg) if not pkgv: pkgv = portage.best(portage.portdb.xmatch("match-all", pkg)) if not pkgv: continue masked = True if len(pkgv) > 1: try: homepage, description, _license = portage.portdb.aux_get( pkgv, ["HOMEPAGE", "DESCRIPTION", "LICENSE"]) except KeyError: homepage, description, _license = "", "", "" pass if len(pkgv) > 1: filesize = getfetchsize(pkgv) else: filesize = '0' (curcat, pkgname) = pkg.split("/") if config['verbose'] == 1 and curcat != lastcat: if lastcat != False: print(duration(cattime), file=config['stdout']) print(bold(" * " + curcat) + ":", end=' ', file=config['stdout']) cattime = time() lastcat = curcat installed = pkg_version(VARTREE.dep_bestmatch(pkg)) if installed: installed = str(installed) dbfile.write(repr((str(pkgname), str(pkg), masked, str(pkg_version(pkgv)), installed, str(filesize), str(homepage), str(description), str(_license))) + str(",\n")) except KeyboardInterrupt: dbfile.close() unlink(config['tmpfile']) print("", file=config['stdout']) return False print("", file=config['stdout']) dbfile.write(")") dbfile.close() copyfile(config['tmpfile'], os.path.join(config['esearchdbdir'], config['esearchdbfile'])) unlink(config['tmpfile']) sys.path.insert(0, config['esearchdbdir']) import esearchdb # import the file, to generate pyc if exists( os.path.join(config['esearchdbdir'], config['esearchdbfile']) + "c"): config['esearchdbfile'] += "c" print(green(" *"), "esearch-index generated in", duration(start), file=config['stdout']) print(green(" *"), "indexed", bold(str(numebuilds)), "ebuilds", file=config['stdout']) print(green(" *"), "size of esearch-index:", bold(str(int(stat( os.path.join(config['esearchdbdir'], config['esearchdbfile']) )[6]/1024)) + " kB"), file=config['stdout']) return True
portdb.porttrees = [portdb.porttree_root] # exclude overlays portdb.freeze() settings = portage.config(clone=portage.settings) vardb = portage.db[settings["ROOT"]]["vartree"].dbapi fakedb = portage.fakedbapi(settings=portage.settings) deps = {} metadata_keys = [k for k in portage.auxdbkeys if not k.startswith("UNUSED_")] dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] good_pkgs = set() bad_pkgs = set() for cp in portdb.cp_all(): best_visible = portdb.xmatch("bestmatch-visible", cp) if best_visible: best_installed = portage.best(vardb.match(cp)) reinstall = False if best_installed and reinstall_period is not None: try: mtime = os.stat(os.path.join( vardb.getpath(best_installed), 'COUNTER')).st_mtime except OSError: reinstall = True else: if current_time - mtime > reinstall_period: reinstall = True #sys.stderr.write("%s is %.1f weeks old\n" % \ # (best_installed, # (current_time - mtime) / seconds_per_week)) if reinstall or best_visible != best_installed:
portdb.porttrees = [portdb.porttree_root] # exclude overlays portdb.freeze() settings = portage.config(clone=portage.settings) vardb = portage.db[settings["ROOT"]]["vartree"].dbapi fakedb = portage.fakedbapi(settings=portage.settings) deps = {} metadata_keys = [k for k in portage.auxdbkeys if not k.startswith("UNUSED_")] dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] good_pkgs = set() bad_pkgs = set() for cp in portdb.cp_all(): best_visible = portdb.xmatch("bestmatch-visible", cp) if best_visible: best_installed = portage.best(vardb.match(cp)) reinstall = False if best_installed and reinstall_period is not None: try: mtime = os.stat( os.path.join(vardb.getpath(best_installed), 'COUNTER')).st_mtime except OSError: reinstall = True else: if current_time - mtime > reinstall_period: reinstall = True #sys.stderr.write("%s is %.1f weeks old\n" % \ # (best_installed, # (current_time - mtime) / seconds_per_week))
def _package_newest_version(self, package): return portage.best(self._package_versions(package))
def current_version(self, atom): return str(portage.best(portage.db['/']['vartree'].dbapi.match(atom)))
def execute(self, searchkey): """Performs the search for the supplied search key""" match_category = 0 self.searchkey = searchkey self.packagematches = [] if self.searchdesc: self.searchdesc = 1 self.matches = {"pkg": [], "desc": [], "set": []} else: self.searchdesc = 0 self.matches = {"pkg": [], "set": []} print("Searching... ", end=' ') regexsearch = False if self.searchkey.startswith('%'): regexsearch = True self.searchkey = self.searchkey[1:] if self.searchkey.startswith('@'): match_category = 1 self.searchkey = self.searchkey[1:] if regexsearch: self.searchre = re.compile(self.searchkey, re.I) else: self.searchre = re.compile(re.escape(self.searchkey), re.I) for package in self._cp_all(): self._spinner_update() if match_category: match_string = package[:] else: match_string = package.split("/")[-1] masked = 0 if self.searchre.search(match_string): if not self._xmatch("match-visible", package): masked = 1 self.matches["pkg"].append([package, masked]) elif self.searchdesc: # DESCRIPTION searching full_package = self._xmatch("bestmatch-visible", package) if not full_package: #no match found; we don't want to query description full_package = portage.best( self._xmatch("match-all", package)) if not full_package: continue else: masked = 1 try: full_desc = self._aux_get(full_package, ["DESCRIPTION"])[0] except KeyError: print("emerge: search: aux_get() failed, skipping") continue if self.searchre.search(full_desc): self.matches["desc"].append([full_package, masked]) self.sdict = self.setconfig.getSets() for setname in self.sdict: self._spinner_update() if match_category: match_string = setname else: match_string = setname.split("/")[-1] if self.searchre.search(match_string): self.matches["set"].append([setname, False]) elif self.searchdesc: if self.searchre.search( self.sdict[setname].getMetadata("DESCRIPTION")): self.matches["set"].append([setname, False]) self.mlen = 0 for mtype in self.matches: self.matches[mtype].sort() self.mlen += len(self.matches[mtype])
def best(versions): """returns the best version in the list""" return portage.best(versions)
def output(self): """Outputs the results of the search.""" msg = [] msg.append("\b\b \n[ Results for search key : " + \ bold(self.searchkey) + " ]\n") msg.append("[ Applications found : " + \ bold(str(self.mlen)) + " ]\n\n") vardb = self.vartree.dbapi metadata_keys = set(Package.metadata_keys) metadata_keys.update(["DESCRIPTION", "HOMEPAGE", "LICENSE", "SRC_URI"]) metadata_keys = tuple(metadata_keys) for mtype in self.matches: for match, masked in self.matches[mtype]: full_package = None if mtype == "pkg": full_package = self._xmatch("bestmatch-visible", match) if not full_package: #no match found; we don't want to query description masked = 1 full_package = portage.best( self._xmatch("match-all", match)) elif mtype == "desc": full_package = match match = portage.cpv_getkey(match) elif mtype == "set": msg.append(green("*") + " " + bold(match) + "\n") if self.verbose: msg.append(" " + darkgreen("Description:") + \ " " + \ self.sdict[match].getMetadata("DESCRIPTION") \ + "\n\n") if full_package: try: metadata = dict( zip(metadata_keys, self._aux_get(full_package, metadata_keys))) except KeyError: msg.append( "emerge: search: aux_get() failed, skipping\n") continue desc = metadata["DESCRIPTION"] homepage = metadata["HOMEPAGE"] license = metadata["LICENSE"] if masked: msg.append(green("*") + " " + \ white(match) + " " + red("[ Masked ]") + "\n") else: msg.append(green("*") + " " + bold(match) + "\n") myversion = self.getVersion(full_package, search.VERSION_RELEASE) mysum = [0, 0] file_size_str = None mycat = match.split("/")[0] mypkg = match.split("/")[1] mycpv = match + "-" + myversion myebuild = self._findname(mycpv) if myebuild: pkg = Package(built=False, cpv=mycpv, installed=False, metadata=metadata, root_config=self.root_config, type_name="ebuild") pkgdir = os.path.dirname(myebuild) mf = self.settings.repositories.get_repo_for_location( os.path.dirname(os.path.dirname(pkgdir))) mf = mf.load_manifest(pkgdir, self.settings["DISTDIR"]) try: uri_map = _parse_uri_map(mycpv, metadata, use=pkg.use.enabled) except portage.exception.InvalidDependString as e: file_size_str = "Unknown (%s)" % (e, ) del e else: try: mysum[0] = mf.getDistfilesSize(uri_map) except KeyError as e: file_size_str = "Unknown (missing " + \ "digest for %s)" % (e,) del e available = False for db in self._dbs: if db is not vardb and \ db.cpv_exists(mycpv): available = True if not myebuild and hasattr(db, "bintree"): myebuild = db.bintree.getname(mycpv) try: mysum[0] = os.stat(myebuild).st_size except OSError: myebuild = None break if myebuild and file_size_str is None: file_size_str = localized_size(mysum[0]) if self.verbose: if available: msg.append(" %s %s\n" % \ (darkgreen("Latest version available:"), myversion)) msg.append(" %s\n" % \ self.getInstallationStatus(mycat+'/'+mypkg)) if myebuild: msg.append(" %s %s\n" % \ (darkgreen("Size of files:"), file_size_str)) msg.append(" " + darkgreen("Homepage:") + \ " " + homepage + "\n") msg.append(" " + darkgreen("Description:") \ + " " + desc + "\n") msg.append(" " + darkgreen("License:") + \ " " + license + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1)
def _new_scan(self): """ Internal scan method, executes the actual scan and retuns a raw list of AntiMatterPackage objects. """ vardb, portdb = self._get_dbs() new_days_old_secs = self._nsargs.new_days_old * 3600 * 24 not_installed = self._nsargs.not_installed result = [] cp_all = portdb.cp_all() cp_all.sort() root = portdb.porttree_root for count, package in enumerate(cp_all): count_str = "[%s of %s]" % ( count, len(cp_all), ) if self._nsargs.verbose: print_warning("%s :: %s" % (count_str, package), back=True) if not not_installed: cp_dir = os.path.join(root, package) try: mtime = os.path.getmtime(cp_dir) except (OSError, IOError): mtime = 0.0 if abs(time.time() - mtime) >= new_days_old_secs: # not new enough continue best_installed = portage.best(vardb.match(package)) if best_installed: # package key is already installed, ignore continue best_visible = portage.best(portdb.match(package)) if not best_visible: # wtf? package masked? continue try: slot, repo = portdb.aux_get(best_visible, ["SLOT", "repository"]) except KeyError: # portage is scrappy continue atom = portage.dep.Atom("=%s:%s::%s" % (best_visible, slot, repo), allow_wildcard=True, allow_repo=True) pkg = AntiMatterPackage(vardb, portdb, None, atom, 1) result.append(pkg) if cp_all and self._nsargs.verbose: print_generic("") return result
if 'ruby_targets_ruby23' in iuse: print('ruby23', end=' ') else: print('nil', end=' ') print(get_deps(cpv), end=' ') print() PORTTREE = portage.db[portage.root]['porttree'] for cp in PORTTREE.dbapi.cp_all(): slot_dict = {} for cpv in PORTTREE.dbapi.cp_list(cp): slot, iuse = PORTTREE.dbapi.aux_get(cpv, ['SLOT', 'IUSE']) slot_dict.setdefault(slot, {})[cpv] = (iuse) for slot, cpvd in slot_dict.items(): if 'ruby_targets_' in iuse: cpvbs = (PORTTREE.dep_bestmatch(cp)) if cpvbs: slot, iuse, keywords = PORTTREE.dbapi.aux_get( cpvbs, ['SLOT', 'IUSE', 'KEYWORDS']) if '~amd64' not in keywords and 'amd64' in keywords: format_output(cpvbs, slot, iuse, 'amd64') cpvbu = portage.best(list(cpvd)) if cpvbu: slot, iuse, keywords = PORTTREE.dbapi.aux_get( cpvbu, ['SLOT', 'IUSE', 'KEYWORDS']) if '~amd64' in keywords: format_output(cpvbu, slot, iuse, '~amd64')
def _scan(self): """ Internal scan method, executes the actual scan and retuns a raw list of AntiMatterPackage objects. """ vardb, portdb = self._get_dbs() result = [] vardb.lock() try: cpv_all = vardb.cpv_all() cpv_all.sort() for count, package in enumerate(cpv_all): count_str = "[%s of %s]" % ( count, len(cpv_all),) try: slot, repo = vardb.aux_get( package, ["SLOT", "repository"]) except KeyError: # package vanished, can still # happen even if locked? continue atom = portage.dep.Atom( "=%s:%s::%s" % (package, slot, repo), allow_wildcard=True, allow_repo=True) if self._nsargs.verbose: print_warning("%s :: %s" % (count_str, atom), back=True) key_slot = "%s:%s" % (atom.cp, atom.slot) best_visible = portage.best(portdb.match(key_slot)) if not best_visible: # dropped upstream pkg = AntiMatterPackage( vardb, portdb, atom, None, -1) result.append(pkg) if self._nsargs.verbose: print_error( " %s no longer upstream or masked" % (key_slot,)) continue cmp_res = portage.versions.pkgcmp( portage.versions.pkgsplit(best_visible), portage.versions.pkgsplit(package)) pkg = AntiMatterPackage( vardb, portdb, atom, best_visible, cmp_res) result.append(pkg) finally: vardb.unlock() if cpv_all and self._nsargs.verbose: print_generic("") return result
def output(self): """Outputs the results of the search.""" msg = [] msg.append("\b\b \n[ Results for search key : " + \ bold(self.searchkey) + " ]\n") msg.append("[ Applications found : " + \ bold(str(self.mlen)) + " ]\n\n") vardb = self.vartree.dbapi metadata_keys = set(Package.metadata_keys) metadata_keys.update(["DESCRIPTION", "HOMEPAGE", "LICENSE", "SRC_URI"]) metadata_keys = tuple(metadata_keys) for mtype in self.matches: for match,masked in self.matches[mtype]: full_package = None if mtype == "pkg": full_package = self._xmatch( "bestmatch-visible", match) if not full_package: #no match found; we don't want to query description masked=1 full_package = portage.best( self._xmatch("match-all",match)) elif mtype == "desc": full_package = match match = portage.cpv_getkey(match) elif mtype == "set": msg.append(green("*") + " " + bold(match) + "\n") if self.verbose: msg.append(" " + darkgreen("Description:") + \ " " + \ self.sdict[match].getMetadata("DESCRIPTION") \ + "\n\n") if full_package: try: metadata = dict(zip(metadata_keys, self._aux_get(full_package, metadata_keys))) except KeyError: msg.append("emerge: search: aux_get() failed, skipping\n") continue desc = metadata["DESCRIPTION"] homepage = metadata["HOMEPAGE"] license = metadata["LICENSE"] if masked: msg.append(green("*") + " " + \ white(match) + " " + red("[ Masked ]") + "\n") else: msg.append(green("*") + " " + bold(match) + "\n") myversion = self.getVersion(full_package, search.VERSION_RELEASE) mysum = [0,0] file_size_str = None mycat = match.split("/")[0] mypkg = match.split("/")[1] mycpv = match + "-" + myversion myebuild = self._findname(mycpv) if myebuild: pkg = Package(built=False, cpv=mycpv, installed=False, metadata=metadata, root_config=self.root_config, type_name="ebuild") pkgdir = os.path.dirname(myebuild) mf = self.settings.repositories.get_repo_for_location( os.path.dirname(os.path.dirname(pkgdir))) mf = mf.load_manifest( pkgdir, self.settings["DISTDIR"]) try: uri_map = _parse_uri_map(mycpv, metadata, use=pkg.use.enabled) except portage.exception.InvalidDependString as e: file_size_str = "Unknown (%s)" % (e,) del e else: try: mysum[0] = mf.getDistfilesSize(uri_map) except KeyError as e: file_size_str = "Unknown (missing " + \ "digest for %s)" % (e,) del e available = False for db in self._dbs: if db is not vardb and \ db.cpv_exists(mycpv): available = True if not myebuild and hasattr(db, "bintree"): myebuild = db.bintree.getname(mycpv) try: mysum[0] = os.stat(myebuild).st_size except OSError: myebuild = None break if myebuild and file_size_str is None: file_size_str = localized_size(mysum[0]) if self.verbose: if available: msg.append(" %s %s\n" % \ (darkgreen("Latest version available:"), myversion)) msg.append(" %s\n" % \ self.getInstallationStatus(mycat+'/'+mypkg)) if myebuild: msg.append(" %s %s\n" % \ (darkgreen("Size of files:"), file_size_str)) msg.append(" " + darkgreen("Homepage:") + \ " " + homepage + "\n") msg.append(" " + darkgreen("Description:") \ + " " + desc + "\n") msg.append(" " + darkgreen("License:") + \ " " + license + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1)
def output(self): """Outputs the results of the search.""" msg = [] msg.append("\b\b \n[ Results for search key : " + \ bold(self.searchkey) + " ]\n") msg.append("[ Applications found : " + \ bold(str(self.mlen)) + " ]\n\n") vardb = self.vartree.dbapi for mtype in self.matches: for match, masked in self.matches[mtype]: full_package = None if mtype == "pkg": catpack = match full_package = self.portdb.xmatch("bestmatch-visible", match) if not full_package: #no match found; we don't want to query description masked = 1 full_package = portage.best( self.portdb.xmatch("match-all", match)) elif mtype == "desc": full_package = match match = portage.cpv_getkey(match) elif mtype == "set": msg.append(green("*") + " " + bold(match) + "\n") if self.verbose: msg.append(" " + darkgreen("Description:") + \ " " + \ self.sdict[match].getMetadata("DESCRIPTION") \ + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1) if full_package: try: desc, homepage, license = self.portdb.aux_get( full_package, ["DESCRIPTION", "HOMEPAGE", "LICENSE"]) except KeyError: msg.append( "emerge: search: aux_get() failed, skipping\n") continue if masked: msg.append(green("*") + " " + \ white(match) + " " + red("[ Masked ]") + "\n") else: msg.append(green("*") + " " + bold(match) + "\n") myversion = self.getVersion(full_package, search.VERSION_RELEASE) mysum = [0, 0] file_size_str = None mycat = match.split("/")[0] mypkg = match.split("/")[1] mycpv = match + "-" + myversion myebuild = self.portdb.findname(mycpv) if myebuild: pkgdir = os.path.dirname(myebuild) from portage import manifest mf = manifest.Manifest(pkgdir, self.settings["DISTDIR"]) try: uri_map = self.portdb.getFetchMap(mycpv) except portage.exception.InvalidDependString as e: file_size_str = "Unknown (%s)" % (e, ) del e else: try: mysum[0] = mf.getDistfilesSize(uri_map) except KeyError as e: file_size_str = "Unknown (missing " + \ "digest for %s)" % (e,) del e available = False for db in self._dbs: if db is not vardb and \ db.cpv_exists(mycpv): available = True if not myebuild and hasattr(db, "bintree"): myebuild = db.bintree.getname(mycpv) try: mysum[0] = os.stat(myebuild).st_size except OSError: myebuild = None break if myebuild and file_size_str is None: mystr = str(mysum[0] // 1024) mycount = len(mystr) while (mycount > 3): mycount -= 3 mystr = mystr[:mycount] + "," + mystr[mycount:] file_size_str = mystr + " kB" if self.verbose: if available: msg.append(" %s %s\n" % \ (darkgreen("Latest version available:"), myversion)) msg.append(" %s\n" % \ self.getInstallationStatus(mycat+'/'+mypkg)) if myebuild: msg.append(" %s %s\n" % \ (darkgreen("Size of files:"), file_size_str)) msg.append(" " + darkgreen("Homepage:") + \ " " + homepage + "\n") msg.append(" " + darkgreen("Description:") \ + " " + desc + "\n") msg.append(" " + darkgreen("License:") + \ " " + license + "\n\n") writemsg_stdout(''.join(msg), noiselevel=-1)
def package_newest_version(self): return self._extract_version(portage.best(self._package_versions(self.package)))