Blame dnf/cli/option_parser.py

Packit Service 21c75c
# optparse.py
Packit Service 21c75c
# CLI options parser.
Packit Service 21c75c
#
Packit Service 21c75c
# Copyright (C) 2014-2016 Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 21c75c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 21c75c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 21c75c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 21c75c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 21c75c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 21c75c
# Public License for more details.  You should have received a copy of the
Packit Service 21c75c
# GNU General Public License along with this program; if not, write to the
Packit Service 21c75c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 21c75c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 21c75c
# source code or documentation are not subject to the GNU General Public
Packit Service 21c75c
# License and may only be used or replicated with the express permission of
Packit Service 21c75c
# Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
from dnf.i18n import _
Packit Service 21c75c
from dnf.util import _parse_specs
Packit Service 21c75c
Packit Service 21c75c
import argparse
Packit Service 21c75c
import dnf.exceptions
Packit Service 21c75c
import dnf.util
Packit Service 21c75c
import dnf.rpm
Packit Service 21c75c
import dnf.yum.misc
Packit Service 21c75c
import logging
Packit Service 21c75c
import os.path
Packit Service 21c75c
import re
Packit Service 21c75c
import sys
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger("dnf")
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class MultilineHelpFormatter(argparse.HelpFormatter):
Packit Service 21c75c
    def _split_lines(self, text, width):
Packit Service 21c75c
        if '\n' in text:
Packit Service 21c75c
            return text.splitlines()
Packit Service 21c75c
        return super(MultilineHelpFormatter, self)._split_lines(text, width)
Packit Service 21c75c
Packit Service 21c75c
class OptionParser(argparse.ArgumentParser):
Packit Service 21c75c
    """ArgumentParser like class to do things the "yum way"."""
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, reset_usage=True):
Packit Service 21c75c
        super(OptionParser, self).__init__(add_help=False,
Packit Service 21c75c
                                           formatter_class=MultilineHelpFormatter)
Packit Service 21c75c
        self.command_positional_parser = None
Packit Service 21c75c
        self.command_group = None
Packit Service 21c75c
        self._add_general_options()
Packit Service 21c75c
        if reset_usage:
Packit Service 21c75c
            self._cmd_usage = {}      # names, summary for dnf commands, to build usage
Packit Service 21c75c
            self._cmd_groups = set()  # cmd groups added (main, plugin)
Packit Service 21c75c
Packit Service 21c75c
    def error(self, msg):
Packit Service 21c75c
        """Output an error message, and exit the program.
Packit Service 21c75c
           This method overrides standard argparser's error
Packit Service 21c75c
           so that error output goes to the logger.
Packit Service 21c75c
Packit Service 21c75c
        :param msg: the error message to output
Packit Service 21c75c
        """
Packit Service 21c75c
        self.print_usage()
Packit Service 21c75c
        logger.critical(_("Command line error: %s"), msg)
Packit Service 21c75c
        sys.exit(1)
Packit Service 21c75c
Packit Service 21c75c
    class _RepoCallback(argparse.Action):
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            operation = 'disable' if opt_str == '--disablerepo' else 'enable'
Packit Service 21c75c
            l = getattr(namespace, self.dest)
Packit Service 21c75c
            l.extend((x, operation) for x in re.split(r'\s*[,\s]\s*', values))
Packit Service 21c75c
Packit Service 21c75c
    class _RepoCallbackEnable(argparse.Action):
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            namespace.repos_ed.append((values[0], 'enable'))
Packit Service 21c75c
            setattr(namespace, 'reponame', values)
Packit Service 21c75c
Packit Service 21c75c
    class _SplitCallback(argparse._AppendAction):
Packit Service 21c75c
        """ Split all strings in seq, at "," and whitespace.
Packit Service 21c75c
        Returns a new list. """
Packit Service 21c75c
        SPLITTER = r'\s*[,\s]\s*'
Packit Service 21c75c
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            first = True
Packit Service 21c75c
            for val in re.split(self.SPLITTER, values):
Packit Service 21c75c
                if first or val:
Packit Service 21c75c
                    # Empty values are sometimes used to clear existing content of the option.
