# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import collections
import logging
import operator
import platform
import re
import signal
import subprocess
import sys
import tempfile
import textwrap
import time
import warnings
from itertools import chain

import portage

portage.proxy.lazyimport.lazyimport(
    globals(),
    "portage.dbapi._similar_name_search:similar_name_search",
    "portage.debug",
    "portage.news:count_unread_news,display_news_notifications",
    "portage.util._get_vm_info:get_vm_info",
    "portage.util.locale:check_locale",
    "portage.emaint.modules.sync.sync:SyncRepos",
    "_emerge.chk_updated_cfg_files:chk_updated_cfg_files",
    "_emerge.help:emerge_help",
    "_emerge.post_emerge:display_news_notification,post_emerge",
    "_emerge.stdout_spinner:stdout_spinner",
)

from portage import os
from portage import shutil
from portage import _encodings, _unicode_decode
from portage.binrepo.config import BinRepoConfigLoader
from portage.const import BINREPOS_CONF_FILE, _DEPCLEAN_LIB_CHECK_DEFAULT
from portage.dbapi.dep_expand import dep_expand
from portage.dbapi._expand_new_virt import expand_new_virt
from portage.dbapi.IndexedPortdb import IndexedPortdb
from portage.dbapi.IndexedVardb import IndexedVardb
from portage.dep import Atom, _repo_separator, _slot_separator
from portage.exception import InvalidAtom, InvalidData, ParseError, GPGException
from portage.output import (
    colorize,
    create_color_func,
    darkgreen,
    red,
    xtermTitle,
    xtermTitleReset,
)

good = create_color_func("GOOD")
bad = create_color_func("BAD")
warn = create_color_func("WARN")
from portage.package.ebuild._ipc.QueryCommand import QueryCommand
from portage.package.ebuild.fetch import _hide_url_passwd
from portage._sets import load_default_config, SETPREFIX
from portage._sets.base import InternalPackageSet
from portage.util import (
    cmp_sort_key,
    normalize_path,
    writemsg,
    varexpand,
    writemsg_level,
    writemsg_stdout,
)
from portage.util.digraph import digraph
from portage.util.path import first_existing
from portage.util.SlotObject import SlotObject
from portage.util._async.run_main_scheduler import run_main_scheduler
from portage.util._async.SchedulerInterface import SchedulerInterface
from portage.util._eventloop.global_event_loop import global_event_loop
from portage._global_updates import _global_updates
from portage.sync.old_tree_timestamp import old_tree_timestamp_warn
from portage.localization import _
from portage.metadata import action_metadata
from portage.emaint.main import print_results
from portage.gpg import GPG
from portage.binpkg import get_binpkg_format

from _emerge.clear_caches import clear_caches
from _emerge.create_depgraph_params import create_depgraph_params
from _emerge.Dependency import Dependency
from _emerge.depgraph import backtrack_depgraph, depgraph, resume_depgraph
from _emerge.emergelog import emergelog
from _emerge.is_valid_package_atom import is_valid_package_atom
from _emerge.main import profile_check
from _emerge.MetadataRegen import MetadataRegen
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig
from _emerge.Scheduler import Scheduler
from _emerge.search import search
from _emerge.SetArg import SetArg
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
from _emerge.unmerge import unmerge
from _emerge.UnmergeDepPriority import UnmergeDepPriority
from _emerge.UseFlagDisplay import pkg_use_display
from _emerge.UserQuery import UserQuery


def action_build(
    emerge_config,
    trees=DeprecationWarning,
    mtimedb=DeprecationWarning,
    myopts=DeprecationWarning,
    myaction=DeprecationWarning,
    myfiles=DeprecationWarning,
    spinner=None,
):

    if not isinstance(emerge_config, _emerge_config):
        warnings.warn(
            "_emerge.actions.action_build() now expects "
            "an _emerge_config instance as the first parameter",
            DeprecationWarning,
            stacklevel=2,
        )
        emerge_config = load_emerge_config(
            action=myaction, args=myfiles, trees=trees, opts=myopts
        )
        adjust_configs(emerge_config.opts, emerge_config.trees)

    settings, trees, mtimedb = emerge_config
    myopts = emerge_config.opts
    myaction = emerge_config.action
    myfiles = emerge_config.args

    if "--usepkgonly" not in myopts:
        old_tree_timestamp_warn(settings["PORTDIR"], settings)

    # It's best for config updates in /etc/portage to be processed
    # before we get here, so warn if they're not (bug #267103).
    chk_updated_cfg_files(settings["EROOT"], ["/etc/portage"])

    quickpkg_root = (
        normalize_path(
            os.path.abspath(
                emerge_config.opts.get(
                    "--quickpkg-direct-root",
                    emerge_config.running_config.settings["ROOT"],
                )
            )
        ).rstrip(os.path.sep)
        + os.path.sep
    )
    quickpkg_direct = (
        "--usepkg" in emerge_config.opts
        and emerge_config.opts.get("--quickpkg-direct", "n") == "y"
        and emerge_config.target_config.settings["ROOT"] != quickpkg_root
    )
    if "--getbinpkg" in emerge_config.opts or quickpkg_direct:
        kwargs = {}
        if quickpkg_direct:
            if quickpkg_root == emerge_config.running_config.settings["ROOT"]:
                quickpkg_vardb = emerge_config.running_config.trees["vartree"].dbapi
            else:
                quickpkg_settings = portage.config(
                    config_root=emerge_config.target_config.settings[
                        "PORTAGE_CONFIGROOT"
                    ],
                    target_root=quickpkg_root,
                    env=emerge_config.target_config.settings.backupenv.copy(),
                    sysroot=emerge_config.target_config.settings["SYSROOT"],
                    eprefix=emerge_config.target_config.settings["EPREFIX"],
                )
                quickpkg_vardb = portage.vartree(settings=quickpkg_settings).dbapi
            kwargs["add_repos"] = (quickpkg_vardb,)

        try:
            emerge_config.target_config.trees["bintree"].populate(
                getbinpkgs="--getbinpkg" in emerge_config.opts, **kwargs
            )
        except ParseError as e:
            writemsg("\n\n!!!%s.\nSee make.conf(5) for more info.\n" % e, noiselevel=-1)
            return 1

    # validate the state of the resume data
    # so that we can make assumptions later.
    for k in ("resume", "resume_backup"):
        if k not in mtimedb:
            continue
        resume_data = mtimedb[k]
        if not isinstance(resume_data, dict):
            del mtimedb[k]
            continue
        mergelist = resume_data.get("mergelist")
        if not isinstance(mergelist, list):
            del mtimedb[k]
            continue
        for x in mergelist:
            if not (isinstance(x, list) and len(x) == 4):
                continue
            pkg_type, pkg_root, pkg_key, pkg_action = x
            if pkg_root not in trees:
                # Current $ROOT setting differs,
                # so the list must be stale.
                mergelist = None
                break
        if not mergelist:
            del mtimedb[k]
            continue
        resume_opts = resume_data.get("myopts")
        if not isinstance(resume_opts, (dict, list)):
            del mtimedb[k]
            continue
        favorites = resume_data.get("favorites")
        if not isinstance(favorites, list):
            del mtimedb[k]
            continue

    resume = False
    if "--resume" in myopts and ("resume" in mtimedb or "resume_backup" in mtimedb):
        resume = True
        if "resume" not in mtimedb:
            mtimedb["resume"] = mtimedb["resume_backup"]
            del mtimedb["resume_backup"]
            mtimedb.commit()
        # "myopts" is a list for backward compatibility.
        resume_opts = mtimedb["resume"].get("myopts", [])
        if isinstance(resume_opts, list):
            resume_opts = dict((k, True) for k in resume_opts)
        for opt in ("--ask", "--color", "--skipfirst", "--tree"):
            resume_opts.pop(opt, None)

        # Current options always override resume_opts.
        resume_opts.update(myopts)
        myopts.clear()
        myopts.update(resume_opts)

        if "--debug" in myopts:
            writemsg_level("myopts %s\n" % (myopts,))

        # Adjust config according to options of the command being resumed.
        for myroot in trees:
            mysettings = trees[myroot]["vartree"].settings
            mysettings.unlock()
            adjust_config(myopts, mysettings)
            mysettings.lock()
            del myroot, mysettings

    ldpath_mtimes = mtimedb["ldpath"]
    favorites = []
    buildpkgonly = "--buildpkgonly" in myopts
    pretend = "--pretend" in myopts
    fetchonly = "--fetchonly" in myopts or "--fetch-all-uri" in myopts
    ask = "--ask" in myopts
    enter_invalid = "--ask-enter-invalid" in myopts
    nodeps = "--nodeps" in myopts
    oneshot = "--oneshot" in myopts or "--onlydeps" in myopts
    tree = "--tree" in myopts
    if nodeps and tree:
        tree = False
        del myopts["--tree"]
        portage.writemsg(
            colorize("WARN", " * ") + "--tree is broken with --nodeps. Disabling...\n"
        )
    debug = "--debug" in myopts
    verbose = "--verbose" in myopts
    quiet = "--quiet" in myopts
    myparams = create_depgraph_params(myopts, myaction)
    mergelist_shown = False

    if pretend or fetchonly:
        mtimedb.make_readonly()
    if "--digest" in myopts or "digest" in settings.features:
        if "--digest" in myopts:
            msg = "The --digest option"
        else:
            msg = "The FEATURES=digest setting"

        msg += (
            " can prevent corruption from being"
            + " noticed. The `repoman manifest` command is the preferred"
            + " way to generate manifests and it is capable of doing an"
            + " entire repository or category at once."
        )
        prefix = bad(" * ")
        writemsg(prefix + "\n")
        for line in textwrap.wrap(msg, 72):
            writemsg("%s%s\n" % (prefix, line))
        writemsg(prefix + "\n")

    if resume:
        favorites = mtimedb["resume"].get("favorites")
        if not isinstance(favorites, list):
            favorites = []

        resume_data = mtimedb["resume"]
        mergelist = resume_data["mergelist"]
        if mergelist and "--skipfirst" in myopts:
            for i, task in enumerate(mergelist):
                if isinstance(task, list) and task and task[-1] == "merge":
                    del mergelist[i]
                    break

        success = False
        mydepgraph = None
        try:
            success, mydepgraph, dropped_tasks = resume_depgraph(
                settings, trees, mtimedb, myopts, myparams, spinner
            )
        except (portage.exception.PackageNotFound, depgraph.UnsatisfiedResumeDep) as e:
            if isinstance(e, depgraph.UnsatisfiedResumeDep):
                mydepgraph = e.depgraph

            from portage.output import EOutput

            out = EOutput()

            resume_data = mtimedb["resume"]
            mergelist = resume_data.get("mergelist")
            if not isinstance(mergelist, list):
                mergelist = []
            if mergelist and debug or (verbose and not quiet):
                out.eerror("Invalid resume list:")
                out.eerror("")
                indent = "  "
                for task in mergelist:
                    if isinstance(task, list):
                        out.eerror(indent + str(tuple(task)))
                out.eerror("")

            if isinstance(e, depgraph.UnsatisfiedResumeDep):
                out.eerror(
                    "One or more packages are either masked or "
                    + "have missing dependencies:"
                )
                out.eerror("")
                indent = "  "
                for dep in e.value:
                    if dep.atom is None:
                        out.eerror(indent + "Masked package:")
                        out.eerror(2 * indent + str(dep.parent))
                        out.eerror("")
                    else:
                        out.eerror(indent + str(dep.atom) + " pulled in by:")
                        out.eerror(2 * indent + str(dep.parent))
                        out.eerror("")
                msg = (
                    "The resume list contains packages "
                    + "that are either masked or have "
                    + "unsatisfied dependencies. "
                    + "Please restart/continue "
                    + "the operation manually, or use --skipfirst "
                    + "to skip the first package in the list and "
                    + "any other packages that may be "
                    + "masked or have missing dependencies."
                )
                for line in textwrap.wrap(msg, 72):
                    out.eerror(line)
            elif isinstance(e, portage.exception.PackageNotFound):
                out.eerror("An expected package is " + "not available: %s" % str(e))
                out.eerror("")
                msg = (
                    "The resume list contains one or more "
                    + "packages that are no longer "
                    + "available. Please restart/continue "
                    + "the operation manually."
                )
                for line in textwrap.wrap(msg, 72):
                    out.eerror(line)

        if success:
            if dropped_tasks:
                portage.writemsg(
                    "!!! One or more packages have been "
                    + "dropped due to\n"
                    + "!!! masking or unsatisfied dependencies:\n\n",
                    noiselevel=-1,
                )
                for task, atoms in dropped_tasks.items():
                    if not atoms:
                        writemsg(
                            "  %s is masked or unavailable\n" % (task,), noiselevel=-1
                        )
                    else:
                        writemsg(
                            "  %s requires %s\n" % (task, ", ".join(atoms)),
                            noiselevel=-1,
                        )

                portage.writemsg("\n", noiselevel=-1)
            del dropped_tasks
        else:
            if mydepgraph is not None:
                mydepgraph.display_problems()
            if not (ask or pretend):
                # delete the current list and also the backup
                # since it's probably stale too.
                for k in ("resume", "resume_backup"):
                    mtimedb.pop(k, None)
                mtimedb.commit()

            return 1
    else:
        if "--resume" in myopts:
            print(darkgreen("emerge: It seems we have nothing to resume..."))
            return os.EX_OK

        try:
            success, mydepgraph, favorites = backtrack_depgraph(
                settings, trees, myopts, myparams, myaction, myfiles, spinner
            )
        except portage.exception.PackageSetNotFound as e:
            root_config = trees[settings["EROOT"]]["root_config"]
            display_missing_pkg_set(root_config, e.value)
            return 1

        if success and mydepgraph.need_config_reload():
            load_emerge_config(emerge_config=emerge_config)
            adjust_configs(emerge_config.opts, emerge_config.trees)
            settings, trees, mtimedb = emerge_config

            # After config reload, the freshly instantiated binarytree
            # instances need to load remote metadata if --getbinpkg
            # is enabled. Use getbinpkg_refresh=False to use cached
            # metadata, since the cache is already fresh.
            if "--getbinpkg" in emerge_config.opts or quickpkg_direct:
                for root_trees in emerge_config.trees.values():
                    kwargs = {}
                    if quickpkg_direct:
                        kwargs["add_repos"] = (
                            emerge_config.running_config.trees["vartree"].dbapi,
                        )

                    try:
                        root_trees["bintree"].populate(
                            getbinpkgs=True, getbinpkg_refresh=False, **kwargs
                        )
                    except ParseError as e:
                        writemsg(
                            "\n\n!!!%s.\nSee make.conf(5) for more info.\n" % e,
                            noiselevel=-1,
                        )
                        return 1

        if "--autounmask-only" in myopts:
            mydepgraph.display_problems()
            return 0

        if not success:
            mydepgraph.display_problems()
            return 1

    mergecount = None
    if (
        "--pretend" not in myopts
        and ("--ask" in myopts or "--tree" in myopts or "--verbose" in myopts)
        and not ("--quiet" in myopts and "--ask" not in myopts)
    ):
        if "--resume" in myopts:
            mymergelist = mydepgraph.altlist()
            if len(mymergelist) == 0:
                print(
                    colorize("INFORM", "emerge: It seems we have nothing to resume...")
                )
                return os.EX_OK
            favorites = mtimedb["resume"]["favorites"]
            retval = mydepgraph.display(mydepgraph.altlist(), favorites=favorites)
            mydepgraph.display_problems()
            mergelist_shown = True
            if retval != os.EX_OK:
                return retval
            prompt = "Would you like to resume merging these packages?"
        else:
            retval = mydepgraph.display(mydepgraph.altlist(), favorites=favorites)
            mydepgraph.display_problems()
            mergelist_shown = True
            if retval != os.EX_OK:
                return retval
            mergecount = 0
            for x in mydepgraph.altlist():
                if isinstance(x, Package) and x.operation == "merge":
                    mergecount += 1

            prompt = None
            if mergecount == 0:
                sets = trees[settings["EROOT"]]["root_config"].sets
                world_candidates = None
                if "selective" in myparams and not oneshot and favorites:
                    # Sets that are not world candidates are filtered
                    # out here since the favorites list needs to be
                    # complete for depgraph.loadResumeCommand() to
                    # operate correctly.
                    world_candidates = [
                        x
                        for x in favorites
                        if not (
                            x.startswith(SETPREFIX) and not sets[x[1:]].world_candidate
                        )
                    ]

                if "selective" in myparams and not oneshot and world_candidates:
                    # Prompt later, inside saveNomergeFavorites.
                    prompt = None
                else:
                    print()
                    print("Nothing to merge; quitting.")
                    print()
                    return os.EX_OK
            elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
                prompt = "Would you like to fetch the source files for these packages?"
            else:
                prompt = "Would you like to merge these packages?"
        print()
        uq = UserQuery(myopts)
        if (
            prompt is not None
            and "--ask" in myopts
            and uq.query(prompt, enter_invalid) == "No"
        ):
            print()
            print("Quitting.")
            print()
            return 128 + signal.SIGINT
        # Don't ask again (e.g. when auto-cleaning packages after merge)
        if mergecount != 0:
            myopts.pop("--ask", None)

    if ("--pretend" in myopts) and not (
        "--fetchonly" in myopts or "--fetch-all-uri" in myopts
    ):
        if "--resume" in myopts:
            mymergelist = mydepgraph.altlist()
            if len(mymergelist) == 0:
                print(
                    colorize("INFORM", "emerge: It seems we have nothing to resume...")
                )
                return os.EX_OK
            favorites = mtimedb["resume"]["favorites"]
            retval = mydepgraph.display(mydepgraph.altlist(), favorites=favorites)
            mydepgraph.display_problems()
            mergelist_shown = True
            if retval != os.EX_OK:
                return retval
        else:
            retval = mydepgraph.display(mydepgraph.altlist(), favorites=favorites)
            mydepgraph.display_problems()
            mergelist_shown = True
            if retval != os.EX_OK:
                return retval

    else:

        if not mergelist_shown:
            # If we haven't already shown the merge list above, at
            # least show warnings about missed updates and such.
            mydepgraph.display_problems()

        need_write_vardb = not Scheduler._opts_no_self_update.intersection(myopts)

        need_write_bindb = not any(
            x in myopts
            for x in ("--fetchonly", "--fetch-all-uri", "--pretend", "--usepkgonly")
        ) and (
            any(
                "buildpkg" in trees[eroot]["root_config"].settings.features
                for eroot in trees
            )
            or any(
                "buildsyspkg" in trees[eroot]["root_config"].settings.features
                for eroot in trees
            )
        )

        if need_write_bindb or need_write_vardb:

            eroots = set()
            ebuild_eroots = set()
            for x in mydepgraph.altlist():
                if isinstance(x, Package) and x.operation == "merge":
                    eroots.add(x.root)
                    if x.type_name == "ebuild":
                        ebuild_eroots.add(x.root)

            for eroot in eroots:
                if need_write_vardb and not trees[eroot]["vartree"].dbapi.writable:
                    writemsg_level(
                        "!!! %s\n"
                        % _("Read-only file system: %s")
                        % trees[eroot]["vartree"].dbapi._dbroot,
                        level=logging.ERROR,
                        noiselevel=-1,
                    )
                    return 1

                if (
                    need_write_bindb
                    and eroot in ebuild_eroots
                    and (
                        "buildpkg" in trees[eroot]["root_config"].settings.features
                        or "buildsyspkg"
                        in trees[eroot]["root_config"].settings.features
                    )
                    and not trees[eroot]["bintree"].dbapi.writable
                ):
                    writemsg_level(
                        "!!! %s\n"
                        % _("Read-only file system: %s")
                        % trees[eroot]["bintree"].pkgdir,
                        level=logging.ERROR,
                        noiselevel=-1,
                    )
                    return 1

                # unlock GPG if needed
                if (
                    need_write_bindb
                    and (eroot in ebuild_eroots)
                    and (
                        "binpkg-signing"
                        in trees[eroot]["root_config"].settings.features
                    )
                ):
                    for binpkg_gpg_config in (
                        "BINPKG_GPG_SIGNING_GPG_HOME",
                        "BINPKG_GPG_SIGNING_KEY",
                    ):
                        if not trees[eroot]["root_config"].settings.get(
                            binpkg_gpg_config
                        ):
                            writemsg_level(
                                colorize(
                                    "BAD", f"!!! {binpkg_gpg_config} is not set\n"
                                ),
                                level=logging.ERROR,
                                noiselevel=-1,
                            )
                            return 1

                    portage.writemsg_stdout(">>> Unlocking GPG... ")
                    sys.stdout.flush()
                    gpg = GPG(trees[eroot]["root_config"].settings)
                    try:
                        gpg.unlock()
                    except GPGException as e:
                        writemsg_level(
                            colorize("BAD", "!!! %s\n" % e),
                            level=logging.ERROR,
                            noiselevel=-1,
                        )
                        return 1

        if "--resume" in myopts:
            favorites = mtimedb["resume"]["favorites"]

        else:
            if (
                "resume" in mtimedb
                and "mergelist" in mtimedb["resume"]
                and len(mtimedb["resume"]["mergelist"]) > 1
            ):
                mtimedb["resume_backup"] = mtimedb["resume"]
                del mtimedb["resume"]
                mtimedb.commit()

            mydepgraph.saveNomergeFavorites()

        if mergecount == 0:
            retval = os.EX_OK
        else:
            mergetask = Scheduler(
                settings,
                trees,
                mtimedb,
                myopts,
                spinner,
                favorites=favorites,
                graph_config=mydepgraph.schedulerGraph(),
            )

            del mydepgraph
            clear_caches(trees)

            retval = mergetask.merge()

            if retval == os.EX_OK and not (buildpkgonly or fetchonly or pretend):
                if "yes" == settings.get("AUTOCLEAN"):
                    portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
                    unmerge(
                        trees[settings["EROOT"]]["root_config"],
                        myopts,
                        "clean",
                        [],
                        ldpath_mtimes,
                        autoclean=1,
                    )

        return retval


