Improve --resume handling of saved "favorites" argument atoms:
authorZac Medico <zmedico@gentoo.org>
Sat, 3 May 2008 19:00:47 +0000 (19:00 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 3 May 2008 19:00:47 +0000 (19:00 -0000)
* Save the favorites in oneshot mode too since they're still useful for
  restoring state upon --resume.

* Add a depgraph._load_favorites() method to resume state from a previous
  select_files() call. This allows Package instances to be matched with
  DependencyArg instances during graph creation.

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

pym/_emerge/__init__.py

index 133c80419ca533d6d2659eb3b5caba347cd5a047..ae01ffd93e8cd398224a42ccabb50781cf87ddc2 100644 (file)
@@ -2285,8 +2285,6 @@ class depgraph(object):
                root_config = self.roots[self.target_root]
                sets = root_config.sets
                getSetAtoms = root_config.setconfig.getSetAtoms
-               oneshot = "--oneshot" in self.myopts or \
-                       "--onlydeps" in self.myopts
                myfavorites=[]
                myroot = self.target_root
                dbs = self._filtered_trees[myroot]["dbs"]
@@ -2410,8 +2408,7 @@ class depgraph(object):
                                        self._sets[s] = expanded_set
                                        args.append(SetArg(arg=x, set=expanded_set,
                                                root_config=root_config))
-                                       if not oneshot:
-                                               myfavorites.append(x)
+                                       myfavorites.append(x)
                                        continue
                                if not is_valid_package_atom(x):
                                        portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
@@ -2498,8 +2495,7 @@ class depgraph(object):
                        if myatom in args_set:
                                continue
                        args_set.add(myatom)
-                       if not oneshot:
-                               myfavorites.append(myatom)
+                       myfavorites.append(myatom)
                self._set_atoms.update(chain(*self._sets.itervalues()))
                atom_arg_map = self._atom_arg_map
                for arg in args:
@@ -4761,11 +4757,13 @@ class depgraph(object):
                Add a resume command to the graph and validate it in the process.  This
                will raise a PackageNotFound exception if a package is not available.
                """
-               self._sets["args"].update(resume_data.get("favorites", []))
-               mergelist = resume_data.get("mergelist", [])
+
+               if not isinstance(resume_data, dict):
+                       return False
                favorites = resume_data.get("favorites")
-               if not isinstance(favorites, list):
-                       favorites = []
+               if isinstance(favorites, list):
+                       self._load_favorites(resume_data)
+               mergelist = resume_data.get("mergelist", [])
 
                if mergelist and "--skipfirst" in self.myopts:
                        for i, task in enumerate(mergelist):
@@ -4822,15 +4820,9 @@ class depgraph(object):
                if not serialized_tasks or "--nodeps" in self.myopts:
                        self._serialized_tasks_cache = serialized_tasks
                else:
-                       favorites_set = InternalPackageSet(atom for atom in favorites \
-                               if isinstance(atom, basestring) and portage.isvalidatom(atom))
-                       for node in serialized_tasks:
-                               if isinstance(node, Package) and \
-                                       node.operation == "merge" and \
-                                       favorites_set.findAtomForPackage(node.cpv, node.metadata):
-                                       self._set_nodes.add(node)
-
                        self._select_package = self._select_pkg_from_graph
+                       self.myparams.add("selective")
+
                        for task in serialized_tasks:
                                if isinstance(task, Package) and \
                                        task.operation == "merge":
@@ -4854,13 +4846,68 @@ class depgraph(object):
                        except self._unknown_internal_error:
                                return False
 
-                       for node in self.digraph.root_nodes():
-                               if isinstance(node, Package) and \
-                                       node.operation == "merge":
-                                       # Give hint to the --tree display.
-                                       self._set_nodes.add(node)
                return True
 
+       def _load_favorites(self, favorites):
+               """
+               Use a list of favorites to resume state from a
+               previous select_files() call. This creates similar
+               DependencyArg instances to those that would have
+               been created by the original select_files() call.
+               This allows Package instances to be matched with
+               DependencyArg instances during graph creation.
+               """
+               root_config = self.roots[self.target_root]
+               getSetAtoms = root_config.setconfig.getSetAtoms
+               sets = root_config.sets
+               args = []
+               for x in favorites:
+                       if not isinstance(x, basestring):
+                               continue
+                       if x in ("system", "world"):
+                               x = SETPREFIX + x
+                       if x.startswith(SETPREFIX):
+                               s = x[len(SETPREFIX):]
+                               if s not in sets:
+                                       continue
+                               if s in self._sets:
+                                       continue
+                               # Recursively expand sets so that containment tests in
+                               # self._get_parent_sets() properly match atoms in nested
+                               # sets (like if world contains system).
+                               expanded_set = InternalPackageSet(
+                                       initial_atoms=getSetAtoms(s))
+                               self._sets[s] = expanded_set
+                               args.append(SetArg(arg=x, set=expanded_set,
+                                       root_config=root_config))
+                       else:
+                               if not portage.isvalidatom(x):
+                                       continue
+                               args.append(AtomArg(arg=x, atom=x,
+                                       root_config=root_config))
+
+               # Create the "args" package set from atoms and
+               # packages given as arguments.
+               args_set = self._sets["args"]
+               for arg in args:
+                       if not isinstance(arg, (AtomArg, PackageArg)):
+                               continue
+                       myatom = arg.atom
+                       if myatom in args_set:
+                               continue
+                       args_set.add(myatom)
+               self._set_atoms.update(chain(*self._sets.itervalues()))
+               atom_arg_map = self._atom_arg_map
+               for arg in args:
+                       for atom in arg.set:
+                               atom_key = (atom, arg.root_config.root)
+                               refs = atom_arg_map.get(atom_key)
+                               if refs is None:
+                                       refs = []
+                                       atom_arg_map[atom_key] = refs
+                                       if arg not in refs:
+                                               refs.append(arg)
+
        class _internal_exception(portage.exception.PortageException):
                def __init__(self, value=""):
                        portage.exception.PortageException.__init__(self, value)
@@ -5202,6 +5249,8 @@ class MergeTask(object):
                failed_fetches = []
                fetchonly = "--fetchonly" in self.myopts or \
                        "--fetch-all-uri" in self.myopts
+               oneshot = "--oneshot" in self.myopts or \
+                       "--onlydeps" in self.myopts
                pretend = "--pretend" in self.myopts
                ldpath_mtimes = mtimedb["ldpath"]
                xterm_titles = "notitles" not in self.settings.features
@@ -5555,10 +5604,8 @@ class MergeTask(object):
                                if retval != os.EX_OK:
                                        return retval
                                #need to check for errors
-                       if "--buildpkgonly" not in self.myopts:
-                               self.trees[x[1]]["vartree"].inject(x[2])
-                               myfavkey = portage.cpv_getkey(x[2])
-                               if not fetchonly and not pretend and \
+                       if not buildpkgonly:
+                               if not (fetchonly or oneshot or pretend) and \
                                        args_set.findAtomForPackage(pkg_key, metadata):
                                        world_set.lock()
                                        world_set.load() # maybe it's changed on disk