Packit Service 21c75c
                    # Only the first value in the parsed string can be empty. Other empty values
Packit Service 21c75c
                    # are ignored.
Packit Service 21c75c
                    super(OptionParser._SplitCallback,
Packit Service 21c75c
                          self).__call__(parser, namespace, val, opt_str)
Packit Service 21c75c
                first = False
Packit Service 21c75c
Packit Service 21c75c
    class _SplitExtendDictCallback(argparse.Action):
Packit Service 21c75c
        """ Split string at "," or whitespace to (key, value).
Packit Service 21c75c
        Extends dict with {key: value}."""
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            try:
Packit Service 21c75c
                key, val = values.split(',')
Packit Service 21c75c
                if not key or not val:
Packit Service 21c75c
                    raise ValueError
Packit Service 21c75c
            except ValueError:
Packit Service 21c75c
                msg = _('bad format: %s') % values
Packit Service 21c75c
                raise argparse.ArgumentError(self, msg)
Packit Service 21c75c
            dct = getattr(namespace, self.dest)
Packit Service 21c75c
            dct[key] = val
Packit Service 21c75c
Packit Service 21c75c
    class _SetoptsCallback(argparse.Action):
Packit Service 21c75c
        """ Parse setopts arguments and put them into main_<setopts>
Packit Service 21c75c
            and repo_<setopts>."""
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            vals = values.split('=')
Packit Service 21c75c
            if len(vals) > 2:
Packit Service 21c75c
                logger.warning(_("Setopt argument has multiple values: %s"), values)
Packit Service 21c75c
                return
Packit Service 21c75c
            if len(vals) < 2:
Packit Service 21c75c
                logger.warning(_("Setopt argument has no value: %s"), values)
Packit Service 21c75c
                return
Packit Service 21c75c
            k, v = vals
Packit Service 21c75c
            period = k.rfind('.')
Packit Service 21c75c
            if period != -1:
Packit Service 21c75c
                repo = k[:period]
Packit Service 21c75c
                k = k[period+1:]
Packit Service 21c75c
                if hasattr(namespace, 'repo_setopts'):
Packit Service 21c75c
                    repoopts = namespace.repo_setopts
Packit Service 21c75c
                else:
Packit Service 21c75c
                    repoopts = {}
Packit Service 21c75c
                repoopts.setdefault(repo, {}).setdefault(k, []).append(v)
Packit Service 21c75c
                setattr(namespace, 'repo_' + self.dest, repoopts)
Packit Service 21c75c
            else:
Packit Service 21c75c
                if hasattr(namespace, 'main_setopts'):
Packit Service 21c75c
                    mainopts = namespace.main_setopts
Packit Service 21c75c
                else:
Packit Service 21c75c
                    mainopts = {}
Packit Service 21c75c
                mainopts.setdefault(k, []).append(v)
Packit Service 21c75c
                setattr(namespace, 'main_' + self.dest, mainopts)
Packit Service 21c75c
Packit Service 21c75c
    class ParseSpecGroupFileCallback(argparse.Action):
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            _parse_specs(namespace, values)
Packit Service 21c75c
Packit Service 21c75c
    class PkgNarrowCallback(argparse.Action):
Packit Service 21c75c
        def __init__(self, *args, **kwargs):
Packit Service 21c75c
            self.pkgnarrow = {}
Packit Service 21c75c
            try:
Packit Service 21c75c
                for k in ['choices', 'default']:
Packit Service 21c75c
                    self.pkgnarrow[k] = kwargs[k]
Packit Service 21c75c
                    del kwargs[k]
Packit Service 21c75c
            except KeyError as e:
Packit Service 21c75c
                raise TypeError("%s() missing mandatory argument %s"
Packit Service 21c75c
                                % (self.__class__.__name__, e))
Packit Service 21c75c
            kwargs['default'] = []
Packit Service 21c75c
            super(OptionParser.PkgNarrowCallback, self).__init__(*args, **kwargs)
Packit Service 21c75c
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            dest_action = self.dest + '_action'
Packit Service 21c75c
            if not values or values[0] not in self.pkgnarrow['choices']:
Packit Service 21c75c
                narrow = self.pkgnarrow['default']
