Combine depgraph._select_dep() into create() so that
authorZac Medico <zmedico@gentoo.org>
Sun, 21 Oct 2007 23:23:42 +0000 (23:23 -0000)
committerZac Medico <zmedico@gentoo.org>
Sun, 21 Oct 2007 23:23:42 +0000 (23:23 -0000)
create() simply calls itself recursively. In order
to implement backtracking, create() will eventually
operate on a stack instead of calling itself.

svn path=/main/trunk/; revision=8221

pym/_emerge/__init__.py

index d76a244c4f0406a71d87955d5ec24d3edc665643..e08e3631033c12816b9406300d40f6e80ee0df98 100644 (file)
@@ -1417,14 +1417,80 @@ class depgraph(object):
                if arg:
                        depth = 0
                depth += 1
-
+               update = "--update" in self.myopts and depth <= 1
+               debug = "--debug" in self.myopts
+               buildpkgonly = "--buildpkgonly" in self.myopts
+               nodeps = "--nodeps" in self.myopts
+               empty = "empty" in self.myparams
+               deep = "deep" in self.myparams
+               strict = mytype != "installed"
                try:
                        for dep_root, dep_string, dep_priority in deps:
                                if not dep_string:
                                        continue
-                               if not self._select_dep(dep_root, dep_string, myuse,
-                                       jbigkey, depth, dep_priority):
+                               if debug:
+                                       print
+                                       print "Parent:   ", jbigkey
+                                       print "Depstring:", dep_string
+                                       print "Priority:", dep_priority
+                               vardb = self.roots[dep_root].trees["vartree"].dbapi
+                               try:
+                                       self._populate_filtered_repo(dep_root, dep_string,
+                                               myuse=myuse, strict=strict)
+                                       selected_atoms = self._select_atoms(dep_root,
+                                               dep_string, myuse=myuse, strict=strict)
+                               except portage.exception.InvalidDependString, e:
+                                       show_invalid_depstring_notice(jbigkey, dep_string, str(e))
                                        return 0
+                               if debug:
+                                       print "Candidates:", selected_atoms
+                               for x in selected_atoms:
+                                       selected_pkg = None
+                                       if x.startswith("!"):
+                                               if not buildpkgonly and \
+                                                       not nodeps and \
+                                                       jbigkey not in self._slot_collision_nodes:
+                                                       if mytype != "installed" and not addme:
+                                                               # It's safe to ignore blockers if the
+                                                               # parent is an --onlydeps node.
+                                                               continue
+                                                       # The blocker applies to the root where
+                                                       # th parent is or will be installed.
+                                                       self.blocker_parents.setdefault(
+                                                               ("blocks", myroot, x[1:]), set()).add(jbigkey)
+                                               continue
+                                       dep_pkg, existing_node = self._select_package(dep_root, x)
+                                       if not dep_pkg:
+                                               self._show_unsatisfied_dep(dep_root, x,
+                                                       myparent=jbigkey)
+                                               return 0
+                                       # In some cases, dep_check will return deps that shouldn't
+                                       # be proccessed any further, so they are identified and
+                                       # discarded here. Try to discard as few as possible since
+                                       # discarded dependencies reduce the amount of information
+                                       # available for optimization of merge order.
+                                       if vardb.match(x) and \
+                                               not (existing_node or empty or deep or update):
+                                               myarg = None
+                                               if dep_root == self.target_root:
+                                                       try:
+                                                               myarg = self._set_atoms.findAtomForPackage(
+                                                                       dep_pkg.cpv, dep_pkg.metadata)
+                                                       except portage.exception.InvalidDependString:
+                                                               if not dep_pkg.installed:
+                                                                       # This shouldn't happen since the package
+                                                                       # should have been masked.
+                                                                       raise
+                                               if not myarg:
+                                                       continue
+                                       mypriority = dep_priority.copy()
+                                       if vardb.match(x):
+                                               mypriority.satisfied = True
+                                       if not self.create(dep_pkg, myparent=jbigkey,
+                                               priority=mypriority, depth=depth):
+                                               return 0
+                               if debug:
+                                       print "Exiting...", jbigkey
                except ValueError, e:
                        if not e.args or not isinstance(e.args[0], list) or \
                                len(e.args[0]) < 2:
@@ -1651,7 +1717,7 @@ class depgraph(object):
                return (not missing,myfavorites)
 
        def _populate_filtered_repo(self, myroot, depstring,
-                       myparent=None, myuse=None, exclude_installed=False):
+                       strict=True, myuse=None, exclude_installed=False):
                """Extract all of the atoms from the depstring, select preferred
                packages from appropriate repositories, and use them to populate
                the filtered repository. This will raise InvalidDependString when
@@ -1660,13 +1726,10 @@ class depgraph(object):
                filtered_db = self._filtered_trees[myroot]["porttree"].dbapi
                pkgsettings = self.pkgsettings[myroot]
                usepkgonly = "--usepkgonly" in self.myopts
-               if myparent:
-                       p_type, p_root, p_key, p_status = myparent
 
                from portage.dep import paren_reduce, use_reduce
                try:
-                       if myparent and p_type == "installed":
-                               portage.dep._dep_check_strict = False
+                       portage.dep._dep_check_strict = strict
                        atoms = paren_reduce(depstring)
                        atoms = use_reduce(atoms, uselist=myuse)
                        atoms = list(iter_atoms(atoms))
@@ -1956,9 +2019,12 @@ class depgraph(object):
                                                        e_cpv, self._mydbapi_keys)))
                                                cpv_slot = "%s:%s" % (e_cpv, metadata["SLOT"])
                                                if portage.dep.match_from_list(atom, [cpv_slot]):
+                                                       e_installed = e_type == "installed"
+                                                       e_built = e_type != "ebuild"
                                                        matched_packages.append(
                                                                Package(type_name=e_type, root=root,
-                                                                       cpv=e_cpv, metadata=metadata))
+                                                                       cpv=e_cpv, metadata=metadata,
+                                                                       built=e_built, installed=e_installed))
                                                else:
                                                        existing_node = None
                                                break
@@ -2066,104 +2132,6 @@ class depgraph(object):
                # ordered by type preference ("ebuild" type is the last resort)
                return  matched_packages[-1], existing_node
 
-       def _select_dep(self, myroot, depstring, myuse,
-               myparent, depth, priority):
-               """ Given a depstring, create the depgraph such that all dependencies are satisfied.
-               @param myroot: $ROOT where these dependencies should be merged to.
-               @param myuse: List of USE flags enabled for myparent.
-               @param myparent: The node whose depstring is being passed in.
-               @param priority: DepPriority indicating the dependency type.
-               @param depth: The depth of recursion in dependencies relative to the
-                       nearest argument atom.
-               @returns: 1 on success and 0 on failure
-               """
-
-               if not depstring:
-                       return 1 # nothing to do
-
-               vardb  = self.roots[myroot].trees["vartree"].dbapi
-               strict = True
-               if myparent:
-                       p_type, p_root, p_key, p_status = myparent
-                       if p_type == "installed":
-                               strict = False
-
-               if "--debug" in self.myopts:
-                       print
-                       print "Parent:   ",myparent
-                       print "Depstring:",depstring
-                       print "Priority:", priority
-
-               try:
-                       self._populate_filtered_repo(
-                               myroot, depstring, myparent=myparent, myuse=myuse)
-                       mymerge = self._select_atoms(myroot, depstring,
-                               myuse=myuse, strict=strict)
-               except portage.exception.InvalidDependString, e:
-                       if myparent:
-                               show_invalid_depstring_notice(
-                                       myparent, depstring, str(e))
-                       else:
-                               sys.stderr.write("\n%s\n%s\n" % (depstring, str(e)))
-                       return 0
-
-               if "--debug" in self.myopts:
-                       print "Candidates:",mymerge
-               for x in mymerge:
-                       selected_pkg = None
-                       if x.startswith("!"):
-                               if "--buildpkgonly" not in self.myopts and \
-                                       "--nodeps" not in self.myopts and \
-                                       myparent not in self._slot_collision_nodes:
-                                       p_type, p_root, p_key, p_status = myparent
-                                       if  p_type != "installed" and p_status != "merge":
-                                               # It's safe to ignore blockers from --onlydeps nodes.
-                                               continue
-                                       self.blocker_parents.setdefault(
-                                               ("blocks", p_root, x[1:]), set()).add(myparent)
-                               continue
-                       else:
-
-                               pkg, existing_node = self._select_package(myroot, x)
-                               if not pkg:
-                                       self._show_unsatisfied_dep(myroot, x, myparent=myparent)
-                                       return 0
-
-                               # In some cases, dep_check will return deps that shouldn't
-                               # be proccessed any further, so they are identified and
-                               # discarded here. Try to discard as few as possible since
-                               # discarded dependencies reduce the amount of information
-                               # available for optimization of merge order.
-                               if myparent and vardb.match(x) and \
-                                       not existing_node and \
-                                       "empty" not in self.myparams and \
-                                       "deep" not in self.myparams and \
-                                       not ("--update" in self.myopts and depth <= 1):
-                                       myarg = None
-                                       if myroot == self.target_root:
-                                               try:
-                                                       myarg = self._set_atoms.findAtomForPackage(
-                                                               pkg.cpv, pkg.metadata)
-                                               except portage.exception.InvalidDependString:
-                                                       # This is already handled inside
-                                                       # self.create() when necessary.
-                                                       pass
-                                       if not myarg:
-                                               continue
-
-                       mypriority = None
-                       if myparent:
-                               mypriority = priority.copy()
-                               if vardb.match(x):
-                                       mypriority.satisfied = True
-                       if not self.create(pkg, myparent=myparent,
-                               priority=mypriority, depth=depth):
-                               return 0
-
-               if "--debug" in self.myopts:
-                       print "Exiting...",myparent
-               return 1
-
        def _select_arg(self, root, atom, arg, addme):
                pprovided = self.pkgsettings[root].pprovideddict.get(
                        portage.dep_getkey(atom))