def action_config(settings, trees, myopts, myfiles):
    enter_invalid = "--ask-enter-invalid" in myopts
    uq = UserQuery(myopts)
    if len(myfiles) != 1:
        print(red("!!! config can only take a single package atom at this time\n"))
        sys.exit(1)
    if not is_valid_package_atom(myfiles[0], allow_repo=True):
        portage.writemsg(
            "!!! '%s' is not a valid package atom.\n" % myfiles[0], noiselevel=-1
        )
        portage.writemsg("!!! Please check ebuild(5) for full details.\n")
        portage.writemsg(
            "!!! (Did you specify a version but forget to prefix with '='?)\n"
        )
        sys.exit(1)
    print()
    try:
        pkgs = trees[settings["EROOT"]]["vartree"].dbapi.match(myfiles[0])
    except portage.exception.AmbiguousPackageName as e:
        # Multiple matches thrown from cpv_expand
        pkgs = e.args[0]
    if len(pkgs) == 0:
        print("No packages found.\n")
        sys.exit(0)
    elif len(pkgs) > 1:
        if "--ask" in myopts:
            options = []
            print("Please select a package to configure:")
            idx = 0
            for pkg in pkgs:
                idx += 1
                options.append(str(idx))
                print(options[-1] + ") " + pkg)
            print("X) Cancel")
            options.append("X")
            idx = uq.query("Selection?", enter_invalid, responses=options)
            if idx == "X":
                sys.exit(128 + signal.SIGINT)
            pkg = pkgs[int(idx) - 1]
        else:
            print("The following packages available:")
            for pkg in pkgs:
                print("* " + pkg)
            print("\nPlease use a specific atom or the --ask option.")
            sys.exit(1)
    else:
        pkg = pkgs[0]

    print()
    if "--ask" in myopts:
        if uq.query("Ready to configure %s?" % pkg, enter_invalid) == "No":
            sys.exit(128 + signal.SIGINT)
    else:
        print("Configuring pkg...")
    print()
    ebuildpath = trees[settings["EROOT"]]["vartree"].dbapi.findname(pkg)
    mysettings = portage.config(clone=settings)
    vardb = trees[mysettings["EROOT"]]["vartree"].dbapi
    debug = mysettings.get("PORTAGE_DEBUG") == "1"
    retval = portage.doebuild(
        ebuildpath,
        "config",
        settings=mysettings,
        debug=(settings.get("PORTAGE_DEBUG", "") == 1),
        cleanup=True,
        mydbapi=trees[settings["EROOT"]]["vartree"].dbapi,
        tree="vartree",
    )
    if retval == os.EX_OK:
        portage.doebuild(
            ebuildpath,
            "clean",
            settings=mysettings,
            debug=debug,
            mydbapi=vardb,
            tree="vartree",
        )
    print()
    return retval


def action_depclean(
    settings, trees, ldpath_mtimes, myopts, action, myfiles, spinner, scheduler=None
):
    # Kill packages that aren't explicitly merged or are required as a
    # dependency of another package. World file is explicit.

    # Global depclean or prune operations are not very safe when there are
    # missing dependencies since it's unknown how badly incomplete
    # the dependency graph is, and we might accidentally remove packages
    # that should have been pulled into the graph. On the other hand, it's
    # relatively safe to ignore missing deps when only asked to remove
    # specific packages.

    # Force autoclean for depcleans (but not purges), as it was changed
    # to default off to not run it on every unmerge.
    # bug #792195
    if action == "depclean":
        settings.unlock()
        settings["AUTOCLEAN"] = "yes"
        settings.backup_changes("AUTOCLEAN")
        settings.lock()

    msg = []
    if (
        "preserve-libs" not in settings.features
        and not myopts.get("--depclean-lib-check", _DEPCLEAN_LIB_CHECK_DEFAULT) != "n"
    ):
        msg.append("Depclean may break link level dependencies. Thus, it is\n")
        msg.append(
            "recommended to use a tool such as " + good("`revdep-rebuild`") + " (from\n"
        )
        msg.append("app-portage/gentoolkit) in order to detect such breakage.\n")
        msg.append("\n")
    msg.append("Always study the list of packages to be cleaned for any obvious\n")
    msg.append("mistakes. Packages that are part of the world set will always\n")
    msg.append("be kept.  They can be manually added to this set with\n")
    msg.append(good("`emerge --noreplace <atom>`") + ".  Packages that are listed in\n")
    msg.append("package.provided (see portage(5)) will be removed by\n")
    msg.append("depclean, even if they are part of the world set.\n")
    msg.append("\n")
    msg.append("As a safety measure, depclean will not remove any packages\n")
    msg.append("unless *all* required dependencies have been resolved.  As a\n")
    msg.append("consequence of this, it often becomes necessary to run \n")
    msg.append(
        "%s" % good("`emerge --update --newuse --deep @world`")
        + " prior to depclean.\n"
    )

    if action == "depclean" and "--quiet" not in myopts and not myfiles:
        portage.writemsg_stdout("\n")
        for x in msg:
            portage.writemsg_stdout(colorize("WARN", " * ") + x)

    root_config = trees[settings["EROOT"]]["root_config"]
    vardb = root_config.trees["vartree"].dbapi

    args_set = InternalPackageSet(allow_repo=True)
    if myfiles:
        args_set.update(myfiles)
        matched_packages = False
        for x in args_set:
            if vardb.match(x):
                matched_packages = True
            else:
                writemsg_level(
                    "--- Couldn't find '%s' to %s.\n"
                    % (x.replace("null/", ""), action),
                    level=logging.WARN,
                    noiselevel=-1,
                )
        if not matched_packages:
            writemsg_level(">>> No packages selected for removal by %s\n" % action)
            return 0

    # The calculation is done in a separate function so that depgraph
    # references go out of scope and the corresponding memory
    # is freed before we call unmerge().
    rval, cleanlist, ordered, req_pkg_count = calc_depclean(
        settings, trees, ldpath_mtimes, myopts, action, args_set, spinner
    )

    clear_caches(trees)

    if rval != os.EX_OK:
        return rval

    if cleanlist:
        rval = unmerge(
            root_config,
            myopts,
            "unmerge",
            cleanlist,
            ldpath_mtimes,
            ordered=ordered,
            scheduler=scheduler,
        )

    if action == "prune":
        return rval

    if not cleanlist and "--quiet" in myopts:
        return rval

    set_atoms = {}
    for k in ("profile", "system", "selected"):
        try:
            set_atoms[k] = root_config.setconfig.getSetAtoms(k)
        except portage.exception.PackageSetNotFound:
            # A nested set could not be resolved, so ignore nested sets.
            set_atoms[k] = root_config.sets[k].getAtoms()

    print("Packages installed:   " + str(len(vardb.cpv_all())))
    print("Packages in world:    %d" % len(set_atoms["selected"]))
    print("Packages in system:   %d" % len(set_atoms["system"]))
    if set_atoms["profile"]:
        print("Packages in profile:  %d" % len(set_atoms["profile"]))
    print("Required packages:    " + str(req_pkg_count))
    if "--pretend" in myopts:
        print("Number to remove:     " + str(len(cleanlist)))
    else:
        print("Number removed:       " + str(len(cleanlist)))

    return rval


def calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spinner):
    result = _calc_depclean(
        settings, trees, ldpath_mtimes, myopts, action, args_set, spinner
    )
    return result.returncode, result.cleanlist, result.ordered, result.req_pkg_count


_depclean_result = collections.namedtuple(
    "_depclean_result",
    ("returncode", "cleanlist", "ordered", "req_pkg_count", "depgraph"),
)


