def get_matched_dep_packages(self, depvar): # change the useflags, because we have internally changed some, but not made them visible for portage actual = self.get_actual_use_flags() depstring = "" try: depstring = " ".join( self.get_package_settings(d, installed=False) for d in depvar) except KeyError: # not found in porttree - use vartree depstring = " ".join( self.get_package_settings(d, installed=True) for d in depvar) deps = portage.dep_check(depstring, None, self._settings.settings, myuse=actual, trees=self._trees) if not deps: # FIXME: what is the difference to [1, []] ? return [] if deps[0] == 0: # error raise DependencyCalcError(deps[1]) deps = deps[1] return [d for d in deps if d[0] != "!"]
def get_deps(self,pkg,dep_type=["RDEPEND","DEPEND"]): #pkg="kde-meta" #print self.vardb.match("<sys-apps/paludis-0.26.0_alpha5") #metadata = dict(zip(self.metadata_keys, self.vardb.aux_get(pkg, self.metadata_keys))) ret=set() pkg = self.portdb.xmatch("bestmatch-visible", pkg) if not pkg: return ret #print pkg known_packages=set() unknown_packages={pkg} while unknown_packages: p=unknown_packages.pop() #print "proceeding "+p if p in known_packages: continue known_packages.add(p) #print self.metadata_keys, p,self.portdb.aux_get(p, self.metadata_keys) metadata = dict(zip(self.metadata_keys, self.vardb.aux_get(p, self.metadata_keys))) #print "proceeding2 "+p dep_str = " ".join(metadata[k] for k in dep_type) success, atoms = portage.dep_check(dep_str, None, self.settings, myuse=self.use.split(), trees=portage.db, myroot=self.settings["ROOT"]) #print atoms if not success: continue for atom in atoms: atomname = self.vartree.dep_bestmatch(atom) #print atomname if not atomname: continue for unvirt_pkg in expand_new_virt(self.vartree.dbapi,'='+atomname): for pkg in self.vartree.dep_match(unvirt_pkg): ret.add(pkg) unknown_packages.add(pkg) return ret
def get_matched_dep_packages (self, depvar): # change the useflags, because we have internally changed some, but not made them visible for portage actual = self.get_actual_use_flags() depstring = "" try: depstring = " ".join(self.get_package_settings(d, installed = False) for d in depvar) except KeyError: # not found in porttree - use vartree depstring = " ".join(self.get_package_settings(d, installed = True) for d in depvar) deps = portage.dep_check(depstring, None, self._settings.settings, myuse = actual, trees = self._trees) if not deps: # FIXME: what is the difference to [1, []] ? return [] if deps[0] == 0: # error raise DependencyCalcError(deps[1]) deps = deps[1] return [d for d in deps if d[0] != "!"]
def get_dep_packages (self, depvar = ["RDEPEND", "PDEPEND", "DEPEND"], with_criterions = False, return_blocks = False): dep_pkgs = [] # the package list # change the useflags, because we have internally changed some, but not made them visible for portage actual = self.get_actual_use_flags() depstring = " ".join(self.get_package_settings(d, installed = False) for d in depvar) # let portage do the main stuff ;) # pay attention to any changes here deps = portage.dep_check (depstring, self._settings.vartree.dbapi, self._settings.settings, myuse = actual, trees = self._trees) if not deps: # FIXME: what is the difference to [1, []] ? return [] if deps[0] == 0: # error raise DependencyCalcError(deps[1]) deps = deps[1] def create_dep_pkgs_data (dep, pkg): """Returns the data to enter into the dep_pkgs list, which is either the package cpv or a tuple consisting of the cpv and the criterion.""" if with_criterions: return (pkg.get_cpv(), dep) else: return pkg.get_cpv() for dep in deps: if dep[0] == '!': # blocking sth blocked = system.find_packages(dep, system.SET_INSTALLED) if len(blocked) == 1: # only exact one match allowed to be harmless if blocked[0].get_slot_cp() == self.get_slot_cp(): # blocks in the same slot are harmless continue if return_blocks: if not blocked: if not system.find_packages(dep, masked = True): continue # well - no packages affected - ignore if with_criterions: dep_pkgs.append((dep, dep)) else: dep_pkgs.append(dep) elif blocked: raise BlockedException((self.get_cpv(), blocked[0].get_cpv())) continue # finished with the blocking one -> next pkg = system.find_best_match(dep) if not pkg: # try to find masked ones pkgs = system.find_packages(dep, masked = True) if not pkgs: raise PackageNotFoundException(dep) pkgs = system.sort_package_list(pkgs) pkgs.reverse() done = False for p in pkgs: if not p.is_masked(): dep_pkgs.append(create_dep_pkgs_data(dep, p)) done = True break if not done: dep_pkgs.append(create_dep_pkgs_data(dep, pkgs[0])) else: dep_pkgs.append(create_dep_pkgs_data(dep, pkg)) return dep_pkgs
def findInstalledBlockers(self, new_pkg, acquire_lock=0): blocker_cache = BlockerCache(self._vartree.root, self._vartree.dbapi) dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] settings = self._vartree.settings stale_cache = set(blocker_cache) fake_vartree = self._get_fake_vartree(acquire_lock=acquire_lock) dep_check_trees = self._dep_check_trees vardb = fake_vartree.dbapi installed_pkgs = list(vardb) for inst_pkg in installed_pkgs: stale_cache.discard(inst_pkg.cpv) cached_blockers = blocker_cache.get(inst_pkg.cpv) if cached_blockers is not None and \ cached_blockers.counter != long(inst_pkg.metadata["COUNTER"]): cached_blockers = None if cached_blockers is not None: blocker_atoms = cached_blockers.atoms else: # Use aux_get() to trigger FakeVartree global # updates on *DEPEND when appropriate. depstr = " ".join(vardb.aux_get(inst_pkg.cpv, dep_keys)) success, atoms = portage.dep_check(depstr, vardb, settings, myuse=inst_pkg.use.enabled, trees=dep_check_trees, myroot=inst_pkg.root) if not success: pkg_location = os.path.join(inst_pkg.root, portage.VDB_PATH, inst_pkg.category, inst_pkg.pf) portage.writemsg("!!! %s/*DEPEND: %s\n" % \ (pkg_location, atoms), noiselevel=-1) continue blocker_atoms = [atom for atom in atoms \ if atom.startswith("!")] blocker_atoms.sort() counter = long(inst_pkg.metadata["COUNTER"]) blocker_cache[inst_pkg.cpv] = \ blocker_cache.BlockerData(counter, blocker_atoms) for cpv in stale_cache: del blocker_cache[cpv] blocker_cache.flush() blocker_parents = digraph() blocker_atoms = [] for pkg in installed_pkgs: for blocker_atom in blocker_cache[pkg.cpv].atoms: blocker_atom = blocker_atom.lstrip("!") blocker_atoms.append(blocker_atom) blocker_parents.add(blocker_atom, pkg) blocker_atoms = InternalPackageSet(initial_atoms=blocker_atoms) blocking_pkgs = set() for atom in blocker_atoms.iterAtomsForPackage(new_pkg): blocking_pkgs.update(blocker_parents.parent_nodes(atom)) # Check for blockers in the other direction. depstr = " ".join(new_pkg.metadata[k] for k in dep_keys) success, atoms = portage.dep_check(depstr, vardb, settings, myuse=new_pkg.use.enabled, trees=dep_check_trees, myroot=new_pkg.root) if not success: # We should never get this far with invalid deps. show_invalid_depstring_notice(new_pkg, depstr, atoms) assert False blocker_atoms = [atom.lstrip("!") for atom in atoms \ if atom[:1] == "!"] if blocker_atoms: blocker_atoms = InternalPackageSet(initial_atoms=blocker_atoms) for inst_pkg in installed_pkgs: try: next(blocker_atoms.iterAtomsForPackage(inst_pkg)) except (portage.exception.InvalidDependString, StopIteration): continue blocking_pkgs.add(inst_pkg) return blocking_pkgs
# value = ( added, dependencies, slot ) DEP_ADDED = 0 DEP_DEPLIST = 1 DEP_SLOT = 2 dep_cache = {} # very simply, we extract the dependencies for each package for pkg in pkgs_to_reorder: try: deps, slot = varapi.aux_get(pkg, ["DEPEND", "SLOT"]) except ValueError: sys.stderr.write("Error getting dependency information off " + pkg + "\n") continue try: realdeps = portage.dep_check(deps, fakedbapi) except TypeError: # we're probably running >=portage-2.0.50 pkgsettings = portage.config(clone=portage.settings) realdeps = portage.dep_check(deps, fakedbapi, pkgsettings) vardeps = [] # match() finds the versions of all those that are installed for dep in realdeps[1]: vardeps = vardeps + varapi.match(dep) dep_cache[pkg] = (0, vardeps, slot) # then we just naively append to a sorted list of deps using this rule. # if a dependency is going to be merged, we add it to the list like # with the dep then the pkg itself. # eg: dev-python/pyqt deps on dev-python/sip, so we the list will look like
def _scan_ebuilds(self, ebuildlist, xpkg, catdir, pkgdir): # detect unused local USE-descriptions used_useflags = set() for y_ebuild in ebuildlist: ebuild = Ebuild( self.repo_settings, self.repolevel, pkgdir, catdir, self.vcs_settings, xpkg, y_ebuild) if self.check['changelog'] and not self.changelog_modified \ and ebuild.ebuild_path in self.changed.new_ebuilds: self.qatracker.add_error('changelog.ebuildadded', ebuild.relative_path) if ebuild.untracked(self.check['ebuild_notadded'], y_ebuild, self.eadded): # ebuild not added to vcs self.qatracker.add_error( "ebuild.notadded", xpkg + "/" + y_ebuild + ".ebuild") if bad_split_check(xpkg, y_ebuild, pkgdir, self.qatracker): continue pkg = self.pkgs[y_ebuild] if pkg_invalid(pkg, self.qatracker, ebuild): self.allvalid = False continue myaux = pkg._metadata eapi = myaux["EAPI"] inherited = pkg.inherited live_ebuild = self.live_eclasses.intersection(inherited) self.eapicheck.check(pkg, ebuild) for k, v in myaux.items(): if not isinstance(v, basestring): continue m = NON_ASCII_RE.search(v) if m is not None: self.qatracker.add_error( "variable.invalidchar", "%s: %s variable contains non-ASCII " "character at position %s" % (ebuild.relative_path, k, m.start() + 1)) if not self.fetchcheck.src_uri_error: self.thirdparty.check(myaux, ebuild.relative_path) if myaux.get("PROVIDE"): self.qatracker.add_error("virtual.oldstyle", ebuild.relative_path) for pos, missing_var in enumerate(missingvars): if not myaux.get(missing_var): if catdir == "virtual" and \ missing_var in ("HOMEPAGE", "LICENSE"): continue if live_ebuild and missing_var == "KEYWORDS": continue myqakey = missingvars[pos] + ".missing" self.qatracker.add_error(myqakey, xpkg + "/" + y_ebuild + ".ebuild") if catdir == "virtual": for var in ("HOMEPAGE", "LICENSE"): if myaux.get(var): myqakey = var + ".virtual" self.qatracker.add_error(myqakey, ebuild.relative_path) self.descriptioncheck.check(pkg, ebuild) keywords = myaux["KEYWORDS"].split() ebuild_archs = set( kw.lstrip("~") for kw in keywords if not kw.startswith("-")) self.keywordcheck.check( pkg, xpkg, ebuild, y_ebuild, keywords, ebuild_archs, self.changed, live_ebuild, self.repo_metadata['kwlist'], self.profiles) if live_ebuild and self.repo_settings.repo_config.name == "gentoo": self.liveeclasscheck.check( pkg, xpkg, ebuild, y_ebuild, keywords, self.repo_metadata['pmaskdict']) if self.options.ignore_arches: arches = [[ self.repo_settings.repoman_settings["ARCH"], self.repo_settings.repoman_settings["ARCH"], self.repo_settings.repoman_settings["ACCEPT_KEYWORDS"].split()]] else: arches = set() for keyword in keywords: if keyword[0] == "-": continue elif keyword[0] == "~": arch = keyword[1:] if arch == "*": for expanded_arch in self.profiles: if expanded_arch == "**": continue arches.add( (keyword, expanded_arch, ( expanded_arch, "~" + expanded_arch))) else: arches.add((keyword, arch, (arch, keyword))) else: # For ebuilds with stable keywords, check if the # dependencies are satisfiable for unstable # configurations, since use.stable.mask is not # applied for unstable configurations (see bug # 563546). if keyword == "*": for expanded_arch in self.profiles: if expanded_arch == "**": continue arches.add( (keyword, expanded_arch, (expanded_arch,))) arches.add( (keyword, expanded_arch, (expanded_arch, "~" + expanded_arch))) else: arches.add((keyword, keyword, (keyword,))) arches.add((keyword, keyword, (keyword, "~" + keyword))) if not arches: # Use an empty profile for checking dependencies of # packages that have empty KEYWORDS. arches.add(('**', '**', ('**',))) unknown_pkgs = set() baddepsyntax = False badlicsyntax = False badprovsyntax = False # catpkg = catdir + "/" + y_ebuild inherited_java_eclass = "java-pkg-2" in inherited or \ "java-pkg-opt-2" in inherited inherited_wxwidgets_eclass = "wxwidgets" in inherited # operator_tokens = set(["||", "(", ")"]) type_list, badsyntax = [], [] for mytype in Package._dep_keys + ("LICENSE", "PROPERTIES", "PROVIDE"): mydepstr = myaux[mytype] buildtime = mytype in Package._buildtime_keys runtime = mytype in Package._runtime_keys token_class = None if mytype.endswith("DEPEND"): token_class = portage.dep.Atom try: atoms = portage.dep.use_reduce( mydepstr, matchall=1, flat=True, is_valid_flag=pkg.iuse.is_valid_flag, token_class=token_class) except portage.exception.InvalidDependString as e: atoms = None badsyntax.append(str(e)) if atoms and mytype.endswith("DEPEND"): if runtime and \ "test?" in mydepstr.split(): self.qatracker.add_error( mytype + '.suspect', "%s: 'test?' USE conditional in %s" % (ebuild.relative_path, mytype)) for atom in atoms: if atom == "||": continue is_blocker = atom.blocker # Skip dependency.unknown for blockers, so that we # don't encourage people to remove necessary blockers, # as discussed in bug 382407. We use atom.without_use # due to bug 525376. if not is_blocker and \ not self.portdb.xmatch("match-all", atom.without_use) and \ not atom.cp.startswith("virtual/"): unknown_pkgs.add((mytype, atom.unevaluated_atom)) if catdir != "virtual": if not is_blocker and \ atom.cp in suspect_virtual: self.qatracker.add_error( 'virtual.suspect', ebuild.relative_path + ": %s: consider using '%s' instead of '%s'" % (mytype, suspect_virtual[atom.cp], atom)) if not is_blocker and \ atom.cp.startswith("perl-core/"): self.qatracker.add_error('dependency.perlcore', ebuild.relative_path + ": %s: please use '%s' instead of '%s'" % (mytype, atom.replace("perl-core/","virtual/perl-"), atom)) if buildtime and \ not is_blocker and \ not inherited_java_eclass and \ atom.cp == "virtual/jdk": self.qatracker.add_error( 'java.eclassesnotused', ebuild.relative_path) elif buildtime and \ not is_blocker and \ not inherited_wxwidgets_eclass and \ atom.cp == "x11-libs/wxGTK": self.qatracker.add_error( 'wxwidgets.eclassnotused', "%s: %ss on x11-libs/wxGTK without inheriting" " wxwidgets.eclass" % (ebuild.relative_path, mytype)) elif runtime: if not is_blocker and \ atom.cp in suspect_rdepend: self.qatracker.add_error( mytype + '.suspect', ebuild.relative_path + ": '%s'" % atom) if atom.operator == "~" and \ portage.versions.catpkgsplit(atom.cpv)[3] != "r0": qacat = 'dependency.badtilde' self.qatracker.add_error( qacat, "%s: %s uses the ~ operator" " with a non-zero revision: '%s'" % (ebuild.relative_path, mytype, atom)) check_missingslot(atom, mytype, eapi, self.portdb, self.qatracker, ebuild.relative_path, myaux) type_list.extend([mytype] * (len(badsyntax) - len(type_list))) for m, b in zip(type_list, badsyntax): if m.endswith("DEPEND"): qacat = "dependency.syntax" else: qacat = m + ".syntax" self.qatracker.add_error( qacat, "%s: %s: %s" % (ebuild.relative_path, m, b)) badlicsyntax = len([z for z in type_list if z == "LICENSE"]) badprovsyntax = len([z for z in type_list if z == "PROVIDE"]) baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax badlicsyntax = badlicsyntax > 0 badprovsyntax = badprovsyntax > 0 self.use_flag_checks.check(pkg, xpkg, ebuild, y_ebuild, self.muselist) ebuild_used_useflags = self.use_flag_checks.getUsedUseFlags() used_useflags = used_useflags.union(ebuild_used_useflags) self.rubyeclasscheck.check(pkg, ebuild) # license checks if not badlicsyntax: self.licensecheck.check(pkg, xpkg, ebuild, y_ebuild) self.restrictcheck.check(pkg, xpkg, ebuild, y_ebuild) # Syntax Checks if not self.vcs_settings.vcs_preserves_mtime: if ebuild.ebuild_path not in self.changed.new_ebuilds and \ ebuild.ebuild_path not in self.changed.ebuilds: pkg.mtime = None try: # All ebuilds should have utf_8 encoding. f = io.open( _unicode_encode( ebuild.full_path, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content']) try: for check_name, e in run_checks(f, pkg): self.qatracker.add_error( check_name, ebuild.relative_path + ': %s' % e) finally: f.close() except UnicodeDecodeError: # A file.UTF8 failure will have already been recorded above. pass if self.options.force: # The dep_check() calls are the most expensive QA test. If --force # is enabled, there's no point in wasting time on these since the # user is intent on forcing the commit anyway. continue relevant_profiles = [] for keyword, arch, groups in arches: if arch not in self.profiles: # A missing profile will create an error further down # during the KEYWORDS verification. continue if self.include_arches is not None: if arch not in self.include_arches: continue relevant_profiles.extend( (keyword, groups, prof) for prof in self.profiles[arch]) relevant_profiles.sort(key=sort_key) for keyword, groups, prof in relevant_profiles: is_stable_profile = prof.status == "stable" is_dev_profile = prof.status == "dev" and \ self.options.include_dev is_exp_profile = prof.status == "exp" and \ self.options.include_exp_profiles == 'y' if not (is_stable_profile or is_dev_profile or is_exp_profile): continue dep_settings = self.caches['arch'].get(prof.sub_path) if dep_settings is None: dep_settings = portage.config( config_profile_path=prof.abs_path, config_incrementals=self.repoman_incrementals, config_root=self.config_root, local_config=False, _unmatched_removal=self.options.unmatched_removal, env=self.env, repositories=self.repo_settings.repoman_settings.repositories) dep_settings.categories = self.repo_settings.repoman_settings.categories if self.options.without_mask: dep_settings._mask_manager_obj = \ copy.deepcopy(dep_settings._mask_manager) dep_settings._mask_manager._pmaskdict.clear() self.caches['arch'][prof.sub_path] = dep_settings xmatch_cache_key = (prof.sub_path, tuple(groups)) xcache = self.caches['arch_xmatch'].get(xmatch_cache_key) if xcache is None: self.portdb.melt() self.portdb.freeze() xcache = self.portdb.xcache xcache.update(self.caches['shared_xmatch']) self.caches['arch_xmatch'][xmatch_cache_key] = xcache self.repo_settings.trees[self.repo_settings.root]["porttree"].settings = dep_settings self.portdb.settings = dep_settings self.portdb.xcache = xcache dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups) # just in case, prevent config.reset() from nuking these. dep_settings.backup_changes("ACCEPT_KEYWORDS") # This attribute is used in dbapi._match_use() to apply # use.stable.{mask,force} settings based on the stable # status of the parent package. This is required in order # for USE deps of unstable packages to be resolved correctly, # since otherwise use.stable.{mask,force} settings of # dependencies may conflict (see bug #456342). dep_settings._parent_stable = dep_settings._isStable(pkg) # Handle package.use*.{force,mask) calculation, for use # in dep_check. dep_settings.useforce = dep_settings._use_manager.getUseForce( pkg, stable=dep_settings._parent_stable) dep_settings.usemask = dep_settings._use_manager.getUseMask( pkg, stable=dep_settings._parent_stable) if not baddepsyntax: ismasked = not ebuild_archs or \ pkg.cpv not in self.portdb.xmatch("match-visible", Atom("%s::%s" % (pkg.cp, self.repo_settings.repo_config.name))) if ismasked: if not self.have['pmasked']: self.have['pmasked'] = bool(dep_settings._getMaskAtom( pkg.cpv, pkg._metadata)) if self.options.ignore_masked: continue # we are testing deps for a masked package; give it some lee-way suffix = "masked" matchmode = "minimum-all-ignore-profile" else: suffix = "" matchmode = "minimum-visible" if not self.have['dev_keywords']: self.have['dev_keywords'] = \ bool(self.dev_keywords.intersection(keywords)) if prof.status == "dev": suffix = suffix + "indev" for mytype in Package._dep_keys: mykey = "dependency.bad" + suffix myvalue = myaux[mytype] if not myvalue: continue success, atoms = portage.dep_check( myvalue, self.portdb, dep_settings, use="all", mode=matchmode, trees=self.repo_settings.trees) if success: if atoms: # Don't bother with dependency.unknown for # cases in which *DEPEND.bad is triggered. for atom in atoms: # dep_check returns all blockers and they # aren't counted for *DEPEND.bad, so we # ignore them here. if not atom.blocker: unknown_pkgs.discard( (mytype, atom.unevaluated_atom)) if not prof.sub_path: # old-style virtuals currently aren't # resolvable with empty profile, since # 'virtuals' mappings are unavailable # (it would be expensive to search # for PROVIDE in all ebuilds) atoms = [ atom for atom in atoms if not ( atom.cp.startswith('virtual/') and not self.portdb.cp_list(atom.cp))] # we have some unsolvable deps # remove ! deps, which always show up as unsatisfiable atoms = [ str(atom.unevaluated_atom) for atom in atoms if not atom.blocker] # if we emptied out our list, continue: if not atoms: continue if self.options.output_style in ['column']: self.qatracker.add_error(mykey, "%s: %s: %s(%s) %s" % (ebuild.relative_path, mytype, keyword, prof, repr(atoms))) else: self.qatracker.add_error(mykey, "%s: %s: %s(%s)\n%s" % (ebuild.relative_path, mytype, keyword, prof, pformat(atoms, indent=6))) else: if self.options.output_style in ['column']: self.qatracker.add_error(mykey, "%s: %s: %s(%s) %s" % (ebuild.relative_path, mytype, keyword, prof, repr(atoms))) else: self.qatracker.add_error(mykey, "%s: %s: %s(%s)\n%s" % (ebuild.relative_path, mytype, keyword, prof, pformat(atoms, indent=6))) if not baddepsyntax and unknown_pkgs: type_map = {} for mytype, atom in unknown_pkgs: type_map.setdefault(mytype, set()).add(atom) for mytype, atoms in type_map.items(): self.qatracker.add_error( "dependency.unknown", "%s: %s: %s" % (ebuild.relative_path, mytype, ", ".join(sorted(atoms)))) # check if there are unused local USE-descriptions in metadata.xml # (unless there are any invalids, to avoid noise) if self.allvalid: for myflag in self.muselist.difference(used_useflags): self.qatracker.add_error( "metadata.warning", "%s/metadata.xml: unused local USE-description: '%s'" % (xpkg, myflag))
# conflict. slot_atom = "%s:%s" % (portage.cpv_getkey(dep_pkg), metadata["SLOT"]) best_visible_slot = portdb.xmatch("bestmatch-visible", slot_atom) if dep_pkg != best_visible_slot: unsatisfied_dep = True bad_pkgs.add(dep_pkg) bad_pkgs.add(parent) break dep_str = " ".join(metadata[k] for k in dep_keys) settings.setcpv(dep_pkg, mydb=metadata) metadata["USE"] = settings["PORTAGE_USE"] success, atoms = portage.dep_check(dep_str, None, settings, myuse=metadata["USE"].split(), trees=portage.db, myroot=settings["ROOT"]) if not success: sys.stderr.write(atoms + "\n") unsatisfied_dep = True bad_pkgs.add(dep_pkg) bad_pkgs.add(parent) break traversed.add(dep_pkg) fakedb.cpv_inject(dep_pkg, metadata=metadata) deps[dep_pkg] = atoms for atom in atoms: if atom.blocker:
# value = ( added, dependencies, slot ) DEP_ADDED = 0 DEP_DEPLIST = 1 DEP_SLOT = 2 dep_cache = {} # very simply, we extract the dependencies for each package for pkg in pkgs_to_reorder: try: deps, slot = varapi.aux_get(pkg, ["DEPEND", "SLOT"]) except ValueError: sys.stderr.write("Error getting dependency information off " + pkg + "\n") continue try: realdeps = portage.dep_check(deps, fakedbapi) except TypeError: # we're probably running >=portage-2.0.50 pkgsettings = portage.config(clone=portage.settings) realdeps = portage.dep_check(deps, fakedbapi, pkgsettings) vardeps = [] # match() finds the versions of all those that are installed for dep in realdeps[1]: vardeps = vardeps + varapi.match(dep) dep_cache[pkg] = ( 0, vardeps, slot ) # then we just naively append to a sorted list of deps using this rule. # if a dependency is going to be merged, we add it to the list like # with the dep then the pkg itself. # eg: dev-python/pyqt deps on dev-python/sip, so we the list will look like
metadata["SLOT"]) best_visible_slot = portdb.xmatch("bestmatch-visible", slot_atom) if dep_pkg != best_visible_slot: unsatisfied_dep = True bad_pkgs.add(dep_pkg) bad_pkgs.add(parent) break dep_str = " ".join(metadata[k] for k in dep_keys) settings.setcpv(dep_pkg, mydb=metadata) metadata["USE"] = settings["PORTAGE_USE"] success, atoms = portage.dep_check( dep_str, None, settings, myuse=metadata["USE"].split(), trees=portage.db, myroot=settings["ROOT"]) if not success: sys.stderr.write(atoms + "\n") unsatisfied_dep = True bad_pkgs.add(dep_pkg) bad_pkgs.add(parent) break traversed.add(dep_pkg) fakedb.cpv_inject(dep_pkg, metadata=metadata) deps[dep_pkg] = atoms
def expand_new_virt(vardb, atom): """ Iterate over the recursively expanded RDEPEND atoms of a new-style virtual. If atom is not a new-style virtual or it does not match an installed package then it is yielded without any expansion. """ if not isinstance(atom, Atom): atom = Atom(atom) if not atom.cp.startswith("virtual/"): yield atom return traversed = set() stack = [atom] while stack: atom = stack.pop() if atom.blocker or \ not atom.cp.startswith("virtual/"): yield atom continue matches = vardb.match(atom) if not (matches and matches[-1].startswith("virtual/")): yield atom continue virt_cpv = matches[-1] if virt_cpv in traversed: continue traversed.add(virt_cpv) eapi, iuse, rdepend, use = vardb.aux_get(virt_cpv, ["EAPI", "IUSE", "RDEPEND", "USE"]) if not portage.eapi_is_supported(eapi): yield atom continue # Validate IUSE and IUSE, for early detection of vardb corruption. useflag_re = _get_useflag_re(eapi) valid_iuse = [] for x in iuse.split(): if x[:1] in ("+", "-"): x = x[1:] if useflag_re.match(x) is not None: valid_iuse.append(x) valid_iuse = frozenset(valid_iuse) iuse_implicit_match = vardb.settings._iuse_implicit_match valid_use = [] for x in use.split(): if x in valid_iuse or iuse_implicit_match(x): valid_use.append(x) valid_use = frozenset(valid_use) success, atoms = portage.dep_check(rdepend, None, vardb.settings, myuse=valid_use, myroot=vardb.settings['EROOT'], trees={vardb.settings['EROOT']:{"porttree":vardb.vartree, "vartree":vardb.vartree}}) if success: stack.extend(atoms) else: yield atom
settings = portage.config(config_profile_path="", local_config=False) settings["ACCEPT_KEYWORDS"] = "**" settings.backup_changes("ACCEPT_KEYWORDS") settings.lock() porttree = portage.portagetree(settings=settings) portdb = porttree.dbapi trees = {"/" : {"porttree":porttree}} dep_keys = ("DEPEND", "RDEPEND", "PDEPEND") for cp in portdb.cp_all(): for cpv in portdb.cp_list(cp): metadata = dict(zip(dep_keys, portdb.aux_get(cpv, dep_keys))) dep_str = " ".join(metadata[k] for k in dep_keys) success, atoms = portage.dep_check(dep_str, None, settings, use="all", trees=trees, myroot=settings["ROOT"]) if not success: sys.stderr.write("%s %s\n" % (cpv, atoms)) else: bad_atoms = [] for atom in atoms: if not atom.blocker and atom.cp == input_atom.cp: matches = portdb.xmatch("match-all", atom) if not portage.dep.match_from_list(input_atom, matches): bad_atoms.append(atom) if bad_atoms: sys.stdout.write("%s\t%s\n" % (cpv, " ".join(bad_atoms)))
def expand_new_virt(vardb, atom): """ Iterate over the recursively expanded RDEPEND atoms of a new-style virtual. If atom is not a new-style virtual or it does not match an installed package then it is yielded without any expansion. """ if not isinstance(atom, Atom): atom = Atom(atom) if not atom.cp.startswith("virtual/"): yield atom return traversed = set() stack = [atom] while stack: atom = stack.pop() if atom.blocker or \ not atom.cp.startswith("virtual/"): yield atom continue matches = vardb.match(atom) if not (matches and matches[-1].startswith("virtual/")): yield atom continue virt_cpv = matches[-1] if virt_cpv in traversed: continue traversed.add(virt_cpv) eapi, iuse, rdepend, use = vardb.aux_get( virt_cpv, ["EAPI", "IUSE", "RDEPEND", "USE"]) if not portage.eapi_is_supported(eapi): yield atom continue eapi_attrs = _get_eapi_attrs(eapi) # Validate IUSE and IUSE, for early detection of vardb corruption. useflag_re = _get_useflag_re(eapi) valid_iuse = [] for x in iuse.split(): if x[:1] in ("+", "-"): x = x[1:] if useflag_re.match(x) is not None: valid_iuse.append(x) valid_iuse = frozenset(valid_iuse) if eapi_attrs.iuse_effective: iuse_implicit_match = vardb.settings._iuse_effective_match else: iuse_implicit_match = vardb.settings._iuse_implicit_match valid_use = [] for x in use.split(): if x in valid_iuse or iuse_implicit_match(x): valid_use.append(x) valid_use = frozenset(valid_use) success, atoms = portage.dep_check(rdepend, None, vardb.settings, myuse=valid_use, myroot=vardb.settings['EROOT'], trees={ vardb.settings['EROOT']: { "porttree": vardb.vartree, "vartree": vardb.vartree } }) if success: stack.extend(atoms) else: yield atom
def get_dep_packages(self, depvar=["RDEPEND", "PDEPEND", "DEPEND"], with_criterions=False, return_blocks=False): dep_pkgs = [] # the package list # change the useflags, because we have internally changed some, but not made them visible for portage actual = self.get_actual_use_flags() depstring = " ".join( self.get_package_settings(d, installed=False) for d in depvar) # let portage do the main stuff ;) # pay attention to any changes here deps = portage.dep_check(depstring, self._settings.vartree.dbapi, self._settings.settings, myuse=actual, trees=self._trees) if not deps: # FIXME: what is the difference to [1, []] ? return [] if deps[0] == 0: # error raise DependencyCalcError(deps[1]) deps = deps[1] def create_dep_pkgs_data(dep, pkg): """Returns the data to enter into the dep_pkgs list, which is either the package cpv or a tuple consisting of the cpv and the criterion.""" if with_criterions: return (pkg.get_cpv(), dep) else: return pkg.get_cpv() for dep in deps: if dep[0] == '!': # blocking sth blocked = system.find_packages(dep, system.SET_INSTALLED) if len(blocked ) == 1: # only exact one match allowed to be harmless if blocked[0].get_slot_cp() == self.get_slot_cp( ): # blocks in the same slot are harmless continue if return_blocks: if not blocked: if not system.find_packages(dep, masked=True): continue # well - no packages affected - ignore if with_criterions: dep_pkgs.append((dep, dep)) else: dep_pkgs.append(dep) elif blocked: raise BlockedException( (self.get_cpv(), blocked[0].get_cpv())) continue # finished with the blocking one -> next pkg = system.find_best_match(dep) if not pkg: # try to find masked ones pkgs = system.find_packages(dep, masked=True) if not pkgs: raise PackageNotFoundException(dep) pkgs = system.sort_package_list(pkgs) pkgs.reverse() done = False for p in pkgs: if not p.is_masked(): dep_pkgs.append(create_dep_pkgs_data(dep, p)) done = True break if not done: dep_pkgs.append(create_dep_pkgs_data(dep, pkgs[0])) else: dep_pkgs.append(create_dep_pkgs_data(dep, pkg)) return dep_pkgs
def depcheck(self, mycheck, use="yes", myusesplit=None): return dep_check(mycheck, self.dbapi, use=use, myuse=myusesplit)