# Copyright 1999-2020 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import collections from itertools import chain from portage.output import red from portage.util import cmp_sort_key from portage.output import blue class UseFlagDisplay: __slots__ = ("name", "enabled", "forced") def __init__(self, name, enabled, forced): self.name = name self.enabled = enabled self.forced = forced def __str__(self): s = self.name if self.enabled: s = red(s) else: s = "-" + s s = blue(s) if self.forced: s = f"({s})" return s def _cmp_combined(a, b): """ Sort by name, combining enabled and disabled flags. """ return (a.name > b.name) - (a.name < b.name) sort_combined = cmp_sort_key(_cmp_combined) del _cmp_combined def _cmp_separated(a, b): """ Sort by name, separating enabled flags from disabled flags. """ enabled_diff = b.enabled - a.enabled if enabled_diff: return enabled_diff return (a.name > b.name) - (a.name < b.name) sort_separated = cmp_sort_key(_cmp_separated) del _cmp_separated _flag_info = collections.namedtuple("_flag_info", ("flag", "display")) def pkg_use_display(pkg, opts, modified_use=None): settings = pkg.root_config.settings use_expand = pkg.use.expand use_expand_hidden = pkg.use.expand_hidden alphabetical_use = "--alphabetical" in opts forced_flags = set(chain(pkg.use.force, pkg.use.mask)) if modified_use is None: use = set(pkg.use.enabled) else: use = set(modified_use) use.discard(settings.get("ARCH")) use_expand_flags = set() use_enabled = {} use_disabled = {} for varname in use_expand: flag_prefix = varname.lower() + "_" for f in use: if f.startswith(flag_prefix): use_expand_flags.add(f) use_enabled.setdefault(varname.upper(), []).append( _flag_info(f, f[len(flag_prefix) :]) ) for f in pkg.iuse.all: if f.startswith(flag_prefix): use_expand_flags.add(f) if f not in use: use_disabled.setdefault(varname.upper(), []).append( _flag_info(f, f[len(flag_prefix) :]) ) var_order = set(use_enabled) var_order.update(use_disabled) var_order = sorted(var_order) var_order.insert(0, "USE") use.difference_update(use_expand_flags) use_enabled["USE"] = list(_flag_info(f, f) for f in use) use_disabled["USE"] = [] for f in pkg.iuse.all: if f not in use and f not in use_expand_flags: use_disabled["USE"].append(_flag_info(f, f)) flag_displays = [] for varname in var_order: if varname.lower() in use_expand_hidden: continue flags = [] for f in use_enabled.get(varname, []): flags.append(UseFlagDisplay(f.display, True, f.flag in forced_flags)) for f in use_disabled.get(varname, []): flags.append(UseFlagDisplay(f.display, False, f.flag in forced_flags)) if alphabetical_use: flags.sort(key=UseFlagDisplay.sort_combined) else: flags.sort(key=UseFlagDisplay.sort_separated) flag_displays.append(f"{varname}=\"{' '.join(f'{f}' for f in flags)}\"") return " ".join(flag_displays)