def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spinner):
    allow_missing_deps = bool(args_set)

    debug = "--debug" in myopts
    xterm_titles = "notitles" not in settings.features
    root_len = len(settings["ROOT"])
    eroot = settings["EROOT"]
    root_config = trees[eroot]["root_config"]
    psets = root_config.setconfig.psets
    deselect = myopts.get("--deselect") != "n"
    required_sets = {}
    required_sets["world"] = psets["world"]

    # When removing packages, a temporary version of the world 'selected'
    # set may be used which excludes packages that are intended to be
    # eligible for removal.
    selected_set = psets["selected"]
    required_sets["selected"] = selected_set
    protected_set = InternalPackageSet()
    protected_set_name = "____depclean_protected_set____"
    required_sets[protected_set_name] = protected_set

    set_error = False
    set_atoms = {}
    for k in ("profile", "system", "selected"):
        try:
            set_atoms[k] = root_config.setconfig.getSetAtoms(k)
        except portage.exception.PackageSetNotFound as e:
            # A nested set could not be resolved, so ignore nested sets.
            set_atoms[k] = root_config.sets[k].getAtoms()
            writemsg_level(
                _("!!! The set '%s' " "contains a non-existent set named '%s'.\n")
                % (k, e),
                level=logging.ERROR,
                noiselevel=-1,
            )
            set_error = True

    # Support @profile as an alternative to @system.
    if not (set_atoms["system"] or set_atoms["profile"]):
        writemsg_level(
            _("!!! You have no system list.\n"), level=logging.WARNING, noiselevel=-1
        )

    if not set_atoms["selected"]:
        writemsg_level(
            _("!!! You have no world file.\n"), level=logging.WARNING, noiselevel=-1
        )

    # Suppress world file warnings unless @world is completely empty,
    # since having an empty world file can be a valid state.
    try:
        world_atoms = bool(root_config.setconfig.getSetAtoms("world"))
    except portage.exception.PackageSetNotFound as e:
        writemsg_level(
            _("!!! The set '%s' " "contains a non-existent set named '%s'.\n")
            % ("world", e),
            level=logging.ERROR,
            noiselevel=-1,
        )
        set_error = True
    else:
        if not world_atoms:
            writemsg_level(
                _("!!! Your @world set is empty.\n"), level=logging.ERROR, noiselevel=-1
            )
            set_error = True

    if set_error:
        writemsg_level(
            _("!!! Aborting due to set configuration " "errors displayed above.\n"),
            level=logging.ERROR,
            noiselevel=-1,
        )
        return _depclean_result(1, [], False, 0, None)

    if action == "depclean":
        emergelog(xterm_titles, " >>> depclean")

    writemsg_level("\nCalculating dependencies  ")
    resolver_params = create_depgraph_params(myopts, "remove")
    resolver = depgraph(settings, trees, myopts, resolver_params, spinner)
    resolver._load_vdb()
    vardb = resolver._frozen_config.trees[eroot]["vartree"].dbapi
    real_vardb = trees[eroot]["vartree"].dbapi

    if action == "depclean":

        if args_set:

            if deselect:
                # Start with an empty set.
                selected_set = InternalPackageSet()
                required_sets["selected"] = selected_set
                # Pull in any sets nested within the selected set.
                selected_set.update(psets["selected"].getNonAtoms())

            # Pull in everything that's installed but not matched
            # by an argument atom since we don't want to clean any
            # package if something depends on it.
            for pkg in vardb:
                if spinner:
                    spinner.update()

                try:
                    if args_set.findAtomForPackage(pkg) is None:
                        protected_set.add("=" + pkg.cpv)
                        continue
                except portage.exception.InvalidDependString as e:
                    show_invalid_depstring_notice(pkg, str(e))
                    del e
                    protected_set.add("=" + pkg.cpv)
                    continue

    elif action == "prune":

        if deselect:
            # Start with an empty set.
            selected_set = InternalPackageSet()
            required_sets["selected"] = selected_set
            # Pull in any sets nested within the selected set.
            selected_set.update(psets["selected"].getNonAtoms())

        # Pull in everything that's installed since we don't
        # to prune a package if something depends on it.
        protected_set.update(vardb.cp_all())

        if not args_set:

            # Try to prune everything that's slotted.
            for cp in vardb.cp_all():
                if len(vardb.cp_list(cp)) > 1:
                    args_set.add(cp)

        # Remove atoms from world that match installed packages
        # that are also matched by argument atoms, but do not remove
        # them if they match the highest installed version.
        for pkg in vardb:
            if spinner is not None:
                spinner.update()
            pkgs_for_cp = vardb.match_pkgs(Atom(pkg.cp))
            if not pkgs_for_cp or pkg not in pkgs_for_cp:
                raise AssertionError(
                    "package expected in matches: "
                    + "cp = %s, cpv = %s matches = %s"
                    % (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp])
                )

            highest_version = pkgs_for_cp[-1]
            if pkg == highest_version:
                # pkg is the highest version
                protected_set.add("=" + pkg.cpv)
                continue

            if len(pkgs_for_cp) <= 1:
                raise AssertionError(
                    "more packages expected: "
                    + "cp = %s, cpv = %s matches = %s"
                    % (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp])
                )

            try:
                if args_set.findAtomForPackage(pkg) is None:
                    protected_set.add("=" + pkg.cpv)
                    continue
            except portage.exception.InvalidDependString as e:
                show_invalid_depstring_notice(pkg, str(e))
                del e
                protected_set.add("=" + pkg.cpv)
                continue

    if resolver._frozen_config.excluded_pkgs:
        excluded_set = resolver._frozen_config.excluded_pkgs
        required_sets["__excluded__"] = InternalPackageSet()

        for pkg in vardb:
            if spinner:
                spinner.update()

            try:
                if excluded_set.findAtomForPackage(pkg):
                    required_sets["__excluded__"].add("=" + pkg.cpv)
            except portage.exception.InvalidDependString as e:
                show_invalid_depstring_notice(pkg, str(e))
                del e
                required_sets["__excluded__"].add("=" + pkg.cpv)

    success = resolver._complete_graph(required_sets={eroot: required_sets})
    writemsg_level("\b\b... done!\n")

    resolver.display_problems()

    if not success:
        return _depclean_result(1, [], False, 0, resolver)

    def unresolved_deps():

        soname_deps = set()
        unresolvable = set()
        for dep in resolver._dynamic_config._initially_unsatisfied_deps:
            if isinstance(dep.parent, Package) and (
                dep.priority > UnmergeDepPriority.SOFT
            ):
                if dep.atom.soname:
                    soname_deps.add((dep.atom, dep.parent.cpv))
                else:
                    unresolvable.add((dep.atom, dep.parent.cpv))

        if soname_deps:
            # Generally, broken soname dependencies can safely be
            # suppressed by a REQUIRES_EXCLUDE setting in the ebuild,
            # so they should only trigger a warning message.
            prefix = warn(" * ")
            msg = []
            msg.append("Broken soname dependencies found:")
            msg.append("")
            for atom, parent in soname_deps:
                msg.append("  %s required by:" % (atom,))
                msg.append("    %s" % (parent,))
                msg.append("")

            writemsg_level(
                "".join("%s%s\n" % (prefix, line) for line in msg),
                level=logging.WARNING,
                noiselevel=-1,
            )

        if not unresolvable:
            return False

        if unresolvable and not allow_missing_deps:

            if "--debug" in myopts:
                writemsg("\ndigraph:\n\n", noiselevel=-1)
                resolver._dynamic_config.digraph.debug_print()
                writemsg("\n", noiselevel=-1)

            prefix = bad(" * ")
            msg = []
            msg.append("Dependencies could not be completely resolved due to")
            msg.append("the following required packages not being installed:")
            msg.append("")
            for atom, parent in unresolvable:
                # For readability, we want to display the atom with USE
                # conditionals evaluated whenever possible. However,
                # there is a very special case where the atom does not
                # match because the unevaluated form contains one or
                # more flags for which the target package has missing
                # IUSE, but due to conditionals those flags are only
                # visible in the unevaluated form of the atom. In this
                # case, we must display the unevaluated atom, so that
                # the user can see the conditional USE deps that would
                # otherwise be invisible. Use Atom(str(atom)) to
                # test for a package where this case would matter. This
                # is not necessarily the same as atom.without_use,
                # since Atom(str(atom)) may still contain some
                # USE dependencies that remain after evaluation of
                # conditionals.
                if (
                    atom.package
                    and atom != atom.unevaluated_atom
                    and vardb.match(Atom(str(atom)))
                ):
                    msg.append(
                        "  %s (%s) pulled in by:" % (atom.unevaluated_atom, atom)
                    )
                else:
                    msg.append("  %s pulled in by:" % (atom,))
                msg.append("    %s" % (parent,))
                msg.append("")
            msg.extend(
                textwrap.wrap(
                    "Have you forgotten to do a complete update prior "
                    + "to depclean? The most comprehensive command for this "
                    + "purpose is as follows:",
                    65,
                )
            )
            msg.append("")
            msg.append(
                "  " + good("emerge --update --newuse --deep --with-bdeps=y @world")
            )
            msg.append("")
            msg.extend(
                textwrap.wrap(
                    "Note that the --with-bdeps=y option is not required in "
                    + "many situations. Refer to the emerge manual page "
                    + "(run `man emerge`) for more information about "
                    + "--with-bdeps.",
                    65,
                )
            )
            msg.append("")
            msg.extend(
                textwrap.wrap(
                    "Also, note that it may be necessary to manually uninstall "
                    + "packages that no longer exist in the repository, since "
                    + "it may not be possible to satisfy their dependencies.",
                    65,
                )
            )
            if action == "prune":
                msg.append("")
                msg.append(
                    "If you would like to ignore "
                    + "dependencies then use %s." % good("--nodeps")
                )
            writemsg_level(
                "".join("%s%s\n" % (prefix, line) for line in msg),
                level=logging.ERROR,
                noiselevel=-1,
            )
            return True
        return False

    if unresolved_deps():
        return _depclean_result(1, [], False, 0, resolver)

    graph = resolver._dynamic_config.digraph.copy()
    required_pkgs_total = 0
    for node in graph:
        if isinstance(node, Package):
            required_pkgs_total += 1

    def show_parents(child_node):
        parent_atoms = resolver._dynamic_config._parent_atoms.get(child_node, [])

        # Never display the special internal protected_set.
        parent_atoms = [
            parent_atom
            for parent_atom in parent_atoms
            if not (
                isinstance(parent_atom[0], SetArg)
                and parent_atom[0].name == protected_set_name
            )
        ]

        if not parent_atoms:
            # With --prune, the highest version can be pulled in without any
            # real parent since all installed packages are pulled in.  In that
            # case there's nothing to show here.
            return
        parent_atom_dict = {}
        for parent, atom in parent_atoms:
            parent_atom_dict.setdefault(parent, []).append(atom)

        parent_strs = []
        for parent, atoms in parent_atom_dict.items():
            # Display package atoms and soname
            # atoms in separate groups.
            atoms = sorted(atoms, reverse=True, key=operator.attrgetter("package"))
            parent_strs.append(
                "%s requires %s"
                % (
                    getattr(parent, "cpv", parent),
                    ", ".join(str(atom) for atom in atoms),
                )
            )
        parent_strs.sort()
        msg = []
        msg.append("  %s pulled in by:\n" % (child_node.cpv,))
        for parent_str in parent_strs:
            msg.append("    %s\n" % (parent_str,))
        msg.append("\n")
        portage.writemsg_stdout("".join(msg), noiselevel=-1)

    def cmp_pkg_cpv(pkg1, pkg2):
        """Sort Package instances by cpv."""
        if pkg1.cpv > pkg2.cpv:
            return 1
        if pkg1.cpv == pkg2.cpv:
            return 0
        return -1

    def create_cleanlist():

        if "--debug" in myopts:
            writemsg("\ndigraph:\n\n", noiselevel=-1)
            graph.debug_print()
            writemsg("\n", noiselevel=-1)

        pkgs_to_remove = []

        if action == "depclean":
            if args_set:

                for pkg in sorted(vardb, key=cmp_sort_key(cmp_pkg_cpv)):
                    arg_atom = None
                    try:
                        arg_atom = args_set.findAtomForPackage(pkg)
                    except portage.exception.InvalidDependString:
                        # this error has already been displayed by now
                        continue

                    if arg_atom:
                        if pkg not in graph:
                            pkgs_to_remove.append(pkg)
                        elif "--verbose" in myopts:
                            show_parents(pkg)

            else:
                for pkg in sorted(vardb, key=cmp_sort_key(cmp_pkg_cpv)):
                    if pkg not in graph:
                        pkgs_to_remove.append(pkg)
                    elif "--verbose" in myopts:
                        show_parents(pkg)

        elif action == "prune":

            for atom in args_set:
                for pkg in vardb.match_pkgs(atom):
                    if pkg not in graph:
                        pkgs_to_remove.append(pkg)
                    elif "--verbose" in myopts:
                        show_parents(pkg)

        if not pkgs_to_remove:
            writemsg_level(">>> No packages selected for removal by %s\n" % action)
            if "--verbose" not in myopts:
                writemsg_level(
                    ">>> To see reverse dependencies, use %s\n" % good("--verbose")
                )
            if action == "prune":
                writemsg_level(
                    ">>> To ignore dependencies, use %s\n" % good("--nodeps")
                )

        return pkgs_to_remove

    cleanlist = create_cleanlist()
    clean_set = set(cleanlist)

    depclean_lib_check = (
        cleanlist
        and real_vardb._linkmap is not None
        and myopts.get("--depclean-lib-check", _DEPCLEAN_LIB_CHECK_DEFAULT) != "n"
    )
    preserve_libs = "preserve-libs" in settings.features
    preserve_libs_restrict = False

    if depclean_lib_check and preserve_libs:
        for pkg in cleanlist:
            if "preserve-libs" in pkg.restrict:
                preserve_libs_restrict = True
                break

    if depclean_lib_check and (preserve_libs_restrict or not preserve_libs):

        # Check if any of these packages are the sole providers of libraries
        # with consumers that have not been selected for removal. If so, these
        # packages and any dependencies need to be added to the graph.
        linkmap = real_vardb._linkmap
        consumer_cache = {}
        provider_cache = {}
        consumer_map = {}

        writemsg_level(">>> Checking for lib consumers...\n")

        for pkg in cleanlist:

            if preserve_libs and "preserve-libs" not in pkg.restrict:
                # Any needed libraries will be preserved
                # when this package is unmerged, so there's
                # no need to account for it here.
                continue

            pkg_dblink = real_vardb._dblink(pkg.cpv)
            consumers = {}

            for lib in pkg_dblink.getcontents():
                lib = lib[root_len:]
                lib_key = linkmap._obj_key(lib)
                lib_consumers = consumer_cache.get(lib_key)
                if lib_consumers is None:
                    try:
                        lib_consumers = linkmap.findConsumers(lib_key)
                    except KeyError:
                        continue
                    consumer_cache[lib_key] = lib_consumers
                if lib_consumers:
                    consumers[lib_key] = lib_consumers

            if not consumers:
                continue

            for lib, lib_consumers in list(consumers.items()):
                for consumer_file in list(lib_consumers):
                    if pkg_dblink.isowner(consumer_file):
                        lib_consumers.remove(consumer_file)
                if not lib_consumers:
                    del consumers[lib]

            if not consumers:
                continue

            for lib, lib_consumers in consumers.items():

                soname = linkmap.getSoname(lib)

                consumer_providers = []
                for lib_consumer in lib_consumers:
                    providers = provider_cache.get(lib)
                    if providers is None:
                        providers = linkmap.findProviders(lib_consumer)
                        provider_cache[lib_consumer] = providers
                    if soname not in providers:
                        # Why does this happen?
                        continue
                    consumer_providers.append((lib_consumer, providers[soname]))

                consumers[lib] = consumer_providers

            consumer_map[pkg] = consumers

        if consumer_map:

            search_files = set()
            for consumers in consumer_map.values():
                for lib, consumer_providers in consumers.items():
                    for lib_consumer, providers in consumer_providers:
                        search_files.add(lib_consumer)
                        search_files.update(providers)

            writemsg_level(">>> Assigning files to packages...\n")
            file_owners = {}
            for f in search_files:
                owner_set = set()
                for owner in linkmap.getOwners(f):
                    owner_dblink = real_vardb._dblink(owner)
                    if owner_dblink.exists():
                        owner_set.add(owner_dblink)
                if owner_set:
                    file_owners[f] = owner_set

            for pkg, consumers in list(consumer_map.items()):
                for lib, consumer_providers in list(consumers.items()):
                    lib_consumers = set()

                    for lib_consumer, providers in consumer_providers:
                        owner_set = file_owners.get(lib_consumer)
                        provider_dblinks = set()
                        provider_pkgs = set()

                        if len(providers) > 1:
                            for provider in providers:
                                provider_set = file_owners.get(provider)
                                if provider_set is not None:
                                    provider_dblinks.update(provider_set)

                        if len(provider_dblinks) > 1:
                            for provider_dblink in provider_dblinks:
                                provider_pkg = resolver._pkg(
                                    provider_dblink.mycpv,
                                    "installed",
                                    root_config,
                                    installed=True,
                                )
                                if provider_pkg not in clean_set:
                                    provider_pkgs.add(provider_pkg)

                        if provider_pkgs:
                            continue

                        if owner_set is not None:
                            lib_consumers.update(owner_set)

                    for consumer_dblink in list(lib_consumers):
                        if (
                            resolver._pkg(
                                consumer_dblink.mycpv,
                                "installed",
                                root_config,
                                installed=True,
                            )
                            in clean_set
                        ):
                            lib_consumers.remove(consumer_dblink)
                            continue

                    if lib_consumers:
                        consumers[lib] = lib_consumers
                    else:
                        del consumers[lib]
                if not consumers:
                    del consumer_map[pkg]

        if consumer_map:
            # TODO: Implement a package set for rebuilding consumer packages.

            msg = (
                "In order to avoid breakage of link level "
                + "dependencies, one or more packages will not be removed. "
                + "This can be solved by rebuilding "
                + "the packages that pulled them in."
            )

            prefix = bad(" * ")
            writemsg_level(
                "".join(prefix + "%s\n" % line for line in textwrap.wrap(msg, 70)),
                level=logging.WARNING,
                noiselevel=-1,
            )

            msg = []
            for pkg in sorted(consumer_map, key=cmp_sort_key(cmp_pkg_cpv)):
                consumers = consumer_map[pkg]
                consumer_libs = {}
                for lib, lib_consumers in consumers.items():
                    for consumer in lib_consumers:
                        consumer_libs.setdefault(consumer.mycpv, set()).add(
                            linkmap.getSoname(lib)
                        )
                unique_consumers = set(chain(*consumers.values()))
                unique_consumers = sorted(
                    consumer.mycpv for consumer in unique_consumers
                )
                msg.append("")
                msg.append("  %s pulled in by:" % (pkg.cpv,))
                for consumer in unique_consumers:
                    libs = consumer_libs[consumer]
                    msg.append("    %s needs %s" % (consumer, ", ".join(sorted(libs))))
            msg.append("")
            writemsg_level(
                "".join(prefix + "%s\n" % line for line in msg),
                level=logging.WARNING,
                noiselevel=-1,
            )

            # Add lib providers to the graph as children of lib consumers,
            # and also add any dependencies pulled in by the provider.
            writemsg_level(">>> Adding lib providers to graph...\n")

            for pkg, consumers in consumer_map.items():
                for consumer_dblink in set(chain(*consumers.values())):
                    consumer_pkg = resolver._pkg(
                        consumer_dblink.mycpv, "installed", root_config, installed=True
                    )
                    if not resolver._add_pkg(
                        pkg,
                        Dependency(
                            parent=consumer_pkg,
                            priority=UnmergeDepPriority(
                                runtime=True, runtime_slot_op=True
                            ),
                            root=pkg.root,
                        ),
                    ):
                        resolver.display_problems()
                        return _depclean_result(1, [], False, 0, resolver)

            writemsg_level("\nCalculating dependencies  ")
            success = resolver._complete_graph(required_sets={eroot: required_sets})
            writemsg_level("\b\b... done!\n")
            resolver.display_problems()
            if not success:
                return _depclean_result(1, [], False, 0, resolver)
            if unresolved_deps():
                return _depclean_result(1, [], False, 0, resolver)

            graph = resolver._dynamic_config.digraph.copy()
            required_pkgs_total = 0
            for node in graph:
                if isinstance(node, Package):
                    required_pkgs_total += 1
            cleanlist = create_cleanlist()
            if not cleanlist:
                return _depclean_result(0, [], False, required_pkgs_total, resolver)
            clean_set = set(cleanlist)

    if clean_set:
        writemsg_level(">>> Calculating removal order...\n")
        # Use a topological sort to create an unmerge order such that
        # each package is unmerged before it's dependencies. This is
        # necessary to avoid breaking things that may need to run
        # during pkg_prerm or pkg_postrm phases.

        # Create a new graph to account for dependencies between the
        # packages being unmerged.
        graph = digraph()
        del cleanlist[:]

        runtime = UnmergeDepPriority(runtime=True)
        runtime_post = UnmergeDepPriority(runtime_post=True)
        buildtime = UnmergeDepPriority(buildtime=True)
        priority_map = {
            "IDEPEND": runtime,
            "RDEPEND": runtime,
            "PDEPEND": runtime_post,
            "BDEPEND": buildtime,
            "DEPEND": buildtime,
        }

        for node in clean_set:
            graph.add(node, None)
            for dep_type in Package._dep_keys:
                depstr = node._metadata[dep_type]
                if not depstr:
                    continue
                priority = priority_map[dep_type]

                if debug:
                    writemsg_level(
                        "\nParent:    %s\n" % (node,),
                        noiselevel=-1,
                        level=logging.DEBUG,
                    )
                    writemsg_level(
                        "Depstring: %s\n" % (depstr,),
                        noiselevel=-1,
                        level=logging.DEBUG,
                    )
                    writemsg_level(
                        "Priority:  %s\n" % (priority,),
                        noiselevel=-1,
                        level=logging.DEBUG,
                    )

                try:
                    atoms = resolver._select_atoms(
                        eroot,
                        depstr,
                        myuse=node.use.enabled,
                        parent=node,
                        priority=priority,
                    )[node]
                except portage.exception.InvalidDependString:
                    # Ignore invalid deps of packages that will
                    # be uninstalled anyway.
                    continue

                if debug:
                    writemsg_level(
                        "Candidates: [%s]\n" % ", ".join("'%s'" % (x,) for x in atoms),
                        noiselevel=-1,
                        level=logging.DEBUG,
                    )

                for atom in atoms:
                    if not isinstance(atom, portage.dep.Atom):
                        # Ignore invalid atoms returned from dep_check().
                        continue
                    if atom.blocker:
                        continue
                    matches = vardb.match_pkgs(atom)
                    if not matches:
                        continue
                    for child_node in matches:
                        if child_node in clean_set:

                            mypriority = priority.copy()
                            if atom.slot_operator_built:
                                if mypriority.buildtime:
                                    mypriority.buildtime_slot_op = True
                                if mypriority.runtime:
                                    mypriority.runtime_slot_op = True

                            graph.add(child_node, node, priority=mypriority)

        if debug:
            writemsg_level("\nunmerge digraph:\n\n", noiselevel=-1, level=logging.DEBUG)
            graph.debug_print()
            writemsg_level("\n", noiselevel=-1, level=logging.DEBUG)

        ordered = True
        if len(graph.order) == len(graph.root_nodes()):
            # If there are no dependencies between packages
            # let unmerge() group them by cat/pn.
            ordered = False
            cleanlist = [pkg.cpv for pkg in graph.order]
        else:
            # Order nodes from lowest to highest overall reference count for
            # optimal root node selection (this can help minimize issues
            # with unaccounted implicit dependencies).
            node_refcounts = {}
            for node in graph.order:
                node_refcounts[node] = len(graph.parent_nodes(node))

            def cmp_reference_count(node1, node2):
                return node_refcounts[node1] - node_refcounts[node2]

            graph.order.sort(key=cmp_sort_key(cmp_reference_count))

            ignore_priority_range = [None]
            ignore_priority_range.extend(
                range(UnmergeDepPriority.MIN, UnmergeDepPriority.MAX + 1)
            )
            while graph:
                for ignore_priority in ignore_priority_range:
                    nodes = graph.root_nodes(ignore_priority=ignore_priority)
                    if nodes:
                        break
                if not nodes:
                    raise AssertionError("no root nodes")
                if ignore_priority is not None:
                    # Some deps have been dropped due to circular dependencies,
                    # so only pop one node in order to minimize the number that
                    # are dropped.
                    del nodes[1:]
                for node in nodes:
                    graph.remove(node)
                    cleanlist.append(node.cpv)

        return _depclean_result(0, cleanlist, ordered, required_pkgs_total, resolver)
    if args_set and "--pretend" not in myopts:
        # If the cleanlist is empty but we were given packages to clean,
        # we aren't successfully depcleaning. Return failure unless
        # we're pretending.
        return _depclean_result(1, [], False, required_pkgs_total, resolver)
    return _depclean_result(0, [], False, required_pkgs_total, resolver)


def action_deselect(settings, trees, opts, atoms):
    enter_invalid = "--ask-enter-invalid" in opts
    root_config = trees[settings["EROOT"]]["root_config"]
    world_set = root_config.sets["selected"]
    if not hasattr(world_set, "update"):
        writemsg_level(
            "World @selected set does not appear to be mutable.\n",
            level=logging.ERROR,
            noiselevel=-1,
        )
        return 1

    pretend = "--pretend" in opts
    locked = False
    if not pretend and hasattr(world_set, "lock"):
        world_set.lock()
        locked = True
    try:
        world_set.load()
        world_atoms = world_set.getAtoms()
        vardb = root_config.trees["vartree"].dbapi
        expanded_atoms = set(atoms)

        for atom in atoms:
            if not atom.startswith(SETPREFIX):
                if atom.cp.startswith("null/"):
                    # try to expand category from world set
                    null_cat, pn = portage.catsplit(atom.cp)
                    for world_atom in world_atoms:
                        cat, world_pn = portage.catsplit(world_atom.cp)
                        if pn == world_pn:
                            expanded_atoms.add(
                                Atom(
                                    atom.replace("null", cat, 1),
                                    allow_repo=True,
                                    allow_wildcard=True,
                                )
                            )

                for cpv in vardb.match(atom):
                    pkg = vardb._pkg_str(cpv, None)
                    expanded_atoms.add(Atom("%s:%s" % (pkg.cp, pkg.slot)))

        discard_atoms = set()
        for atom in world_set:
            for arg_atom in expanded_atoms:
                if arg_atom.startswith(SETPREFIX):
                    if atom.startswith(SETPREFIX) and arg_atom == atom:
                        discard_atoms.add(atom)
                        break
                else:
                    if (
                        not atom.startswith(SETPREFIX)
                        and arg_atom.intersects(atom)
                        and not (arg_atom.slot and not atom.slot)
                        and not (arg_atom.repo and not atom.repo)
                    ):
                        discard_atoms.add(atom)
                        break
        if discard_atoms:
            for atom in sorted(discard_atoms):

                if pretend:
                    action_desc = "Would remove"
                else:
                    action_desc = "Removing"

                if atom.startswith(SETPREFIX):
                    filename = "world_sets"
                else:
                    filename = "world"

                writemsg_stdout(
                    '>>> %s %s from "%s" favorites file...\n'
                    % (action_desc, colorize("INFORM", str(atom)), filename),
                    noiselevel=-1,
                )

            if "--ask" in opts:
                prompt = (
                    "Would you like to remove these "
                    + "packages from your world favorites?"
                )
                uq = UserQuery(opts)
                if uq.query(prompt, enter_invalid) == "No":
                    return 128 + signal.SIGINT

            remaining = set(world_set)
            remaining.difference_update(discard_atoms)
            if not pretend:
                world_set.replace(remaining)
        else:
            print('>>> No matching atoms found in "world" favorites file...')
    finally:
        if locked:
            world_set.unlock()
    return os.EX_OK


class _info_pkgs_ver:
    def __init__(self, ver, repo_suffix, provide_suffix):
        self.ver = ver
        self.repo_suffix = repo_suffix
        self.provide_suffix = provide_suffix

    def __lt__(self, other):
        return portage.versions.vercmp(self.ver, other.ver) < 0

    def toString(self):
        """
        This may return unicode if repo_name contains unicode.
        Don't use __str__ and str() since unicode triggers compatibility
        issues between python 2.x and 3.x.
        """
        return self.ver + self.repo_suffix + self.provide_suffix


def action_info(settings, trees, myopts, myfiles):

    # See if we can find any packages installed matching the strings
    # passed on the command line
    mypkgs = []
    eroot = settings["EROOT"]
    vardb = trees[eroot]["vartree"].dbapi
    portdb = trees[eroot]["porttree"].dbapi
    bindb = trees[eroot]["bintree"].dbapi
    repos = portdb.settings.repositories
    for x in myfiles:
        any_match = False
        cp_exists = bool(vardb.match(x.cp))
        installed_match = vardb.match(x)
        for installed in installed_match:
            mypkgs.append((installed, "installed"))
            any_match = True

        if any_match:
            continue

        for db, pkg_type in ((portdb, "ebuild"), (bindb, "binary")):
            if pkg_type == "binary" and "--usepkg" not in myopts:
                continue

            # Use match instead of cp_list, to account for old-style virtuals.
            if not cp_exists and db.match(x.cp):
                cp_exists = True
            # Search for masked packages too.
            if not cp_exists and hasattr(db, "xmatch") and db.xmatch("match-all", x.cp):
                cp_exists = True

            matches = db.match(x)
            matches.reverse()
            for match in matches:
                if pkg_type == "binary":
                    if db.bintree.isremote(match):
                        continue
                auxkeys = ["EAPI", "DEFINED_PHASES"]
                metadata = dict(zip(auxkeys, db.aux_get(match, auxkeys)))
                if (
                    metadata["EAPI"] not in ("0", "1", "2", "3")
                    and "info" in metadata["DEFINED_PHASES"].split()
                ):
                    mypkgs.append((match, pkg_type))
                    break

        if not cp_exists:
            xinfo = '"%s"' % x.unevaluated_atom
            # Discard null/ from failed cpv_expand category expansion.
            xinfo = xinfo.replace("null/", "")
            if settings["ROOT"] != "/":
                xinfo = "%s for %s" % (xinfo, eroot)
            writemsg(
                "\nemerge: there are no ebuilds to satisfy %s.\n"
                % colorize("INFORM", xinfo),
                noiselevel=-1,
            )

            if myopts.get("--misspell-suggestions", "y") != "n":

                writemsg("\nemerge: searching for similar names...", noiselevel=-1)

                search_index = myopts.get("--search-index", "y") != "n"
                dbs = [IndexedVardb(vardb) if search_index else vardb]
                # if "--usepkgonly" not in myopts:
                dbs.append(IndexedPortdb(portdb) if search_index else portdb)
                if "--usepkg" in myopts:
                    dbs.append(bindb)

                matches = similar_name_search(dbs, x)

                if len(matches) == 1:
                    writemsg(
                        "\nemerge: Maybe you meant " + matches[0] + "?\n", noiselevel=-1
                    )
                elif len(matches) > 1:
                    writemsg(
                        "\nemerge: Maybe you meant any of these: %s?\n"
                        % (", ".join(matches),),
                        noiselevel=-1,
                    )
                else:
                    # Generally, this would only happen if
                    # all dbapis are empty.
                    writemsg(" nothing similar found.\n", noiselevel=-1)

            return 1

    output_buffer = []
    append = output_buffer.append
    root_config = trees[settings["EROOT"]]["root_config"]
    chost = settings.get("CHOST")

    append(
        getportageversion(
            settings["PORTDIR"],
            None,
            settings.profile_path,
            chost,
            trees[settings["EROOT"]]["vartree"].dbapi,
        )
    )

    header_width = 65
    header_title = "System Settings"
    if myfiles:
        append(header_width * "=")
        append(header_title.rjust(int(header_width / 2 + len(header_title) / 2)))
    append(header_width * "=")
    append("System uname: %s" % (platform.platform(aliased=1),))

    vm_info = get_vm_info()
    if "ram.total" in vm_info:
        line = "%-9s %10d total" % ("KiB Mem:", vm_info["ram.total"] // 1024)
        if "ram.free" in vm_info:
            line += ",%10d free" % (vm_info["ram.free"] // 1024,)
        append(line)
    if "swap.total" in vm_info:
        line = "%-9s %10d total" % ("KiB Swap:", vm_info["swap.total"] // 1024)
        if "swap.free" in vm_info:
            line += ",%10d free" % (vm_info["swap.free"] // 1024,)
        append(line)

    for repo in repos:
        last_sync = portage.grabfile(
            os.path.join(repo.location, "metadata", "timestamp.chk")
        )
        head_commit = None
        if last_sync:
            append("Timestamp of repository %s: %s" % (repo.name, last_sync[0]))
        if repo.sync_type:
            sync = portage.sync.module_controller.get_class(repo.sync_type)()
            options = {"repo": repo}
            try:
                head_commit = sync.retrieve_head(options=options)
            except NotImplementedError:
                head_commit = (1, False)
        if head_commit and head_commit[0] == os.EX_OK:
            append("Head commit of repository %s: %s" % (repo.name, head_commit[1]))

    # Searching contents for the /bin/sh provider is somewhat
    # slow. Therefore, use the basename of the symlink target
    # to locate the package. If this fails, then only the
    # basename of the symlink target will be displayed. So,
    # typical output is something like "sh bash 4.2_p53". Since
    # realpath is used to resolve symlinks recursively, this
    # approach is also able to handle multiple levels of symlinks
    # such as /bin/sh -> bb -> busybox. Note that we do not parse
    # the output of "/bin/sh --version" because many shells
    # do not have a --version option.
    basename = os.path.basename(
        os.path.realpath(os.path.join(os.sep, portage.const.EPREFIX, "bin", "sh"))
    )
    try:
        Atom("null/%s" % basename)
    except InvalidAtom:
        matches = None
    else:
        try:
            # Try a match against the basename, which should work for
            # busybox and most shells.
            matches = trees[trees._running_eroot]["vartree"].dbapi.match(basename)
        except portage.exception.AmbiguousPackageName:
            # If the name is ambiguous, then restrict our match
            # to the app-shells category.
            matches = trees[trees._running_eroot]["vartree"].dbapi.match(
                "app-shells/%s" % basename
            )

    if matches:
        pkg = matches[-1]
        name = pkg.cp
        version = pkg.version
        # Omit app-shells category from the output.
        if name.startswith("app-shells/"):
            name = name[len("app-shells/") :]
        sh_str = "%s %s" % (name, version)
    else:
        sh_str = basename

    append("sh %s" % sh_str)

    ld_names = []
    if chost:
        ld_names.append(chost + "-ld")
    ld_names.append("ld")
    for name in ld_names:
        try:
            proc = subprocess.Popen(
                [name, "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
            )
        except OSError:
            pass
        else:
            output = _unicode_decode(proc.communicate()[0]).splitlines()
            proc.wait()
            if proc.wait() == os.EX_OK and output:
                append("ld %s" % (output[0]))
                break

    try:
        proc = subprocess.Popen(
            ["distcc", "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        )
    except OSError:
        output = (1, None)
    else:
        output = _unicode_decode(proc.communicate()[0]).rstrip("\n")
        output = (proc.wait(), output)
    if output[0] == os.EX_OK:
        distcc_str = output[1].split("\n", 1)[0]
        if "distcc" in settings.features:
            distcc_str += " [enabled]"
        else:
            distcc_str += " [disabled]"
        append(distcc_str)

    try:
        proc = subprocess.Popen(
            ["ccache", "-V"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        )
    except OSError:
        output = (1, None)
    else:
        output = _unicode_decode(proc.communicate()[0]).rstrip("\n")
        output = (proc.wait(), output)
    if output[0] == os.EX_OK:
        ccache_str = output[1].split("\n", 1)[0]
        if "ccache" in settings.features:
            ccache_str += " [enabled]"
        else:
            ccache_str += " [disabled]"
        append(ccache_str)

    myvars = [
        "sys-devel/autoconf",
        "sys-devel/automake",
        "virtual/os-headers",
        "sys-devel/binutils",
        "sys-devel/libtool",
        "dev-lang/python",
    ]
    myvars += portage.util.grabfile(settings["PORTDIR"] + "/profiles/info_pkgs")
    atoms = []
    for x in myvars:
        try:
            x = Atom(x)
        except InvalidAtom:
            append("%-20s %s" % (x + ":", "[NOT VALID]"))
        else:
            for atom in expand_new_virt(vardb, x):
                if not atom.blocker:
                    atoms.append((x, atom))

    myvars = sorted(set(atoms))

    cp_map = {}
    cp_max_len = 0

    for orig_atom, x in myvars:
        pkg_matches = vardb.match(x)

        versions = []
        for cpv in pkg_matches:
            matched_cp = portage.versions.cpv_getkey(cpv)
            ver = portage.versions.cpv_getversion(cpv)
            ver_map = cp_map.setdefault(matched_cp, {})
            prev_match = ver_map.get(ver)
            if prev_match is not None:
                if prev_match.provide_suffix:
                    # prefer duplicate matches that include
                    # additional virtual provider info
                    continue

            if len(matched_cp) > cp_max_len:
                cp_max_len = len(matched_cp)
            repo = vardb.aux_get(cpv, ["repository"])[0]
            if repo:
                repo_suffix = _repo_separator + repo
            else:
                repo_suffix = _repo_separator + "<unknown repository>"

            if matched_cp == orig_atom.cp:
                provide_suffix = ""
            else:
                provide_suffix = " (%s)" % (orig_atom,)

            ver_map[ver] = _info_pkgs_ver(ver, repo_suffix, provide_suffix)

    for cp in sorted(cp_map):
        versions = sorted(cp_map[cp].values())
        versions = ", ".join(ver.toString() for ver in versions)
        append("%s %s" % ((cp + ":").ljust(cp_max_len + 1), versions))

    append("Repositories:\n")
    for repo in repos:
        append(repo.info_string())

    binrepos_conf_path = os.path.join(
        settings["PORTAGE_CONFIGROOT"], BINREPOS_CONF_FILE
    )
    binrepos_conf = BinRepoConfigLoader((binrepos_conf_path,), settings)
    if binrepos_conf and any(repo.name for repo in binrepos_conf.values()):
        append("Binary Repositories:\n")
        for repo in reversed(list(binrepos_conf.values())):
            # Omit repos from the PORTAGE_BINHOST variable, since they
            # do not have a name to label them with.
            if repo.name:
                append(repo.info_string())

    installed_sets = sorted(
        s for s in root_config.sets["selected"].getNonAtoms() if s.startswith(SETPREFIX)
    )
    if installed_sets:
        sets_line = "Installed sets: "
        sets_line += ", ".join(installed_sets)
        append(sets_line)

    if "--verbose" in myopts:
        myvars = list(settings)
    else:
        myvars = [
            "GENTOO_MIRRORS",
            "CONFIG_PROTECT",
            "CONFIG_PROTECT_MASK",
            "DISTDIR",
            "ENV_UNSET",
            "PKGDIR",
            "PORTAGE_TMPDIR",
            "PORTAGE_BINHOST",
            "PORTAGE_BUNZIP2_COMMAND",
            "PORTAGE_BZIP2_COMMAND",
            "USE",
            "CHOST",
            "CFLAGS",
            "CXXFLAGS",
            "ACCEPT_KEYWORDS",
            "ACCEPT_LICENSE",
            "FEATURES",
            "EMERGE_DEFAULT_OPTS",
        ]

        myvars.extend(
            portage.util.grabfile(settings["PORTDIR"] + "/profiles/info_vars")
        )

    myvars_ignore_defaults = {
        "PORTAGE_BZIP2_COMMAND": "bzip2",
    }

    skipped_vars = ["PORTAGE_REPOSITORIES"]
    # Deprecated variables
    skipped_vars.extend(("PORTDIR", "PORTDIR_OVERLAY", "SYNC"))

    myvars = set(myvars)
    myvars.difference_update(skipped_vars)
    myvars = sorted(myvars)

    use_expand = settings.get("USE_EXPAND", "").split()
    use_expand.sort()
    unset_vars = []

    for k in myvars:
        v = settings.get(k)
        if v is not None:
            if k != "USE":
                default = myvars_ignore_defaults.get(k)
                if default is not None and default == v:
                    continue

                v = _hide_url_passwd(v)

                append('%s="%s"' % (k, v))
            else:
                use = set(v.split())
                for varname in use_expand:
                    flag_prefix = varname.lower() + "_"
                    for f in list(use):
                        if f.startswith(flag_prefix):
                            use.remove(f)
                use = list(use)
                use.sort()
                use = ['USE="%s"' % " ".join(use)]
                for varname in use_expand:
                    myval = settings.get(varname)
                    if myval:
                        use.append('%s="%s"' % (varname, myval))
                append(" ".join(use))
        else:
            unset_vars.append(k)
    if unset_vars:
        append("Unset:  " + ", ".join(unset_vars))
    append("")
    append("")
    writemsg_stdout("\n".join(output_buffer), noiselevel=-1)
    del output_buffer[:]

    # If some packages were found...
    if mypkgs:
        # Get our global settings (we only print stuff if it varies from
        # the current config)
        mydesiredvars = ["CHOST", "CFLAGS", "CXXFLAGS", "FEATURES", "LDFLAGS"]
        auxkeys = mydesiredvars + list(vardb._aux_cache_keys)
        auxkeys.append("DEFINED_PHASES")
        pkgsettings = portage.config(clone=settings)

        # Loop through each package
        # Only print settings if they differ from global settings
        header_title = "Package Settings"
        append(header_width * "=")
        append(header_title.rjust(int(header_width / 2 + len(header_title) / 2)))
        append(header_width * "=")
        append("")
        writemsg_stdout("\n".join(output_buffer), noiselevel=-1)
        del output_buffer[:]

        out = portage.output.EOutput()
        for mypkg in mypkgs:
            cpv = mypkg[0]
            pkg_type = mypkg[1]
            # Get all package specific variables
            if pkg_type == "installed":
                metadata = dict(zip(auxkeys, vardb.aux_get(cpv, auxkeys)))
            elif pkg_type == "ebuild":
                metadata = dict(zip(auxkeys, portdb.aux_get(cpv, auxkeys)))
            elif pkg_type == "binary":
                metadata = dict(zip(auxkeys, bindb.aux_get(cpv, auxkeys)))

            pkg = Package(
                built=(pkg_type != "ebuild"),
                cpv=cpv,
                installed=(pkg_type == "installed"),
                metadata=zip(
                    Package.metadata_keys,
                    (metadata.get(x, "") for x in Package.metadata_keys),
                ),
                root_config=root_config,
                type_name=pkg_type,
            )

            if pkg_type == "installed":
                append(
                    "\n%s was built with the following:"
                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
                )
            elif pkg_type == "ebuild":
                append(
                    "\n%s would be built with the following:"
                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
                )
            elif pkg_type == "binary":
                append(
                    "\n%s (non-installed binary) was built with the following:"
                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
                )

            append("%s" % pkg_use_display(pkg, myopts))
            if pkg_type == "installed":
                for myvar in mydesiredvars:
                    if metadata[myvar].split() != settings.get(myvar, "").split():
                        append('%s="%s"' % (myvar, metadata[myvar]))
            append("")
            append("")
            writemsg_stdout("\n".join(output_buffer), noiselevel=-1)
            del output_buffer[:]

            if metadata["DEFINED_PHASES"]:
                if "info" not in metadata["DEFINED_PHASES"].split():
                    continue

            writemsg_stdout(
                ">>> Attempting to run pkg_info() for '%s'\n" % pkg.cpv, noiselevel=-1
            )

            if pkg_type == "installed":
                ebuildpath = vardb.findname(pkg.cpv)
            elif pkg_type == "ebuild":
                ebuildpath = portdb.findname(pkg.cpv, myrepo=pkg.repo)
            elif pkg_type == "binary":
                binpkg_file = bindb.bintree.getname(pkg.cpv)
                ebuild_file_name = pkg.cpv.split("/")[1] + ".ebuild"
                binpkg_format = pkg.cpv._metadata.get("BINPKG_FORMAT", None)
                if not binpkg_format:
                    binpkg_format = get_binpkg_format(binpkg_file)
                if binpkg_format == "xpak":
                    ebuild_file_contents = portage.xpak.tbz2(binpkg_file).getfile(
                        ebuild_file_name
                    )
                elif binpkg_format == "gpkg":
                    ebuild_file_contents = portage.gpkg.gpkg(
                        settings, pkg.cpv, binpkg_file
                    ).get_metadata(ebuild_file_name)
                else:
                    continue
                tmpdir = tempfile.mkdtemp()
                ebuildpath = os.path.join(tmpdir, ebuild_file_name)
                file = open(ebuildpath, "w")
                file.write(ebuild_file_contents)
                file.close()

            if not ebuildpath or not os.path.exists(ebuildpath):
                out.ewarn("No ebuild found for '%s'" % pkg.cpv)
                continue

            if pkg_type == "installed":
                portage.doebuild(
                    ebuildpath,
                    "info",
                    settings=pkgsettings,
                    debug=(settings.get("PORTAGE_DEBUG", "") == 1),
                    mydbapi=trees[settings["EROOT"]]["vartree"].dbapi,
                    tree="vartree",
                )
            elif pkg_type == "ebuild":
                portage.doebuild(
                    ebuildpath,
                    "info",
                    settings=pkgsettings,
                    debug=(settings.get("PORTAGE_DEBUG", "") == 1),
                    mydbapi=trees[settings["EROOT"]]["porttree"].dbapi,
                    tree="porttree",
                )
            elif pkg_type == "binary":
                portage.doebuild(
                    ebuildpath,
                    "info",
                    settings=pkgsettings,
                    debug=(settings.get("PORTAGE_DEBUG", "") == 1),
                    mydbapi=trees[settings["EROOT"]]["bintree"].dbapi,
                    tree="bintree",
                )
                shutil.rmtree(tmpdir)


def action_regen(settings, portdb, max_jobs, max_load):
    xterm_titles = "notitles" not in settings.features
    emergelog(xterm_titles, " === regen")
    # regenerate cache entries
    sys.stdout.flush()

    regen = MetadataRegen(portdb, max_jobs=max_jobs, max_load=max_load, main=True)

    signum = run_main_scheduler(regen)
    if signum is not None:
        sys.exit(128 + signum)

    portage.writemsg_stdout("done!\n")
    return regen.returncode


def action_search(root_config, myopts, myfiles, spinner):
    if not myfiles:
        print("emerge: no search terms provided.")
    else:
        searchinstance = search(
            root_config,
            spinner,
            "--searchdesc" in myopts,
            "--quiet" not in myopts,
            "--usepkg" in myopts,
            "--usepkgonly" in myopts,
            search_index=myopts.get("--search-index", "y") != "n",
            search_similarity=myopts.get("--search-similarity"),
            fuzzy=myopts.get("--fuzzy-search") != "n",
            regex_auto=myopts.get("--regex-search-auto") != "n",
        )
        for mysearch in myfiles:
            try:
                searchinstance.execute(mysearch)
            except re.error as comment:
                print(
                    '\n!!! Regular expression error in "%s": %s' % (mysearch, comment)
                )
                sys.exit(1)
            searchinstance.output()


def action_sync(
    emerge_config,
    trees=DeprecationWarning,
    mtimedb=DeprecationWarning,
    opts=DeprecationWarning,
    action=DeprecationWarning,
):

    if not isinstance(emerge_config, _emerge_config):
        warnings.warn(
            "_emerge.actions.action_sync() now expects "
            "an _emerge_config instance as the first parameter",
            DeprecationWarning,
            stacklevel=2,
        )
        emerge_config = load_emerge_config(
            action=action, args=[], trees=trees, opts=opts
        )

    syncer = SyncRepos(emerge_config)
    return_messages = "--quiet" not in emerge_config.opts
    options = {"return-messages": return_messages}
    if emerge_config.args:
        options["repo"] = emerge_config.args
        success, msgs = syncer.repo(options=options)
    else:
        success, msgs = syncer.auto_sync(options=options)
    if return_messages:
        print_results(msgs)
    elif msgs and not success:
        writemsg_level(
            "".join("%s\n" % (line,) for line in msgs),
            level=logging.ERROR,
            noiselevel=-1,
        )

    return os.EX_OK if success else 1


def action_uninstall(settings, trees, ldpath_mtimes, opts, action, files, spinner):
    # For backward compat, some actions do not require leading '='.
    ignore_missing_eq = action in ("clean", "rage-clean", "unmerge")
    root = settings["ROOT"]
    eroot = settings["EROOT"]
    vardb = trees[settings["EROOT"]]["vartree"].dbapi
    valid_atoms = []
    lookup_owners = []

    # Ensure atoms are valid before calling unmerge().
    # For backward compat, leading '=' is not required.
    for x in files:
        if is_valid_package_atom(x, allow_repo=True) or (
            ignore_missing_eq and is_valid_package_atom("=" + x)
        ):

            try:
                atom = dep_expand(x, mydb=vardb, settings=settings)
            except portage.exception.AmbiguousPackageName as e:
                msg = (
                    'The short ebuild name "'
                    + x
                    + '" is ambiguous.  Please specify '
                    + "one of the following "
                    + "fully-qualified ebuild names instead:"
                )
                for line in textwrap.wrap(msg, 70):
                    writemsg_level(
                        "!!! %s\n" % (line,), level=logging.ERROR, noiselevel=-1
                    )
                for i in e.args[0]:
                    writemsg_level(
                        "    %s\n" % colorize("INFORM", i),
                        level=logging.ERROR,
                        noiselevel=-1,
                    )
                writemsg_level("\n", level=logging.ERROR, noiselevel=-1)
                return 1
            else:
                if atom.use and atom.use.conditional:
                    writemsg_level(
                        (
                            "\n\n!!! '%s' contains a conditional "
                            + "which is not allowed.\n"
                        )
                        % (x,),
                        level=logging.ERROR,
                        noiselevel=-1,
                    )
                    writemsg_level(
                        "!!! Please check ebuild(5) for full details.\n",
                        level=logging.ERROR,
                    )
                    return 1
                valid_atoms.append(atom)

        elif x.startswith(os.sep):
            if not x.startswith(eroot):
                writemsg_level(
                    ("!!! '%s' does not start with" + " $EROOT.\n") % x,
                    level=logging.ERROR,
                    noiselevel=-1,
                )
                return 1
            # Queue these up since it's most efficient to handle
            # multiple files in a single iter_owners() call.
            lookup_owners.append(x)

        elif x.startswith(SETPREFIX) and action == "deselect":
            valid_atoms.append(x)

        elif "*" in x:
            try:
                ext_atom = Atom(x, allow_repo=True, allow_wildcard=True)
            except InvalidAtom:
                msg = []
                msg.append("'%s' is not a valid package atom." % (x,))
                msg.append("Please check ebuild(5) for full details.")
                writemsg_level(
                    "".join("!!! %s\n" % line for line in msg),
                    level=logging.ERROR,
                    noiselevel=-1,
                )
                return 1

            for cpv in vardb.cpv_all():
                if portage.match_from_list(ext_atom, [cpv]):
                    require_metadata = False
                    atom = portage.cpv_getkey(cpv)
                    if ext_atom.operator == "=*":
                        atom = "=" + atom + "-" + portage.versions.cpv_getversion(cpv)
                    if ext_atom.slot:
                        atom += _slot_separator + ext_atom.slot
                        require_metadata = True
                    if ext_atom.repo:
                        atom += _repo_separator + ext_atom.repo
                        require_metadata = True

                    atom = Atom(atom, allow_repo=True)
                    if require_metadata:
                        try:
                            cpv = vardb._pkg_str(cpv, ext_atom.repo)
                        except (KeyError, InvalidData):
                            continue
                        if not portage.match_from_list(atom, [cpv]):
                            continue

                    valid_atoms.append(atom)

        else:
            msg = []
            msg.append("'%s' is not a valid package atom." % (x,))
            msg.append("Please check ebuild(5) for full details.")
            writemsg_level(
                "".join("!!! %s\n" % line for line in msg),
                level=logging.ERROR,
                noiselevel=-1,
            )
            return 1

    if lookup_owners:
        relative_paths = []
        search_for_multiple = False
        if len(lookup_owners) > 1:
            search_for_multiple = True

        for x in lookup_owners:
            if not search_for_multiple and os.path.isdir(x):
                search_for_multiple = True
            relative_paths.append(x[len(root) - 1 :])

        owners = set()
        for pkg, relative_path in vardb._owners.iter_owners(relative_paths):
            owners.add(pkg.mycpv)
            if not search_for_multiple:
                break

        if owners:
            for cpv in owners:
                pkg = vardb._pkg_str(cpv, None)
                atom = "%s:%s" % (pkg.cp, pkg.slot)
                valid_atoms.append(portage.dep.Atom(atom))
        else:
            writemsg_level(
                ("!!! '%s' is not claimed " + "by any package.\n") % lookup_owners[0],
                level=logging.WARNING,
                noiselevel=-1,
            )

    if files and not valid_atoms:
        return 1

    if (
        action == "unmerge"
        and "--quiet" not in opts
        and "--quiet-unmerge-warn" not in opts
    ):
        msg = (
            "This action can remove important packages! "
            + "In order to be safer, use "
            + "`emerge -pv --depclean <atom>` to check for "
            + "reverse dependencies before removing packages."
        )
        out = portage.output.EOutput()
        for line in textwrap.wrap(msg, 72):
            out.ewarn(line)

    if action == "deselect":
        return action_deselect(settings, trees, opts, valid_atoms)

    # Use the same logic as the Scheduler class to trigger redirection
    # of ebuild pkg_prerm/postrm phase output to logs as appropriate
    # for options such as --jobs, --quiet and --quiet-build.
    max_jobs = opts.get("--jobs", 1)
    background = (
        max_jobs is True
        or max_jobs > 1
        or "--quiet" in opts
        or opts.get("--quiet-build") == "y"
    )
    sched_iface = SchedulerInterface(
        global_event_loop(), is_background=lambda: background
    )

    if background:
        settings.unlock()
        settings["PORTAGE_BACKGROUND"] = "1"
        settings.backup_changes("PORTAGE_BACKGROUND")
        settings.lock()

    if action in ("clean", "rage-clean", "unmerge") or (
        action == "prune" and "--nodeps" in opts
    ):
        # When given a list of atoms, unmerge them in the order given.
        ordered = action in ("rage-clean", "unmerge")
        rval = unmerge(
            trees[settings["EROOT"]]["root_config"],
            opts,
            action,
            valid_atoms,
            ldpath_mtimes,
            ordered=ordered,
            scheduler=sched_iface,
        )
    else:
        rval = action_depclean(
            settings,
            trees,
            ldpath_mtimes,
            opts,
            action,
            valid_atoms,
            spinner,
            scheduler=sched_iface,
        )

    return rval


def adjust_configs(myopts, trees):
    for myroot, mytrees in trees.items():
        mysettings = trees[myroot]["vartree"].settings
        mysettings.unlock()

        # For --usepkgonly mode, propagate settings from the binary package
        # database, so that it's possible to operate without dependence on
        # a local ebuild repository and profile.
        if "--usepkgonly" in myopts and mytrees["bintree"]._propagate_config(
            mysettings
        ):
            # Also propagate changes to the portdbapi doebuild_settings
            # attribute which is used by Package instances for USE
            # calculations (in support of --binpkg-respect-use).
            mytrees["porttree"].dbapi.doebuild_settings = portage.config(
                clone=mysettings
            )

        adjust_config(myopts, mysettings)
        mysettings.lock()


def adjust_config(myopts, settings):
    """Make emerge specific adjustments to the config."""

    # Kill noauto as it will break merges otherwise.
    if "noauto" in settings.features:
        settings.features.remove("noauto")

    fail_clean = myopts.get("--fail-clean")
    if fail_clean is not None:
        if fail_clean is True and "fail-clean" not in settings.features:
            settings.features.add("fail-clean")
        elif fail_clean == "n" and "fail-clean" in settings.features:
            settings.features.remove("fail-clean")

    CLEAN_DELAY = 5
    try:
        CLEAN_DELAY = int(settings.get("CLEAN_DELAY", str(CLEAN_DELAY)))
    except ValueError as e:
        portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
        portage.writemsg(
            "!!! Unable to parse integer: CLEAN_DELAY='%s'\n" % settings["CLEAN_DELAY"],
            noiselevel=-1,
        )
    settings["CLEAN_DELAY"] = str(CLEAN_DELAY)
    settings.backup_changes("CLEAN_DELAY")

    EMERGE_WARNING_DELAY = 10
    try:
        EMERGE_WARNING_DELAY = int(
            settings.get("EMERGE_WARNING_DELAY", str(EMERGE_WARNING_DELAY))
        )
    except ValueError as e:
        portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
        portage.writemsg(
            "!!! Unable to parse integer: EMERGE_WARNING_DELAY='%s'\n"
            % settings["EMERGE_WARNING_DELAY"],
            noiselevel=-1,
        )
    settings["EMERGE_WARNING_DELAY"] = str(EMERGE_WARNING_DELAY)
    settings.backup_changes("EMERGE_WARNING_DELAY")

    buildpkg = myopts.get("--buildpkg")
    if buildpkg is True:
        settings.features.add("buildpkg")
    elif buildpkg == "n":
        settings.features.discard("buildpkg")

    if "--quiet" in myopts:
        settings["PORTAGE_QUIET"] = "1"
        settings.backup_changes("PORTAGE_QUIET")

    if "--verbose" in myopts:
        settings["PORTAGE_VERBOSE"] = "1"
        settings.backup_changes("PORTAGE_VERBOSE")

    # Set so that configs will be merged regardless of remembered status
    if "--noconfmem" in myopts:
        settings["NOCONFMEM"] = "1"
        settings.backup_changes("NOCONFMEM")

    # Set various debug markers... They should be merged somehow.
    PORTAGE_DEBUG = 0
    try:
        PORTAGE_DEBUG = int(settings.get("PORTAGE_DEBUG", str(PORTAGE_DEBUG)))
        if PORTAGE_DEBUG not in (0, 1):
            portage.writemsg(
                "!!! Invalid value: PORTAGE_DEBUG='%i'\n" % PORTAGE_DEBUG, noiselevel=-1
            )
            portage.writemsg("!!! PORTAGE_DEBUG must be either 0 or 1\n", noiselevel=-1)
            PORTAGE_DEBUG = 0
    except ValueError as e:
        portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
        portage.writemsg(
            "!!! Unable to parse integer: PORTAGE_DEBUG='%s'\n"
            % settings["PORTAGE_DEBUG"],
            noiselevel=-1,
        )
        del e
    if "--debug" in myopts:
        PORTAGE_DEBUG = 1
    settings["PORTAGE_DEBUG"] = str(PORTAGE_DEBUG)
    settings.backup_changes("PORTAGE_DEBUG")

    if settings.get("NOCOLOR") not in ("yes", "true"):
        portage.output.havecolor = 1

    # The explicit --color < y | n > option overrides the NOCOLOR environment
    # variable and stdout auto-detection.
    if "--color" in myopts:
        if "y" == myopts["--color"]:
            portage.output.havecolor = 1
            settings["NOCOLOR"] = "false"
        else:
            portage.output.havecolor = 0
            settings["NOCOLOR"] = "true"
        settings.backup_changes("NOCOLOR")
    elif settings.get("TERM") == "dumb" or not sys.stdout.isatty():
        portage.output.havecolor = 0
        settings["NOCOLOR"] = "true"
        settings.backup_changes("NOCOLOR")

    if "--pkg-format" in myopts:
        settings["PORTAGE_BINPKG_FORMAT"] = myopts["--pkg-format"]
        settings.backup_changes("PORTAGE_BINPKG_FORMAT")


def display_missing_pkg_set(root_config, set_name):

    msg = []
    msg.append(
        ("emerge: There are no sets to satisfy '%s'. " + "The following sets exist:")
        % colorize("INFORM", set_name)
    )
    msg.append("")

    for s in sorted(root_config.sets):
        msg.append("    %s" % s)
    msg.append("")

    writemsg_level("".join("%s\n" % l for l in msg), level=logging.ERROR, noiselevel=-1)


def relative_profile_path(portdir, abs_profile):
    realpath = os.path.realpath(abs_profile)
    basepath = os.path.realpath(os.path.join(portdir, "profiles"))
    if realpath.startswith(basepath):
        profilever = realpath[1 + len(basepath) :]
    else:
        profilever = None
    return profilever


def getportageversion(portdir, _unused, profile, chost, vardb):
    pythonver = "python %d.%d.%d-%s-%d" % sys.version_info[:]
    profilever = None
    repositories = vardb.settings.repositories
    if profile:
        profilever = relative_profile_path(portdir, profile)
        if profilever is None:
            try:
                for parent in portage.grabfile(os.path.join(profile, "parent")):
                    profilever = relative_profile_path(
                        portdir, os.path.join(profile, parent)
                    )
                    if profilever is not None:
                        break
                    colon = parent.find(":")
                    if colon != -1:
                        p_repo_name = parent[:colon]
                        try:
                            p_repo_loc = repositories.get_location_for_name(p_repo_name)
                        except KeyError:
                            pass
                        else:
                            profilever = relative_profile_path(
                                p_repo_loc,
                                os.path.join(
                                    p_repo_loc, "profiles", parent[colon + 1 :]
                                ),
                            )
                            if profilever is not None:
                                break
            except portage.exception.PortageException:
                pass

            if profilever is None:
                try:
                    profilever = "!" + os.readlink(profile)
                except OSError:
                    pass

    if profilever is None:
        profilever = "unavailable"

    libcver = []
    libclist = set()
    for atom in expand_new_virt(vardb, portage.const.LIBC_PACKAGE_ATOM):
        if not atom.blocker:
            libclist.update(vardb.match(atom))
    if libclist:
        for cpv in sorted(libclist):
            libc_split = portage.catpkgsplit(cpv)[1:]
            if libc_split[-1] == "r0":
                libc_split = libc_split[:-1]
            libcver.append("-".join(libc_split))
    else:
        libcver = ["unavailable"]

    gccver = getgccversion(chost)
    unameout = platform.release() + " " + platform.machine()

    return "Portage %s (%s, %s, %s, %s, %s)" % (
        portage.VERSION,
        pythonver,
        profilever,
        gccver,
        ",".join(libcver),
        unameout,
    )


class _emerge_config(SlotObject):

    __slots__ = ("action", "args", "opts", "running_config", "target_config", "trees")

    # Support unpack as tuple, for load_emerge_config backward compatibility.
    def __iter__(self):
        yield self.target_config.settings
        yield self.trees
        yield self.target_config.mtimedb

    def __getitem__(self, index):
        return list(self)[index]

    def __len__(self):
        return 3


def load_emerge_config(emerge_config=None, env=None, **kargs):

    if emerge_config is None:
        emerge_config = _emerge_config(**kargs)

    env = os.environ if env is None else env
    kwargs = {"env": env}
    for k, envvar in (
        ("config_root", "PORTAGE_CONFIGROOT"),
        ("target_root", "ROOT"),
        ("sysroot", "SYSROOT"),
        ("eprefix", "EPREFIX"),
    ):
        v = env.get(envvar)
        if v is not None:
            kwargs[k] = v
    emerge_config.trees = portage.create_trees(trees=emerge_config.trees, **kwargs)

    for root_trees in emerge_config.trees.values():
        settings = root_trees["vartree"].settings
        settings._init_dirs()
        setconfig = load_default_config(settings, root_trees)
        root_config = RootConfig(settings, root_trees, setconfig)
        if "root_config" in root_trees:
            # Propagate changes to the existing instance,
            # which may be referenced by a depgraph.
            root_trees["root_config"].update(root_config)
        else:
            root_trees["root_config"] = root_config

    target_eroot = emerge_config.trees._target_eroot
    emerge_config.target_config = emerge_config.trees[target_eroot]["root_config"]
    emerge_config.target_config.mtimedb = portage.MtimeDB(
        os.path.join(target_eroot, portage.CACHE_PATH, "mtimedb")
    )
    emerge_config.running_config = emerge_config.trees[
        emerge_config.trees._running_eroot
    ]["root_config"]
    QueryCommand._db = emerge_config.trees

    return emerge_config


def getgccversion(chost=None):
    """
    rtype: C{str}
    return:  the current in-use gcc version
    """

    gcc_ver_command = ["gcc", "-dumpversion"]
    gcc_ver_prefix = "gcc-"

    gcc_not_found_error = red(
        "!!! No gcc found. You probably need to 'source /etc/profile'\n"
        + "!!! to update the environment of this terminal and possibly\n"
        + "!!! other terminals also.\n"
    )

    if chost:
        try:
            proc = subprocess.Popen(
                ["gcc-config", "-c"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
            )
        except OSError:
            myoutput = None
            mystatus = 1
        else:
            myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n")
            mystatus = proc.wait()
        if mystatus == os.EX_OK and myoutput.startswith(chost + "-"):
            return myoutput.replace(chost + "-", gcc_ver_prefix, 1)

        try:
            proc = subprocess.Popen(
                [chost + "-" + gcc_ver_command[0]] + gcc_ver_command[1:],
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
            )
        except OSError:
            myoutput = None
            mystatus = 1
        else:
            myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n")
            mystatus = proc.wait()
        if mystatus == os.EX_OK:
            return gcc_ver_prefix + myoutput

    try:
        proc = subprocess.Popen(
            gcc_ver_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        )
    except OSError:
        myoutput = None
        mystatus = 1
    else:
        myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n")
        mystatus = proc.wait()
    if mystatus == os.EX_OK:
        return gcc_ver_prefix + myoutput

    portage.writemsg(gcc_not_found_error, noiselevel=-1)
    return "[unavailable]"


# Warn about features that may confuse users and
# lead them to report invalid bugs.
_emerge_features_warn = frozenset(["keeptemp", "keepwork"])


def validate_ebuild_environment(trees):
    features_warn = set()
    for myroot in trees:
        settings = trees[myroot]["vartree"].settings
        settings.validate()
        features_warn.update(_emerge_features_warn.intersection(settings.features))

    if features_warn:
        msg = (
            "WARNING: The FEATURES variable contains one "
            + "or more values that should be disabled under "
            + "normal circumstances: %s" % " ".join(features_warn)
        )
        out = portage.output.EOutput()
        for line in textwrap.wrap(msg, 65):
            out.ewarn(line)

    check_locale()


def check_procfs():
    procfs_path = "/proc"
    if platform.system() not in ("Linux",) or os.path.ismount(procfs_path):
        return os.EX_OK
    msg = "It seems that %s is not mounted. You have been warned." % procfs_path
    writemsg_level(
        "".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
        level=logging.ERROR,
        noiselevel=-1,
    )
    return 1


def config_protect_check(trees):
    for root, root_trees in trees.items():
        settings = root_trees["root_config"].settings
        if not settings.get("CONFIG_PROTECT"):
            msg = "!!! CONFIG_PROTECT is empty"
            if settings["ROOT"] != "/":
                msg += " for '%s'" % root
            msg += "\n"
            writemsg_level(msg, level=logging.WARN, noiselevel=-1)


def apply_priorities(settings):
    ionice(settings)
    nice(settings)
    set_scheduling_policy(settings)


def nice(settings):
    try:
        os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
    except (OSError, ValueError) as e:
        out = portage.output.EOutput()
        out.eerror(
            "Failed to change nice value to '%s'"
            % settings.get("PORTAGE_NICENESS", "0")
        )
        out.eerror("%s\n" % str(e))


def ionice(settings):

    ionice_cmd = settings.get("PORTAGE_IONICE_COMMAND")
    if ionice_cmd:
        ionice_cmd = portage.util.shlex_split(ionice_cmd)
    if not ionice_cmd:
        return

    variables = {"PID": str(portage.getpid())}
    cmd = [varexpand(x, mydict=variables) for x in ionice_cmd]

    try:
        rval = portage.process.spawn(cmd, env=os.environ)
    except portage.exception.CommandNotFound:
        # The OS kernel probably doesn't support ionice,
        # so return silently.
        return

    if rval != os.EX_OK:
        out = portage.output.EOutput()
        out.eerror("PORTAGE_IONICE_COMMAND returned %d" % (rval,))
        out.eerror(
            "See the make.conf(5) man page for PORTAGE_IONICE_COMMAND usage instructions."
        )


def set_scheduling_policy(settings):
    scheduling_policy = settings.get("PORTAGE_SCHEDULING_POLICY")
    scheduling_priority = settings.get("PORTAGE_SCHEDULING_PRIORITY")

    if platform.system() != "Linux" or not scheduling_policy:
        return os.EX_OK

    policies = {
        "other": os.SCHED_OTHER,
        "batch": os.SCHED_BATCH,
        "idle": os.SCHED_IDLE,
        "fifo": os.SCHED_FIFO,
        "round-robin": os.SCHED_RR,
    }

    out = portage.output.EOutput()

    if scheduling_policy in policies:
        policy = policies[scheduling_policy]
    else:
        out.eerror("Invalid policy in PORTAGE_SCHEDULING_POLICY.")
        out.eerror(
            "See the make.conf(5) man page for PORTAGE_SCHEDULING_POLICY usage instructions."
        )
        return os.EX_USAGE

    if not scheduling_priority:
        scheduling_priority = os.sched_get_priority_min(policy)
    else:
        scheduling_priority = int(scheduling_priority)
        if scheduling_priority not in range(
            os.sched_get_priority_min(policy), os.sched_get_priority_max(policy) + 1
        ):
            out.eerror("Invalid priority in PORTAGE_SCHEDULING_PRIORITY.")
            out.eerror(
                "See the make.conf(5) man page for PORTAGE_SCHEDULING_PRIORITY usage instructions."
            )
            return os.EX_USAGE

    os.sched_setscheduler(portage.getpid(), policy, os.sched_param(scheduling_priority))

    return os.EX_OK


def setconfig_fallback(root_config):
    setconfig = root_config.setconfig
    setconfig._create_default_config()
    setconfig._parse(update=True)
    root_config.sets = setconfig.getSets()


def get_missing_sets(root_config):
    # emerge requires existence of "world", "selected", and "system"
    missing_sets = []

    for s in (
        "selected",
        "system",
        "world",
    ):
        if s not in root_config.sets:
            missing_sets.append(s)

    return missing_sets


def missing_sets_warning(root_config, missing_sets):
    if len(missing_sets) > 2:
        missing_sets_str = ", ".join('"%s"' % s for s in missing_sets[:-1])
        missing_sets_str += ', and "%s"' % missing_sets[-1]
    elif len(missing_sets) == 2:
        missing_sets_str = '"%s" and "%s"' % tuple(missing_sets)
    else:
        missing_sets_str = '"%s"' % missing_sets[-1]
    msg = [
        "emerge: incomplete set configuration, "
        + "missing set(s): %s" % missing_sets_str
    ]
    if root_config.sets:
        msg.append("        sets defined: %s" % ", ".join(root_config.sets))
    global_config_path = portage.const.GLOBAL_CONFIG_PATH
    if portage.const.EPREFIX:
        global_config_path = os.path.join(
            portage.const.EPREFIX, portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep)
        )
    msg.append(
        "        This usually means that '%s'"
        % (os.path.join(global_config_path, "sets/portage.conf"),)
    )
    msg.append("        is missing or corrupt.")
    msg.append("        Falling back to default world and system set configuration!!!")
    for line in msg:
        writemsg_level(line + "\n", level=logging.ERROR, noiselevel=-1)


def ensure_required_sets(trees):
    warning_shown = False
    for root_trees in trees.values():
        missing_sets = get_missing_sets(root_trees["root_config"])
        if missing_sets and not warning_shown:
            warning_shown = True
            missing_sets_warning(root_trees["root_config"], missing_sets)
        if missing_sets:
            setconfig_fallback(root_trees["root_config"])


def expand_set_arguments(myfiles, myaction, root_config):
    retval = os.EX_OK
    setconfig = root_config.setconfig

    sets = setconfig.getSets()

    # In order to know exactly which atoms/sets should be added to the
    # world file, the depgraph performs set expansion later. It will get
    # confused about where the atoms came from if it's not allowed to
    # expand them itself.
    do_not_expand = myaction is None
    newargs = []
    for a in myfiles:
        if a in ("system", "world"):
            newargs.append(SETPREFIX + a)
        else:
            newargs.append(a)
    myfiles = newargs
    del newargs
    newargs = []

    # separators for set arguments
    ARG_START = "{"
    ARG_END = "}"

    for i in range(0, len(myfiles)):
        if myfiles[i].startswith(SETPREFIX):
            start = 0
            end = 0
            x = myfiles[i][len(SETPREFIX) :]
            newset = ""
            while x:
                start = x.find(ARG_START)
                end = x.find(ARG_END)
                if start > 0 and start < end:
                    namepart = x[:start]
                    argpart = x[start + 1 : end]

                    # TODO: implement proper quoting
                    args = argpart.split(",")
                    options = {}
                    for a in args:
                        if "=" in a:
                            k, v = a.split("=", 1)
                            options[k] = v
                        else:
                            options[a] = "True"
                    setconfig.update(namepart, options)
                    newset += x[: start - len(namepart)] + namepart
                    x = x[end + len(ARG_END) :]
                else:
                    newset += x
                    x = ""
            myfiles[i] = SETPREFIX + newset

    sets = setconfig.getSets()

    # display errors that occurred while loading the SetConfig instance
    for e in setconfig.errors:
        print(colorize("BAD", "Error during set creation: %s" % e))

    unmerge_actions = ("unmerge", "prune", "clean", "depclean", "rage-clean")

    for a in myfiles:
        if a.startswith(SETPREFIX):
            s = a[len(SETPREFIX) :]
            if s not in sets:
                display_missing_pkg_set(root_config, s)
                return (None, 1)
            if s == "installed":
                msg = (
                    "The @installed set is not recommended when "
                    "updating packages because it will often "
                    "introduce unsolved blocker conflicts. Please "
                    "refer to bug #387059 for details."
                )
                out = portage.output.EOutput()
                for line in textwrap.wrap(msg, 57):
                    out.ewarn(line)
            setconfig.active.append(s)

            if do_not_expand:
                # Loading sets can be slow, so skip it here, in order
                # to allow the depgraph to indicate progress with the
                # spinner while sets are loading (bug #461412).
                newargs.append(a)
                continue

            try:
                set_atoms = setconfig.getSetAtoms(s)
            except portage.exception.PackageSetNotFound as e:
                writemsg_level(
                    (
                        "emerge: the given set '%s' "
                        + "contains a non-existent set named '%s'.\n"
                    )
                    % (s, e),
                    level=logging.ERROR,
                    noiselevel=-1,
                )
                if (
                    s in ("world", "selected")
                    and SETPREFIX + e.value in sets["selected"]
                ):
                    writemsg_level(
                        (
                            "Use `emerge --deselect %s%s` to "
                            "remove this set from world_sets.\n"
                        )
                        % (
                            SETPREFIX,
                            e,
                        ),
                        level=logging.ERROR,
                        noiselevel=-1,
                    )
                return (None, 1)
            if myaction in unmerge_actions and not sets[s].supportsOperation("unmerge"):
                writemsg_level(
                    "emerge: the given set '%s' does " % s
                    + "not support unmerge operations\n",
                    level=logging.ERROR,
                    noiselevel=-1,
                )
                retval = 1
            elif not set_atoms:
                writemsg_level(
                    "emerge: '%s' is an empty set\n" % s,
                    level=logging.INFO,
                    noiselevel=-1,
                )
            else:
                newargs.extend(set_atoms)
            for error_msg in sets[s].errors:
                writemsg_level(
                    "%s\n" % (error_msg,), level=logging.ERROR, noiselevel=-1
                )
        else:
            newargs.append(a)
    return (newargs, retval)


def repo_name_check(trees):
    missing_repo_names = set()
    for root_trees in trees.values():
        porttree = root_trees.get("porttree")
        if porttree:
            portdb = porttree.dbapi
            missing_repo_names.update(portdb.getMissingRepoNames())

    # Skip warnings about missing repo_name entries for
    # /usr/local/portage (see bug #248603).
    try:
        missing_repo_names.remove("/usr/local/portage")
    except KeyError:
        pass

    if missing_repo_names:
        msg = []
        msg.append(
            "WARNING: One or more repositories " + "have missing repo_name entries:"
        )
        msg.append("")
        for p in missing_repo_names:
            msg.append("\t%s/profiles/repo_name" % (p,))
        msg.append("")
        msg.extend(
            textwrap.wrap(
                "NOTE: Each repo_name entry "
                + "should be a plain text file containing a unique "
                + "name for the repository on the first line.",
                70,
            )
        )
        msg.append("\n")
        writemsg_level(
            "".join("%s\n" % l for l in msg), level=logging.WARNING, noiselevel=-1
        )

    return bool(missing_repo_names)


def repo_name_duplicate_check(trees):
    ignored_repos = {}
    for root, root_trees in trees.items():
        if "porttree" in root_trees:
            portdb = root_trees["porttree"].dbapi
            if portdb.settings.get("PORTAGE_REPO_DUPLICATE_WARN") != "0":
                for repo_name, paths in portdb.getIgnoredRepos():
                    k = (root, repo_name, portdb.getRepositoryPath(repo_name))
                    ignored_repos.setdefault(k, []).extend(paths)

    if ignored_repos:
        msg = []
        msg.append(
            "WARNING: One or more repositories " + "have been ignored due to duplicate"
        )
        msg.append("  profiles/repo_name entries:")
        msg.append("")
        for k in sorted(ignored_repos):
            msg.append("  %s overrides" % ", ".join(k))
            for path in ignored_repos[k]:
                msg.append("    %s" % (path,))
            msg.append("")
        msg.extend(
            "  " + x
            for x in textwrap.wrap(
                "All profiles/repo_name entries must be unique in order "
                + "to avoid having duplicates ignored. "
                + 'Set PORTAGE_REPO_DUPLICATE_WARN="0" in '
                + "/etc/portage/make.conf if you would like to disable this warning."
            )
        )
        msg.append("\n")
        writemsg_level(
            "".join("%s\n" % l for l in msg), level=logging.WARNING, noiselevel=-1
        )

    return bool(ignored_repos)


def run_action(emerge_config):

    # skip global updates prior to sync, since it's called after sync
    if (
        emerge_config.action not in ("help", "info", "sync", "version")
        and emerge_config.opts.get("--package-moves") != "n"
        and _global_updates(
            emerge_config.trees,
            emerge_config.target_config.mtimedb["updates"],
            quiet=("--quiet" in emerge_config.opts),
        )
    ):
        emerge_config.target_config.mtimedb.commit()
        # Reload the whole config from scratch.
        load_emerge_config(emerge_config=emerge_config)

        # Let's autoclean if we applied updates, rather than always doing it
        # bug #792195
        emerge_config.target_config.settings.unlock()
        emerge_config.target_config.settings["AUTOCLEAN"] = "yes"
        emerge_config.target_config.settings.backup_changes("AUTOCLEAN")
        emerge_config.target_config.settings.lock()

    xterm_titles = "notitles" not in emerge_config.target_config.settings.features
    if xterm_titles:
        xtermTitle("emerge")

    if "--digest" in emerge_config.opts:
        os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " digest"
        # Reload the whole config from scratch so that the portdbapi internal
        # config is updated with new FEATURES.
        load_emerge_config(emerge_config=emerge_config)

    # NOTE: adjust_configs() can map options to FEATURES, so any relevant
    # options adjustments should be made prior to calling adjust_configs().
    if "--buildpkgonly" in emerge_config.opts:
        emerge_config.opts["--buildpkg"] = True

    if "getbinpkg" in emerge_config.target_config.settings.features:
        emerge_config.opts["--getbinpkg"] = True

    if "--getbinpkgonly" in emerge_config.opts:
        emerge_config.opts["--getbinpkg"] = True

    if "--getbinpkgonly" in emerge_config.opts:
        emerge_config.opts["--usepkgonly"] = True

    if "--getbinpkg" in emerge_config.opts:
        emerge_config.opts["--usepkg"] = True

    if "--usepkgonly" in emerge_config.opts:
        emerge_config.opts["--usepkg"] = True

    # Populate the bintree with current --getbinpkg setting.
    # This needs to happen before:
    # * expand_set_arguments, in case any sets use the bintree
    # * adjust_configs and profile_check, in order to propagate settings
    #   implicit IUSE and USE_EXPAND settings from the binhost(s)
    if emerge_config.action in ("search", None) and "--usepkg" in emerge_config.opts:
        for mytrees in emerge_config.trees.values():
            kwargs = {}
            if (
                mytrees is emerge_config.target_config.trees
                and emerge_config.target_config is not emerge_config.running_config
                and emerge_config.opts.get("--quickpkg-direct", "n") == "y"
            ):
                kwargs["add_repos"] = (
                    emerge_config.running_config.trees["vartree"].dbapi,
                )

            try:
                mytrees["bintree"].populate(
                    getbinpkgs="--getbinpkg" in emerge_config.opts, **kwargs
                )
            except ParseError as e:
                writemsg(
                    "\n\n!!!%s.\nSee make.conf(5) for more info.\n" % (e,),
                    noiselevel=-1,
                )
                return 1

    adjust_configs(emerge_config.opts, emerge_config.trees)

    if profile_check(emerge_config.trees, emerge_config.action) != os.EX_OK:
        return 1

    apply_priorities(emerge_config.target_config.settings)

    if (
        "--autounmask-continue" in emerge_config.opts
        and emerge_config.opts.get("--autounmask") == "n"
    ):
        writemsg_level(
            " %s --autounmask-continue has been disabled by --autounmask=n\n"
            % warn("*"),
            level=logging.WARNING,
            noiselevel=-1,
        )

    for fmt in emerge_config.target_config.settings.get(
        "PORTAGE_BINPKG_FORMAT", ""
    ).split():
        if not fmt in portage.const.SUPPORTED_BINPKG_FORMATS:
            if "--pkg-format" in emerge_config.opts:
                problematic = "--pkg-format"
            else:
                problematic = "PORTAGE_BINPKG_FORMAT"

            writemsg_level(
                (
                    "emerge: %s is not set correctly. Format "
                    + "'%s' is not supported.\n"
                )
                % (problematic, fmt),
                level=logging.ERROR,
                noiselevel=-1,
            )
            return 1

    if emerge_config.action == "version":
        writemsg_stdout(
            getportageversion(
                emerge_config.target_config.settings["PORTDIR"],
                None,
                emerge_config.target_config.settings.profile_path,
                emerge_config.target_config.settings.get("CHOST"),
                emerge_config.target_config.trees["vartree"].dbapi,
            )
            + "\n",
            noiselevel=-1,
        )
        return 0
    if emerge_config.action == "help":
        emerge_help()
        return 0

    spinner = stdout_spinner()
    if "candy" in emerge_config.target_config.settings.features:
        spinner.update = spinner.update_scroll

    if "--quiet" not in emerge_config.opts:
        portage.deprecated_profile_check(settings=emerge_config.target_config.settings)
        repo_name_check(emerge_config.trees)
        repo_name_duplicate_check(emerge_config.trees)
        config_protect_check(emerge_config.trees)
    check_procfs()

    for mytrees in emerge_config.trees.values():
        mydb = mytrees["porttree"].dbapi
        # Freeze the portdbapi for performance (memoize all xmatch results).
        mydb.freeze()

    del mytrees, mydb

    for x in emerge_config.args:
        if x.endswith((".ebuild", ".tbz2")) and os.path.exists(os.path.abspath(x)):
            print(
                colorize(
                    "BAD",
                    "\n*** emerging by path is broken " "and may not always work!!!\n",
                )
            )
            break

    if emerge_config.action == "list-sets":
        writemsg_stdout(
            "".join("%s\n" % s for s in sorted(emerge_config.target_config.sets))
        )
        return os.EX_OK
    if emerge_config.action == "check-news":
        news_counts = count_unread_news(
            emerge_config.target_config.trees["porttree"].dbapi,
            emerge_config.target_config.trees["vartree"].dbapi,
        )
        if any(news_counts.values()):
            display_news_notifications(news_counts)
        elif "--quiet" not in emerge_config.opts:
            print("", colorize("GOOD", "*"), "No news items were found.")
        return os.EX_OK

    ensure_required_sets(emerge_config.trees)

    if (
        emerge_config.action is None
        and "--resume" in emerge_config.opts
        and emerge_config.args
    ):
        writemsg(
            "emerge: unexpected argument(s) for --resume: %s\n"
            % " ".join(emerge_config.args),
            noiselevel=-1,
        )
        return 1

    # only expand sets for actions taking package arguments
    oldargs = emerge_config.args[:]
    if emerge_config.action in (
        "clean",
        "config",
        "depclean",
        "info",
        "prune",
        "unmerge",
        "rage-clean",
        None,
    ):
        newargs, retval = expand_set_arguments(
            emerge_config.args, emerge_config.action, emerge_config.target_config
        )
        if retval != os.EX_OK:
            return retval

        # Need to handle empty sets specially, otherwise emerge will react
        # with the help message for empty argument lists
        if oldargs and not newargs:
            print("emerge: no targets left after set expansion")
            return 0

        emerge_config.args = newargs

    if "--tree" in emerge_config.opts and "--columns" in emerge_config.opts:
        print('emerge: can\'t specify both of "--tree" and "--columns".')
        return 1

    if "--emptytree" in emerge_config.opts and "--noreplace" in emerge_config.opts:
        writemsg_level(
            "emerge: can't specify both of " + '"--emptytree" and "--noreplace".\n',
            level=logging.ERROR,
            noiselevel=-1,
        )
        return 1

    if "--quiet" in emerge_config.opts:
        spinner.update = spinner.update_quiet
        portage.util.noiselimit = -1

    if "--fetch-all-uri" in emerge_config.opts:
        emerge_config.opts["--fetchonly"] = True

    if "--skipfirst" in emerge_config.opts and "--resume" not in emerge_config.opts:
        emerge_config.opts["--resume"] = True

    # Allow -p to remove --ask
    if "--pretend" in emerge_config.opts:
        emerge_config.opts.pop("--ask", None)

    # forbid --ask when not in a terminal
    # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
    if ("--ask" in emerge_config.opts) and (not sys.stdin.isatty()):
        portage.writemsg(
            '!!! "--ask" should only be used in a terminal. Exiting.\n', noiselevel=-1
        )
        return 1

    if emerge_config.target_config.settings.get("PORTAGE_DEBUG", "") == "1":
        spinner.update = spinner.update_quiet
        portage.util.noiselimit = 0
        if "python-trace" in emerge_config.target_config.settings.features:
            portage.debug.set_trace(True)

    if not "--quiet" in emerge_config.opts:
        if (
            "--nospinner" in emerge_config.opts
            or emerge_config.target_config.settings.get("TERM") == "dumb"
            or not sys.stdout.isatty()
        ):
            spinner.update = spinner.update_basic

    if "--debug" in emerge_config.opts:
        print("myaction", emerge_config.action)
        print("myopts", emerge_config.opts)

    if (
        not emerge_config.action
        and not emerge_config.args
        and "--resume" not in emerge_config.opts
    ):
        emerge_help()
        return 1

    pretend = "--pretend" in emerge_config.opts
    fetchonly = (
        "--fetchonly" in emerge_config.opts or "--fetch-all-uri" in emerge_config.opts
    )
    buildpkgonly = "--buildpkgonly" in emerge_config.opts

    # check if root user is the current user for the actions where emerge needs this
    if portage.data.secpass < 2:
        # We've already allowed "--version" and "--help" above.
        if "--pretend" not in emerge_config.opts and emerge_config.action not in (
            "search",
            "info",
        ):
            need_superuser = emerge_config.action in (
                "clean",
                "depclean",
                "deselect",
                "prune",
                "unmerge",
                "rage-clean",
            ) or not (
                fetchonly
                or (buildpkgonly and portage.data.secpass >= 1)
                or emerge_config.action in ("metadata", "regen", "sync")
            )
            if portage.data.secpass < 1 or need_superuser:
                if need_superuser:
                    access_desc = "superuser"
                else:
                    access_desc = "portage group"
                # Always show portage_group_warning() when only portage group
                # access is required but the user is not in the portage group.
                if "--ask" in emerge_config.opts:
                    writemsg_stdout(
                        "This action requires %s access...\n" % (access_desc,),
                        noiselevel=-1,
                    )
                    if portage.data.secpass < 1 and not need_superuser:
                        portage.data.portage_group_warning()
                    uq = UserQuery(emerge_config.opts)
                    if (
                        uq.query(
                            "Would you like to add --pretend to options?",
                            "--ask-enter-invalid" in emerge_config.opts,
                        )
                        == "No"
                    ):
                        return 128 + signal.SIGINT
                    emerge_config.opts["--pretend"] = True
                    emerge_config.opts.pop("--ask")
                else:
                    sys.stderr.write(("emerge: %s access is required\n") % access_desc)
                    if portage.data.secpass < 1 and not need_superuser:
                        portage.data.portage_group_warning()
                    return 1

    # Disable emergelog for everything except build or unmerge operations.
    # This helps minimize parallel emerge.log entries that can confuse log
    # parsers like genlop.
    disable_emergelog = False

    emerge_log_dir = emerge_config.target_config.settings.get("EMERGE_LOG_DIR")
    default_log_dir = os.path.join(
        os.sep, portage.const.EPREFIX.lstrip(os.sep), "var", "log"
    )
    for x in ("--pretend", "--fetchonly", "--fetch-all-uri"):
        if x in emerge_config.opts:
            if x == "--fetchonly" and "--quiet" in emerge_config.opts:
                # Log will be used to store fetch progress
                log_dir = emerge_log_dir if emerge_log_dir else default_log_dir
                disable_emergelog = not all(
                    os.access(logfile, os.W_OK)
                    for logfile in set(
                        first_existing(os.path.join(log_dir, logfile))
                        for logfile in ("emerge.log", "emerge-fetch.log")
                    )
                )
                break
            else:
                disable_emergelog = True
                break
    if disable_emergelog:
        pass
    elif emerge_config.action in ("search", "info"):
        disable_emergelog = True
    elif portage.data.secpass < 1:
        disable_emergelog = True

    import _emerge.emergelog

    _emerge.emergelog._disable = disable_emergelog

    if not disable_emergelog:
        if emerge_log_dir:
            try:
                # At least the parent needs to exist for the lock file.
                portage.util.ensure_dirs(emerge_log_dir)
            except portage.exception.PortageException as e:
                writemsg_level(
                    "!!! Error creating directory for "
                    + "EMERGE_LOG_DIR='%s':\n!!! %s\n" % (emerge_log_dir, e),
                    noiselevel=-1,
                    level=logging.ERROR,
                )
                portage.util.ensure_dirs(_emerge.emergelog._emerge_log_dir)
            else:
                _emerge.emergelog._emerge_log_dir = emerge_log_dir
        else:
            _emerge.emergelog._emerge_log_dir = default_log_dir
            portage.util.ensure_dirs(_emerge.emergelog._emerge_log_dir)

    if not "--pretend" in emerge_config.opts:
        time_fmt = "%b %d, %Y %H:%M:%S"
        time_str = time.strftime(time_fmt, time.localtime(time.time()))
        # Avoid potential UnicodeDecodeError in Python 2, since strftime
        # returns bytes in Python 2, and %b may contain non-ascii chars.
        time_str = _unicode_decode(
            time_str, encoding=_encodings["content"], errors="replace"
        )
        emergelog(xterm_titles, "Started emerge on: %s" % time_str)
        myelogstr = ""
        if emerge_config.opts:
            opt_list = []
            for opt, arg in emerge_config.opts.items():
                if arg is True:
                    opt_list.append(opt)
                elif isinstance(arg, list):
                    # arguments like --exclude that use 'append' action
                    for x in arg:
                        opt_list.append("%s=%s" % (opt, x))
                else:
                    opt_list.append("%s=%s" % (opt, arg))
            myelogstr = " ".join(opt_list)
        if emerge_config.action:
            myelogstr += " --" + emerge_config.action
        if oldargs:
            myelogstr += " " + " ".join(oldargs)
        emergelog(xterm_titles, " *** emerge " + myelogstr)

    oldargs = None

    def emergeexitsig(signum, frame):
        signal.signal(signal.SIGTERM, signal.SIG_IGN)
        portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal": signum})
        sys.exit(128 + signum)

    signal.signal(signal.SIGTERM, emergeexitsig)

    def emergeexit():
        """This gets out final log message in before we quit."""
        if "--pretend" not in emerge_config.opts:
            emergelog(xterm_titles, " *** terminating.")
        if xterm_titles:
            xtermTitleReset()

    portage.atexit_register(emergeexit)

    if emerge_config.action in ("config", "metadata", "regen", "sync"):
        if "--pretend" in emerge_config.opts:
            sys.stderr.write(
                ("emerge: The '%s' action does " + "not support '--pretend'.\n")
                % emerge_config.action
            )
            return 1

    if "sync" == emerge_config.action:
        return action_sync(emerge_config)
    if "metadata" == emerge_config.action:
        action_metadata(
            emerge_config.target_config.settings,
            emerge_config.target_config.trees["porttree"].dbapi,
            emerge_config.opts,
        )
    elif emerge_config.action == "regen":
        validate_ebuild_environment(emerge_config.trees)
        return action_regen(
            emerge_config.target_config.settings,
            emerge_config.target_config.trees["porttree"].dbapi,
            emerge_config.opts.get("--jobs"),
            emerge_config.opts.get("--load-average"),
        )
    # HELP action
    elif "config" == emerge_config.action:
        validate_ebuild_environment(emerge_config.trees)
        return action_config(
            emerge_config.target_config.settings,
            emerge_config.trees,
            emerge_config.opts,
            emerge_config.args,
        )

    # SEARCH action
    elif "search" == emerge_config.action:
        validate_ebuild_environment(emerge_config.trees)
        action_search(
            emerge_config.target_config, emerge_config.opts, emerge_config.args, spinner
        )

    elif emerge_config.action in (
        "clean",
        "depclean",
        "deselect",
        "prune",
        "unmerge",
        "rage-clean",
    ):
        validate_ebuild_environment(emerge_config.trees)
        rval = action_uninstall(
            emerge_config.target_config.settings,
            emerge_config.trees,
            emerge_config.target_config.mtimedb["ldpath"],
            emerge_config.opts,
            emerge_config.action,
            emerge_config.args,
            spinner,
        )
        if not (
            emerge_config.action == "deselect" or buildpkgonly or fetchonly or pretend
        ):
            post_emerge(
                emerge_config.action,
                emerge_config.opts,
                emerge_config.args,
                emerge_config.target_config.root,
                emerge_config.trees,
                emerge_config.target_config.mtimedb,
                rval,
            )
        return rval

    elif emerge_config.action == "info":

        # Ensure atoms are valid before calling unmerge().
        vardb = emerge_config.target_config.trees["vartree"].dbapi
        portdb = emerge_config.target_config.trees["porttree"].dbapi
        bindb = emerge_config.target_config.trees["bintree"].dbapi
        valid_atoms = []
        for x in emerge_config.args:
            if is_valid_package_atom(x, allow_repo=True):
                try:
                    # look at the installed files first, if there is no match
                    # look at the ebuilds, since EAPI 4 allows running pkg_info
                    # on non-installed packages
                    valid_atom = dep_expand(x, mydb=vardb)
                    if valid_atom.cp.split("/")[0] == "null":
                        valid_atom = dep_expand(x, mydb=portdb)

                    if (
                        valid_atom.cp.split("/")[0] == "null"
                        and "--usepkg" in emerge_config.opts
                    ):
                        valid_atom = dep_expand(x, mydb=bindb)

                    valid_atoms.append(valid_atom)

                except portage.exception.AmbiguousPackageName as e:
                    msg = (
                        'The short ebuild name "'
                        + x
                        + '" is ambiguous.  Please specify '
                        + "one of the following "
                        + "fully-qualified ebuild names instead:"
                    )
                    for line in textwrap.wrap(msg, 70):
                        writemsg_level(
                            "!!! %s\n" % (line,), level=logging.ERROR, noiselevel=-1
                        )
                    for i in e.args[0]:
                        writemsg_level(
                            "    %s\n" % colorize("INFORM", i),
                            level=logging.ERROR,
                            noiselevel=-1,
                        )
                    writemsg_level("\n", level=logging.ERROR, noiselevel=-1)
                    return 1
                continue
            msg = []
            msg.append("'%s' is not a valid package atom." % (x,))
            msg.append("Please check ebuild(5) for full details.")
            writemsg_level(
                "".join("!!! %s\n" % line for line in msg),
                level=logging.ERROR,
                noiselevel=-1,
            )
            return 1

        return action_info(
            emerge_config.target_config.settings,
            emerge_config.trees,
            emerge_config.opts,
            valid_atoms,
        )

    # "update", "system", or just process files:
    else:
        validate_ebuild_environment(emerge_config.trees)

        for x in emerge_config.args:
            if x.startswith(SETPREFIX) or is_valid_package_atom(x, allow_repo=True):
                continue
            if x[:1] == os.sep:
                continue
            try:
                os.lstat(x)
                continue
            except OSError:
                pass
            msg = []
            msg.append("'%s' is not a valid package atom." % (x,))
            msg.append("Please check ebuild(5) for full details.")
            writemsg_level(
                "".join("!!! %s\n" % line for line in msg),
                level=logging.ERROR,
                noiselevel=-1,
            )
            return 1

        # GLEP 42 says to display news *after* an emerge --pretend
        if "--pretend" not in emerge_config.opts:
            uq = UserQuery(emerge_config.opts)
            if (
                display_news_notification(
                    emerge_config.target_config, emerge_config.opts
                )
                and "--ask" in emerge_config.opts
                and "--read-news" in emerge_config.opts
                and uq.query(
                    "Would you like to read the news items while "
                    "calculating dependencies?",
                    "--ask-enter-invalid" in emerge_config.opts,
                )
                == "Yes"
            ):
                try:
                    subprocess.call(["eselect", "news", "read"])
                # If eselect is not installed, Python <3.3 will throw an
                # OSError. >=3.3 will throw a FileNotFoundError, which is a
                # subclass of OSError.
                except OSError:
                    writemsg(
                        "Please install eselect to use this feature.\n", noiselevel=-1
                    )
        retval = action_build(emerge_config, spinner=spinner)
        post_emerge(
            emerge_config.action,
            emerge_config.opts,
            emerge_config.args,
            emerge_config.target_config.root,
            emerge_config.trees,
            emerge_config.target_config.mtimedb,
            retval,
        )

        return retval