Packit Service 21c75c
            else:
Packit Service 21c75c
                narrow = values.pop(0)
Packit Service 21c75c
            setattr(namespace, dest_action, narrow)
Packit Service 21c75c
            setattr(namespace, self.dest, values)
Packit Service 21c75c
Packit Service 21c75c
    class ForceArchAction(argparse.Action):
Packit Service 21c75c
        def __call__(self, parser, namespace, values, opt_str):
Packit Service 21c75c
            namespace.ignorearch = True
Packit Service 21c75c
            namespace.arch = values
Packit Service 21c75c
Packit Service 21c75c
    def _add_general_options(self):
Packit Service 21c75c
        """ Standard options known to all dnf subcommands. """
Packit Service 21c75c
        # All defaults need to be a None, so we can always tell whether the user
Packit Service 21c75c
        # has set something or whether we are getting a default.
Packit Service 21c75c
        general_grp = self.add_argument_group(_('General {prog} options'.format(
Packit Service 21c75c
            prog=dnf.util.MAIN_PROG_UPPER)))
Packit Service 21c75c
        general_grp.add_argument("-c", "--config", dest="config_file_path",
Packit Service 21c75c
                                 default=None, metavar='[config file]',
Packit Service 21c75c
                                 help=_("config file location"))
Packit Service 21c75c
        general_grp.add_argument("-q", "--quiet", dest="quiet",
Packit Service 21c75c
                                 action="store_true", default=None,
Packit Service 21c75c
                                 help=_("quiet operation"))
Packit Service 21c75c
        general_grp.add_argument("-v", "--verbose", action="store_true",
Packit Service 21c75c
                                 default=None, help=_("verbose operation"))
Packit Service 21c75c
        general_grp.add_argument("--version", action="store_true", default=None,
Packit Service 21c75c
                                 help=_("show {prog} version and exit").format(
Packit Service 21c75c
                                     prog=dnf.util.MAIN_PROG_UPPER))
Packit Service 21c75c
        general_grp.add_argument("--installroot", help=_("set install root"),
Packit Service 21c75c
                                 metavar='[path]')
Packit Service 21c75c
        general_grp.add_argument("--nodocs", action="store_const", const=['nodocs'], dest='tsflags',
Packit Service 21c75c
                                 help=_("do not install documentations"))
Packit Service 21c75c
        general_grp.add_argument("--noplugins", action="store_false",
Packit Service 21c75c
                                 default=None, dest='plugins',
Packit Service 21c75c
                                 help=_("disable all plugins"))
Packit Service 21c75c
        general_grp.add_argument("--enableplugin", dest="enableplugin",
Packit Service 21c75c
                                 default=[], action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("enable plugins by name"),
Packit Service 21c75c
                                 metavar='[plugin]')
Packit Service 21c75c
        general_grp.add_argument("--disableplugin", dest="disableplugin",
Packit Service 21c75c
                                 default=[], action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("disable plugins by name"),
Packit Service 21c75c
                                 metavar='[plugin]')
Packit Service 21c75c
        general_grp.add_argument("--releasever", default=None,
Packit Service 21c75c
                                 help=_("override the value of $releasever"
Packit Service 21c75c
                                        " in config and repo files"))
Packit Service 21c75c
        general_grp.add_argument("--setopt", dest="setopts", default=[],
Packit Service 21c75c
                                 action=self._SetoptsCallback,
Packit Service 21c75c
                                 help=_("set arbitrary config and repo options"))
Packit Service 21c75c
        general_grp.add_argument("--skip-broken", dest="skip_broken", action="store_true",
Packit Service 21c75c
                                 default=None,
Packit Service 21c75c
                                 help=_("resolve depsolve problems by skipping packages"))
Packit Service 21c75c
        general_grp.add_argument('-h', '--help', '--help-cmd',
Packit Service 21c75c
                                 action="store_true", dest='help',
Packit Service 21c75c
                                 help=_("show command help"))
Packit Service 21c75c
Packit Service 21c75c
        general_grp.add_argument('--allowerasing', action='store_true',
Packit Service 21c75c
                                 default=None,
Packit Service 21c75c
                                 help=_('allow erasing of installed packages to '
Packit Service 21c75c
                                        'resolve dependencies'))
