8000 cli: Handle missing commands gracefully by vinzenz · Pull Request #785 · oamg/leapp · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

cli: Handle missing commands gracefully #785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions leapp/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

import os
import pkgutil
import socket
import sys
import textwrap

from leapp import VERSION
from leapp.cli import commands
from leapp.exceptions import UnknownCommandError
from leapp.utils.clicmd import command


Expand Down Expand Up @@ -40,4 +41,16 @@ def main():

os.environ['LEAPP_HOSTNAME'] = socket.getfqdn()
_load_commands(cli.command)
cli.command.execute('leapp version {}'.format(VERSION))
try:
cli.command.execute('leapp version {}'.format(VERSION))
except UnknownCommandError as e:
bad_cmd = (
"Command \"{CMD}\" is unknown.\nMost likely there is a typo in the command or particular "
"leapp repositories that provide this command are not present on the system.\n"
"You can try to install the missing content e.g. by the following 8000 command: "
"`dnf install 'leapp-command({CMD})'`")
if e.requested.startswith('-'):
# A quick ack not to confuse users with install a leapp-command(--some-wrong-argument) suggestion
bad_cmd = "No such argument {CMD}"
print(bad_cmd.format(CMD=e.requested))
sys.exit(1)
6 changes: 6 additions & 0 deletions leapp/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ class CommandDefinitionError(LeappError):
pass


class UnknownCommandError(LeappError):
def __init__(self, command):
super().__init__('Unknown command: {}'.format(command))
self.requested = command


class LeappRuntimeError(LeappError):
pass

Expand Down
17 changes: 11 additions & 6 deletions leapp/utils/clicmd.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import functools
import os
import sys

from argparse import ArgumentParser, _SubParsersAction, RawDescriptionHelpFormatter
from argparse import (ArgumentParser, RawDescriptionHelpFormatter,
_SubParsersAction)

import six

from leapp.exceptions import CommandDefinitionError, UsageError, CommandError
from leapp.exceptions import (CommandDefinitionError, CommandError,
UnknownCommandError, UsageError)


class _LeappArgumentParser(ArgumentParser):
Expand All @@ -23,6 +23,7 @@ class _LeappHelpFormatter(RawDescriptionHelpFormatter):
"""
Capitalizes section headings in the help output
"""

def start_section(self, heading):
return super(_LeappHelpFormatter, self).start_section(heading.capitalize())

Expand All @@ -38,6 +39,7 @@ class _SubParserActionOverride(_SubParsersAction):

The additional code will not be executed if python 2.7.9 or higher is found.
"""

def __call__(self, parser, namespace, values, option_string=None):
super(_SubParserActionOverride, self).__call__(parser, namespace, values, option_string)
if sys.version_info >= (2, 7, 9):
Expand All @@ -54,6 +56,7 @@ class Command(object):
"""
Command implements a convenient command-based argument parsing the framework.
"""

def __init__(self, name, target=None, help='', description=None): # noqa; pylint: disable=redefined-builtin
"""
:param name: Name of the sub command
Expand Down Expand Up @@ -100,8 +103,10 @@ def execute(self, version):
args, leftover = parser.parse_known_args()
if leftover:
cmdname = args.prog.split()[-1]
# NOTE(ivasilev) No vetting of cmdname is necessary here as unless a proper leapp subcommand was
# invocated parser.parse_known_args() would have thrown an exception
if cmdname not in self._sub_commands:
cmdname = leftover[0]
if cmdname not in self._sub_commands:
raise UnknownCommandError(cmdname)
self._sub_commands[cmdname].parser.error(leftover)
args.func(args)

Expand Down
0