For bug #184983, prevent USE_EXPAND_HIDDEN flags from being hidden if they are the...
authorZac Medico <zmedico@gentoo.org>
Thu, 12 Jul 2007 00:11:57 +0000 (00:11 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 12 Jul 2007 00:11:57 +0000 (00:11 -0000)
svn path=/main/branches/2.1.2/; revision=7238

bin/emerge

index 557d33fcdd740cd8a9e1153fd66122e415199899..3bbdc5a618953b43d37e7d95f69d128c85a87819 100755 (executable)
@@ -1083,6 +1083,8 @@ class depgraph:
                self.pkg_node_map = {}
                # Maps slot atom to digraph node for all nodes added to the graph.
                self._slot_node_map = {}
+               # Maps nodes to the reasons they were selected for reinstallation.
+               self._reinstall_nodes = {}
                self.mydbapi = {}
                self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND",
                        "USE", "IUSE", "PROVIDE", "RESTRICT"]
@@ -1204,18 +1206,23 @@ class depgraph:
 
        def _reinstall_for_flags(self, forced_flags,
                orig_use, orig_iuse, cur_use, cur_iuse):
+               """Return a set of flags that trigger reinstallation, or None if there
+               are no such flags."""
                if "--newuse" in self.myopts:
-                       if orig_iuse.symmetric_difference(
-                               cur_iuse).difference(forced_flags):
-                               return True
-                       elif orig_iuse.intersection(orig_use) != \
-                               cur_iuse.intersection(cur_use):
-                               return True
+                       flags = orig_iuse.symmetric_difference(
+                               cur_iuse).difference(forced_flags)
+                       if flags:
+                               return flags
+                       flags = orig_iuse.intersection(orig_use).symmetric_difference(
+                               cur_iuse.intersection(cur_use))
+                       if flags:
+                               return flags
                elif "changed-use" == self.myopts.get("--reinstall"):
-                       if orig_iuse.intersection(orig_use) != \
-                               cur_iuse.intersection(cur_use):
-                               return True
-               return False
+                       flags = orig_iuse.intersection(orig_use).symmetric_difference(
+                               cur_iuse.intersection(cur_use))
+                       if flags:
+                               return flags
+               return None
 
        def create(self, mybigkey, myparent=None, addme=1, myuse=None,
                priority=DepPriority(), rev_dep=False, arg=None):
@@ -1286,6 +1293,7 @@ class depgraph:
                                        return 0
                                del e
 
+               reinstall_for_flags = None
                merging=1
                if mytype == "installed":
                        merging = 0
@@ -1299,6 +1307,7 @@ class depgraph:
                            If the package has new iuse flags or different use flags then if
                            --newuse is specified, we need to merge the package. """
                        if merging == 0 and \
+                               myroot == self.target_root and \
                                ("--newuse" in self.myopts or
                                "--reinstall" in self.myopts) and \
                                vardbapi.cpv_exists(mykey):
@@ -1310,8 +1319,9 @@ class depgraph:
                                iuses = set(filter_iuse_defaults(metadata["IUSE"].split()))
                                old_iuse = set(filter_iuse_defaults(
                                        vardbapi.aux_get(mykey, ["IUSE"])[0].split()))
-                               if self._reinstall_for_flags(
-                                       forced_flags, old_use, old_iuse, myuse, iuses):
+                               reinstall_for_flags = self._reinstall_for_flags(
+                                       forced_flags, old_use, old_iuse, myuse, iuses)
+                               if reinstall_for_flags:
                                        merging = 1
 
                if addme and merging == 1:
@@ -1379,6 +1389,8 @@ class depgraph:
                                self._slot_node_map[myroot][slot_atom] = jbigkey
                                self.pkg_node_map[myroot][mykey] = jbigkey
                                self.useFlags[myroot][mykey] = myuse
+                               if reinstall_for_flags:
+                                       self._reinstall_nodes[jbigkey] = reinstall_for_flags
 
                        if rev_dep and myparent:
                                self.digraph.addnode(myparent, jbigkey,
@@ -2874,7 +2886,8 @@ class depgraph:
                                        use_expand_hidden = \
                                                pkgsettings["USE_EXPAND_HIDDEN"].lower().split()
 
-                                       def map_to_use_expand(myvals, forcedFlags=False):
+                                       def map_to_use_expand(myvals, forcedFlags=False,
+                                               removeHidden=True):
                                                ret = {}
                                                forced = {}
                                                for exp in use_expand:
@@ -2889,13 +2902,32 @@ class depgraph:
                                                ret["USE"] = myvals
                                                forced["USE"] = [val for val in myvals \
                                                        if val in forced_flags]
-                                               for exp in use_expand_hidden:
-                                                       if exp in ret:
-                                                               del ret[exp]
+                                               if removeHidden:
+                                                       for exp in use_expand_hidden:
+                                                               ret.pop(exp, None)
                                                if forcedFlags:
                                                        return ret, forced
                                                return ret
 
+                                       # Prevent USE_EXPAND_HIDDEN flags from being hidden if they
+                                       # are the only thing that triggered reinstallation.
+                                       reinst_flags_map = None
+                                       reinstall_for_flags = self._reinstall_nodes.get(pkg_node)
+                                       if reinstall_for_flags:
+                                               reinst_flags_map = map_to_use_expand(
+                                                       list(reinstall_for_flags), removeHidden=False)
+                                               if reinst_flags_map["USE"]:
+                                                       reinst_flags_map = None
+                                               else:
+                                                       for k in reinst_flags_map.keys():
+                                                               if not reinst_flags_map[k]:
+                                                                       del reinst_flags_map[k]
+                                       if reinst_flags_map and \
+                                               not set(reinst_flags_map).difference(
+                                               use_expand_hidden):
+                                               use_expand_hidden = set(use_expand_hidden).difference(
+                                                       reinst_flags_map)
+
                                        cur_iuse_map, iuse_forced = \
                                                map_to_use_expand(cur_iuse, forcedFlags=True)
                                        cur_use_map = map_to_use_expand(cur_use)