Packit Service 21c75c
        best_group = general_grp.add_mutually_exclusive_group()
Packit Service 21c75c
        best_group.add_argument("-b", "--best", action="store_true", dest='best', default=None,
Packit Service 21c75c
                                help=_("try the best available package versions in transactions."))
Packit Service 21c75c
        best_group.add_argument("--nobest", action="store_false", dest='best',
Packit Service 21c75c
                                help=_("do not limit the transaction to the best candidate"))
Packit Service 21c75c
        general_grp.add_argument("-C", "--cacheonly", dest="cacheonly",
Packit Service 21c75c
                                 action="store_true", default=None,
Packit Service 21c75c
                                 help=_("run entirely from system cache, "
Packit Service 21c75c
                                        "don't update cache"))
Packit Service 21c75c
        general_grp.add_argument("-R", "--randomwait", dest="sleeptime", type=int,
Packit Service 21c75c
                                 default=None, metavar='[minutes]',
Packit Service 21c75c
                                 help=_("maximum command wait time"))
Packit Service 21c75c
        general_grp.add_argument("-d", "--debuglevel", dest="debuglevel",
Packit Service 21c75c
                                 metavar='[debug level]', default=None,
Packit Service 21c75c
                                 help=_("debugging output level"), type=int)
Packit Service 21c75c
        general_grp.add_argument("--debugsolver",
Packit Service 21c75c
                                 action="store_true", default=None,
Packit Service 21c75c
                                 help=_("dumps detailed solving results into"
Packit Service 21c75c
                                        " files"))
Packit Service 21c75c
        general_grp.add_argument("--showduplicates", dest="showdupesfromrepos",
Packit Service 21c75c
                                 action="store_true", default=None,
Packit Service 21c75c
                                 help=_("show duplicates, in repos, "
Packit Service 21c75c
                                        "in list/search commands"))
Packit Service 21c75c
        general_grp.add_argument("-e", "--errorlevel", default=None, type=int,
Packit Service 21c75c
                                 help=_("error output level"))
Packit Service 21c75c
        general_grp.add_argument("--obsoletes", default=None, dest="obsoletes",
Packit Service 21c75c
                                 action="store_true",
Packit Service 21c75c
                                 help=_("enables {prog}'s obsoletes processing logic "
Packit Service 21c75c
                                        "for upgrade or display capabilities that "
Packit Service 21c75c
                                        "the package obsoletes for info, list and "
Packit Service 21c75c
                                        "repoquery").format(prog=dnf.util.MAIN_PROG))
Packit Service 21c75c
        general_grp.add_argument("--rpmverbosity", default=None,
Packit Service 21c75c
                                 help=_("debugging output level for rpm"),
Packit Service 21c75c
                                 metavar='[debug level name]')
Packit Service 21c75c
        general_grp.add_argument("-y", "--assumeyes", action="store_true",
Packit Service 21c75c
                                 default=None, help=_("automatically answer yes"
Packit Service 21c75c
                                                      " for all questions"))
Packit Service 21c75c
        general_grp.add_argument("--assumeno", action="store_true",
Packit Service 21c75c
                                 default=None, help=_("automatically answer no"
Packit Service 21c75c
                                                      " for all questions"))
Packit Service 21c75c
        general_grp.add_argument("--enablerepo", action=self._RepoCallback,
Packit Service 21c75c
                                 dest='repos_ed', default=[], metavar='[repo]',
Packit Service 21c75c
                                 help=_("Enable additional repositories. List option. "
Packit Service 21c75c
                                        "Supports globs, can be specified multiple times."))
Packit Service 21c75c
        repo_group = general_grp.add_mutually_exclusive_group()
Packit Service 21c75c
        repo_group.add_argument("--disablerepo", action=self._RepoCallback,
Packit Service 21c75c
                                dest='repos_ed', default=[], metavar='[repo]',
Packit Service 21c75c
                                help=_("Disable repositories. List option. "
Packit Service 21c75c
                                       "Supports globs, can be specified multiple times."))
