Repository: rotki/rotki

Issue:
Do not crush if a wrong argument is given to the CLI backend
## Problem Definition

If directly interacting with the CLI backend and a wrong argument is provided then a crush happens.

```
CRITICAL:root:Traceback (most recent call last):
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/__main__.py", line 14, in main
    rotkehlchen_server = RotkehlchenServer()
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/server.py", line 45, in __init__
    self.args = arg_parser.parse_args()
  File "/usr/lib64/python3.7/argparse.py", line 1749, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib64/python3.7/argparse.py", line 1781, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib64/python3.7/argparse.py", line 1990, in _parse_known_args
    stop_index = consume_positionals(start_index)
  File "/usr/lib64/python3.7/argparse.py", line 1946, in consume_positionals
    take_action(action, args)
  File "/usr/lib64/python3.7/argparse.py", line 1855, in take_action
    action(self, namespace, argument_values, option_string)
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/args.py", line 14, in __call__
    print(get_system_spec()['rotkehlchen'])
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/utils/misc.py", line 319, in get_system_spec
    rotkehlchen=pkg_resources.require(rotkehlchen.__name__)[0].version,
  File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.7/site-packages/pkg_resources/__init__.py", line 895, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.7/site-packages/pkg_resources/__init__.py", line 781, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'rotkehlchen' distribution was not found and is required by the application

Failed to start rotkehlchen backend:
Traceback (most recent call last):
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/__main__.py", line 14, in main
    rotkehlchen_server = RotkehlchenServer()
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/server.py", line 45, in __init__
    self.args = arg_parser.parse_args()
  File "/usr/lib64/python3.7/argparse.py", line 1749, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib64/python3.7/argparse.py", line 1781, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib64/python3.7/argparse.py", line 1990, in _parse_known_args
    stop_index = consume_positionals(start_index)
  File "/usr/lib64/python3.7/argparse.py", line 1946, in consume_positionals
    take_action(action, args)
  File "/usr/lib64/python3.7/argparse.py", line 1855, in take_action
    action(self, namespace, argument_values, option_string)
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/args.py", line 14, in __call__
    print(get_system_spec()['rotkehlchen'])
  File "/home/lefteris/w/rotkehlchen/rotkehlchen/utils/misc.py", line 319, in get_system_spec
    rotkehlchen=pkg_resources.require(rotkehlchen.__name__)[0].version,
  File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.7/site-packages/pkg_resources/__init__.py", line 895, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.7/site-packages/pkg_resources/__init__.py", line 781, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'rotkehlchen' distribution was not found and is required by the application
```
## Task

Fix it. Perhaps also add CLI tests?


Discussion:

Resolving patch:
diff --git a/rotkehlchen/args.py b/rotkehlchen/args.py
--- a/rotkehlchen/args.py
+++ b/rotkehlchen/args.py
@@ -6,11 +6,18 @@
 from rotkehlchen.utils.misc import get_system_spec
 
 
-class VersionAction(argparse.Action):
+class CommandAction(argparse.Action):
+    """Interprets the positional argument as a command if that command exists"""
     def __init__(self, option_strings, dest, **kwargs):  # pylint: disable=unused-argument
         super().__init__(option_strings, dest)
 
     def __call__(self, parser, namespace, values, option_string=None):
+        # Only command we have at the moment is version
+        if values != 'version':
+            parser.print_usage()
+            print(f'Unrecognized command: {values}.')
+            sys.exit(0)
+
         print(get_system_spec()['rotkehlchen'])
         sys.exit(0)
 
@@ -71,7 +78,7 @@ def app_args(prog: str, description: str) -> argparse.ArgumentParser:
     p.add_argument(
         'version',
         help='Shows the rotkehlchen version',
-        action=VersionAction,
+        action=CommandAction,
     )
 
     return p


Test patch: