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"]
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):
return 0
del e
+ reinstall_for_flags = None
merging=1
if mytype == "installed":
merging = 0
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):
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:
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,
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:
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)