Packit Service 21c75c
        repo_group.add_argument('--repo', '--repoid', metavar='[repo]', dest='repo',
Packit Service 21c75c
                                action=self._SplitCallback, default=[],
Packit Service 21c75c
                                help=_('enable just specific repositories by an id or a glob, '
Packit Service 21c75c
                                       'can be specified multiple times'))
Packit Service 21c75c
        enable_group = general_grp.add_mutually_exclusive_group()
Packit Service 21c75c
        enable_group.add_argument("--enable", default=False,
Packit Service 21c75c
                                  dest="set_enabled", action="store_true",
Packit Service 21c75c
                                  help=_("enable repos with config-manager "
Packit Service 21c75c
                                         "command (automatically saves)"))
Packit Service 21c75c
        enable_group.add_argument("--disable", default=False,
Packit Service 21c75c
                                  dest="set_disabled", action="store_true",
Packit Service 21c75c
                                  help=_("disable repos with config-manager "
Packit Service 21c75c
                                         "command (automatically saves)"))
Packit Service 21c75c
        general_grp.add_argument("-x", "--exclude", "--excludepkgs", default=[],
Packit Service 21c75c
                                 dest='excludepkgs', action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("exclude packages by name or glob"),
Packit Service 21c75c
                                 metavar='[package]')
Packit Service 21c75c
        general_grp.add_argument("--disableexcludes", "--disableexcludepkgs",
Packit Service 21c75c
                                 default=[], dest="disable_excludes",
Packit Service 21c75c
                                 action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("disable excludepkgs"),
Packit Service 21c75c
                                 metavar='[repo]')
Packit Service 21c75c
        general_grp.add_argument("--repofrompath", default={},
Packit Service 21c75c
                                 action=self._SplitExtendDictCallback,
Packit Service 21c75c
                                 metavar='[repo,path]',
Packit Service 21c75c
                                 help=_("label and path to an additional repository to use (same "
Packit Service 21c75c
                                        "path as in a baseurl), can be specified multiple times."))
Packit Service 21c75c
        general_grp.add_argument("--noautoremove", action="store_false",
Packit Service 21c75c
                                 default=None, dest='clean_requirements_on_remove',
Packit Service 21c75c
                                 help=_("disable removal of dependencies that are no longer used"))
Packit Service 21c75c
        general_grp.add_argument("--nogpgcheck", action="store_false",
Packit Service 21c75c
                                 default=None, dest='gpgcheck',
Packit Service 21c75c
                                 help=_("disable gpg signature checking (if RPM policy allows)"))
Packit Service 21c75c
        general_grp.add_argument("--color", dest="color", default=None,
Packit Service 21c75c
                                 help=_("control whether color is used"))
Packit Service 21c75c
        general_grp.add_argument("--refresh", dest="freshest_metadata",
Packit Service 21c75c
                                 action="store_true",
Packit Service 21c75c
                                 help=_("set metadata as expired before running"
Packit Service 21c75c
                                        " the command"))
Packit Service 21c75c
        general_grp.add_argument("-4", dest="ip_resolve", default=None,
Packit Service 21c75c
                                 help=_("resolve to IPv4 addresses only"),
Packit Service 21c75c
                                 action="store_const", const='ipv4')
Packit Service 21c75c
        general_grp.add_argument("-6", dest="ip_resolve", default=None,
Packit Service 21c75c
                                 help=_("resolve to IPv6 addresses only"),
Packit Service 21c75c
                                 action="store_const", const='ipv6')
Packit Service 21c75c
        general_grp.add_argument("--destdir", "--downloaddir", dest="destdir", default=None,
Packit Service 21c75c
                                 help=_("set directory to copy packages to"))
Packit Service 21c75c
        general_grp.add_argument("--downloadonly", dest="downloadonly",
Packit Service 21c75c
                                 action="store_true", default=False,
Packit Service 21c75c
                                 help=_("only download packages"))
Packit Service 21c75c
        general_grp.add_argument("--comment", dest="comment", default=None,
Packit Service 21c75c
                                 help=_("add a comment to transaction"))
Packit Service 21c75c
        # Updateinfo options...
Packit Service 21c75c
        general_grp.add_argument("--bugfix", action="store_true",
Packit Service 21c75c
                                 help=_("Include bugfix relevant packages, "
Packit Service 21c75c
                                        "in updates"))
Packit Service 21c75c
        general_grp.add_argument("--enhancement", action="store_true",
Packit Service 21c75c
                                 help=_("Include enhancement relevant packages,"
Packit Service 21c75c
                                        " in updates"))
Packit Service 21c75c
        general_grp.add_argument("--newpackage", action="store_true",
Packit Service 21c75c
                                 help=_("Include newpackage relevant packages,"
Packit Service 21c75c
                                        " in updates"))
Packit Service 21c75c
        general_grp.add_argument("--security", action="store_true",
Packit Service 21c75c
                                 help=_("Include security relevant packages, "
Packit Service 21c75c
                                        "in updates"))
Packit Service 21c75c
        general_grp.add_argument("--advisory", "--advisories", dest="advisory",
Packit Service 21c75c
                                 default=[], action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("Include packages needed to fix the "
Packit Service 21c75c
                                        "given advisory, in updates"))
Packit Service 21c75c
        general_grp.add_argument("--bz", "--bzs", default=[], dest="bugzilla",
Packit Service 21c75c
                                 action=self._SplitCallback, help=_(
Packit Service 21c75c
                "Include packages needed to fix the given BZ, in updates"))
Packit Service 21c75c
        general_grp.add_argument("--cve", "--cves", default=[], dest="cves",
Packit Service 21c75c
                                 action=self._SplitCallback,
Packit Service 21c75c
                                 help=_("Include packages needed to fix the given CVE, in updates"))
Packit Service 21c75c
        general_grp.add_argument(
Packit Service 21c75c
            "--sec-severity", "--secseverity",
Packit Service 21c75c
            choices=['Critical', 'Important', 'Moderate', 'Low'], default=[],
Packit Service 21c75c
            dest="severity", action=self._SplitCallback, help=_(
Packit Service 21c75c
                "Include security relevant packages matching the severity, "
Packit Service 21c75c
                "in updates"))
Packit Service 21c75c
        general_grp.add_argument("--forcearch", metavar="ARCH",
Packit Service 21c75c
                                 dest=argparse.SUPPRESS,
Packit Service 21c75c
                                 action=self.ForceArchAction,
Packit Service 21c75c
                                 choices=sorted(dnf.rpm._BASEARCH_MAP.keys()),
Packit Service 21c75c
                                 help=_("Force the use of an architecture"))
Packit Service 21c75c
        general_grp.add_argument('command', nargs='?', help=argparse.SUPPRESS)
Packit Service 21c75c
Packit Service 21c75c
    def _add_cmd_usage(self, cmd, group):
Packit Service 21c75c
        """ store usage info about a single dnf command."""
Packit Service 21c75c
        summary = dnf.i18n.ucd(cmd.summary)
Packit Service 21c75c
        name = dnf.i18n.ucd(cmd.aliases[0])
Packit Service 21c75c
        if not name in self._cmd_usage:
Packit Service 21c75c
            self._cmd_usage[name] = (group, summary)
Packit Service 21c75c
            self._cmd_groups.add(group)
Packit Service 21c75c
Packit Service 21c75c
    def add_commands(self, cli_cmds, group):
Packit Service 21c75c
        """ store name & summary for dnf commands
Packit Service 21c75c
Packit Service 21c75c
        The stored information is used build usage information
Packit Service 21c75c
        grouped by build-in & plugin commands.
Packit Service 21c75c
        """
Packit Service 21c75c
        for cmd in set(cli_cmds.values()):
Packit Service 21c75c
            self._add_cmd_usage(cmd, group)
Packit Service 21c75c
Packit Service 21c75c
    def get_usage(self):
Packit Service 21c75c
        """ get the usage information to show the user. """
Packit Service 21c75c
        desc = {'main': _('List of Main Commands:'),
Packit Service 21c75c
                'plugin': _('List of Plugin Commands:')}
Packit Service 21c75c
        usage = '%s [options] COMMAND\n' % dnf.util.MAIN_PROG
Packit Service 21c75c
        for grp in ['main', 'plugin']:
Packit Service 21c75c
            if not grp in self._cmd_groups:
Packit Service 21c75c
                # dont add plugin usage, if we dont have plugins
Packit Service 21c75c
                continue
Packit Service 21c75c
            usage += "\n%s\n\n" % desc[grp]
Packit Service 21c75c
            for name in sorted(self._cmd_usage.keys()):
Packit Service 21c75c
                group, summary = self._cmd_usage[name]
Packit Service 21c75c
                if group == grp:
Packit Service 21c75c
                    usage += "%-25s %s\n" % (name, summary)
Packit Service 21c75c
        return usage
Packit Service 21c75c
Packit Service 21c75c
    def _add_command_options(self, command):
Packit Service 21c75c
        self.prog = "%s %s" % (dnf.util.MAIN_PROG, command._basecmd)
Packit Service 21c75c
        self.description = command.summary
Packit Service 21c75c
        self.command_positional_parser = argparse.ArgumentParser(self.prog, add_help=False)
Packit Service 21c75c
        self.command_positional_parser.print_usage = self.print_usage
Packit Service 21c75c
        self.command_positional_parser._positionals.title = None
Packit Service 21c75c
        self.command_group = self.add_argument_group(
Packit Service 21c75c
            '{} command-specific options'.format(command._basecmd.capitalize()))
Packit Service 21c75c
        self.command_group.add_argument = self.cmd_add_argument
Packit Service 21c75c
        self.command_group._command = command._basecmd
Packit Service 21c75c
        command.set_argparser(self.command_group)
Packit Service 21c75c
Packit Service 21c75c
    def cmd_add_argument(self, *args, **kwargs):
Packit Service 21c75c
        if all([(arg[0] in self.prefix_chars) for arg in args]):
Packit Service 21c75c
            return type(self.command_group).add_argument(self.command_group, *args, **kwargs)
Packit Service 21c75c
        else:
Packit Service 21c75c
            return self.command_positional_parser.add_argument(*args, **kwargs)
Packit Service 21c75c
Packit Service 21c75c
    def _check_encoding(self, args):
Packit Service 21c75c
        for arg in args:
Packit Service 21c75c
            try:
Packit Service 21c75c
                arg.encode('utf-8')
Packit Service 21c75c
            except UnicodeEncodeError as e:
Packit Service 21c75c
                raise dnf.exceptions.ConfigError(
Packit Service 21c75c
                    _("Cannot encode argument '%s': %s") % (arg, str(e)))
Packit Service 21c75c
Packit Service 21c75c
    def parse_main_args(self, args):
Packit Service 21c75c
        self._check_encoding(args)
Packit Service 21c75c
        namespace, _unused_args = self.parse_known_args(args)
Packit Service 21c75c
        return namespace
Packit Service 21c75c
Packit Service 21c75c
    def parse_command_args(self, command, args):
Packit Service 21c75c
        self._add_command_options(command)
Packit Service 21c75c
        namespace, unused_args = self.parse_known_args(args)
Packit Service 21c75c
        namespace = self.command_positional_parser.parse_args(unused_args, namespace)
Packit Service 21c75c
        command.opts = namespace
Packit Service 21c75c
        return command.opts
Packit Service 21c75c
Packit Service 21c75c
    def print_usage(self, file_=None):
Packit Service 21c75c
        if self.command_positional_parser:
Packit Service 21c75c
            self._actions += self.command_positional_parser._actions
Packit Service 21c75c
        super(OptionParser, self).print_usage(file_)
Packit Service 21c75c
Packit Service 21c75c
    def print_help(self, command=None):
Packit Service 21c75c
        # pylint: disable=W0212
Packit Service 21c75c
        if command:
Packit Service 21c75c
            if not self.command_group or self.command_group._command != command._basecmd:
Packit Service 21c75c
                self._add_command_options(command)
Packit Service 21c75c
            self._actions += self.command_positional_parser._actions
Packit Service 21c75c
            self._action_groups.append(self.command_positional_parser._positionals)
Packit Service 21c75c
        else:
Packit Service 21c75c
            self.usage = self.get_usage()
Packit Service 21c75c
        super(OptionParser, self).print_help()