prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Switch CLI to use click
  I recently discovered [`click`](http://click.pocoo.org/5/) which makes adding command line options and arguments to your python application super simple and much more robust.
  
  We should look at replacing the [current argparse code](https://github.com/opsdroid/opsdroid/blob/master/opsdroid/__main__.py#L88) with `click`!
  
  </issue>
  <code>
  [start of opsdroid/__main__.py]
  1 """Starts opsdroid."""
  2 
  3 import os
  4 import sys
  5 import logging
  6 import argparse
  7 import gettext
  8 
  9 from opsdroid.core import OpsDroid
  10 from opsdroid.const import DEFAULT_LOG_FILENAME, EXAMPLE_CONFIG_FILE,\
  11     DEFAULT_LANGUAGE, LOCALE_DIR
  12 from opsdroid.web import Web
  13 
  14 
  15 gettext.install('opsdroid')
  16 _LOGGER = logging.getLogger("opsdroid")
  17 
  18 
  19 def configure_lang(config):
  20     """Configure app language based on user config."""
  21     lang_code = config.get("lang", DEFAULT_LANGUAGE)
  22     if lang_code != DEFAULT_LANGUAGE:
  23         lang = gettext.translation(
  24             'opsdroid', LOCALE_DIR, (lang_code,), fallback=True)
  25         lang.install()
  26 
  27 
  28 def configure_logging(config):
  29     """Configure the root logger based on user config."""
  30     rootlogger = logging.getLogger()
  31     while rootlogger.handlers:
  32         rootlogger.handlers.pop()
  33 
  34     try:
  35         if config["logging"]["path"]:
  36             logfile_path = os.path.expanduser(config["logging"]["path"])
  37         else:
  38             logfile_path = config["logging"]["path"]
  39     except KeyError:
  40         logfile_path = DEFAULT_LOG_FILENAME
  41 
  42     try:
  43         log_level = get_logging_level(
  44             config["logging"]["level"])
  45     except KeyError:
  46         log_level = logging.INFO
  47 
  48     rootlogger.setLevel(log_level)
  49     formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')
  50 
  51     console_handler = logging.StreamHandler()
  52     console_handler.setLevel(log_level)
  53     console_handler.setFormatter(formatter)
  54     rootlogger.addHandler(console_handler)
  55 
  56     try:
  57         if not config["logging"]["console"]:
  58             console_handler.setLevel(logging.CRITICAL)
  59     except KeyError:
  60         pass
  61 
  62     if logfile_path:
  63         logdir = os.path.dirname(os.path.realpath(logfile_path))
  64         if not os.path.isdir(logdir):
  65             os.makedirs(logdir)
  66         file_handler = logging.FileHandler(logfile_path)
  67         file_handler.setLevel(log_level)
  68         file_handler.setFormatter(formatter)
  69         rootlogger.addHandler(file_handler)
  70     _LOGGER.info("="*40)
  71     _LOGGER.info(_("Started application"))
  72 
  73 
  74 def get_logging_level(logging_level):
  75     """Get the logger level based on the user configuration."""
  76     if logging_level == 'critical':
  77         return logging.CRITICAL
  78     elif logging_level == 'error':
  79         return logging.ERROR
  80     elif logging_level == 'warning':
  81         return logging.WARNING
  82     elif logging_level == 'debug':
  83         return logging.DEBUG
  84 
  85     return logging.INFO
  86 
  87 
  88 def parse_args(args):
  89     """Parse command line arguments."""
  90     parser = argparse.ArgumentParser(description='Run opsdroid.')
  91     parser.add_argument('--gen-config', action="store_true",
  92                         help='prints out an example configuration file')
  93     return parser.parse_args(args)
  94 
  95 
  96 def check_dependencies():
  97     """Check for system dependencies required by opsdroid."""
  98     if sys.version_info.major < 3 or sys.version_info.minor < 5:
  99         logging.critical(_("Whoops! opsdroid requires python 3.5 or above."))
  100         sys.exit(1)
  101 
  102 
  103 def welcome_message(config):
  104     """Add welcome message if set to true in configuration."""
  105     try:
  106         if config['welcome-message']:
  107             _LOGGER.info("=" * 40)
  108             _LOGGER.info(_("You can customise your opsdroid by modifying "
  109                            "your configuration.yaml"))
  110             _LOGGER.info(_("Read more at: "
  111                            "http://opsdroid.readthedocs.io/#configuration"))
  112             _LOGGER.info(_("Watch the Get Started Videos at: "
  113                            "http://bit.ly/2fnC0Fh"))
  114             _LOGGER.info(_("Install Opsdroid Desktop at: \n"
  115                            "https://github.com/opsdroid/opsdroid-desktop/"
  116                            "releases"))
  117             _LOGGER.info("=" * 40)
  118     except KeyError:
  119         _LOGGER.warning(_("'welcome-message: true/false' is missing in "
  120                           "configuration.yaml"))
  121 
  122 
  123 def main():
  124     """Parse the args and then start the application."""
  125     args = parse_args(sys.argv[1:])
  126 
  127     if args.gen_config:
  128         with open(EXAMPLE_CONFIG_FILE, 'r') as conf:
  129             print(conf.read())
  130         sys.exit(0)
  131 
  132     check_dependencies()
  133 
  134     with OpsDroid() as opsdroid:
  135         opsdroid.load()
  136         configure_lang(opsdroid.config)
  137         configure_logging(opsdroid.config)
  138         welcome_message(opsdroid.config)
  139         opsdroid.web_server = Web(opsdroid)
  140         opsdroid.start_loop()
  141 
  142 
  143 def init():
  144     """Enter the application."""
  145     if __name__ == "__main__":
  146         main()
  147 
  148 
  149 init()
  150
  [end of opsdroid/__main__.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/opsdroid/__main__.py b/opsdroid/__main__.py
  --- a/opsdroid/__main__.py
  +++ b/opsdroid/__main__.py
  @@ -3,12 +3,13 @@
   import os
   import sys
   import logging
  -import argparse
   import gettext
   
  +import click
  +
   from opsdroid.core import OpsDroid
  -from opsdroid.const import DEFAULT_LOG_FILENAME, EXAMPLE_CONFIG_FILE,\
  -    DEFAULT_LANGUAGE, LOCALE_DIR
  +from opsdroid.const import __version__, DEFAULT_LOG_FILENAME, \
  +    EXAMPLE_CONFIG_FILE, DEFAULT_LANGUAGE, LOCALE_DIR
   from opsdroid.web import Web
   
   
  @@ -85,14 +86,6 @@
       return logging.INFO
   
   
  -def parse_args(args):
  -    """Parse command line arguments."""
  -    parser = argparse.ArgumentParser(description='Run opsdroid.')
  -    parser.add_argument('--gen-config', action="store_true",
  -                        help='prints out an example configuration file')
  -    return parser.parse_args(args)
  -
  -
   def check_dependencies():
       """Check for system dependencies required by opsdroid."""
       if sys.version_info.major < 3 or sys.version_info.minor < 5:
  @@ -100,6 +93,23 @@
           sys.exit(1)
   
   
  +def print_version(ctx, param, value):
  +    """Print out the version of opsdroid that is installed."""
  +    if not value or ctx.resilient_parsing:
  +        return
  +    click.echo('opsdroid v{version}'.format(version=__version__))
  +    ctx.exit(0)
  +
  +
  +def print_example_config(ctx, param, value):
  +    """Print out the example config."""
  +    if not value or ctx.resilient_parsing:
  +        return
  +    with open(EXAMPLE_CONFIG_FILE, 'r') as conf:
  +        click.echo(conf.read())
  +    ctx.exit(0)
  +
  +
   def welcome_message(config):
       """Add welcome message if set to true in configuration."""
       try:
  @@ -120,15 +130,19 @@
                             "configuration.yaml"))
   
   
  +@click.command()
  +@click.option('--gen-config', is_flag=True, callback=print_example_config,
  +              expose_value=False, default=False,
  +              help='Print an example config and exit.')
  +@click.option('--version', '-v', is_flag=True, callback=print_version,
  +              expose_value=False, default=False, is_eager=True,
  +              help='Print the version and exit.')
   def main():
  -    """Parse the args and then start the application."""
  -    args = parse_args(sys.argv[1:])
  -
  -    if args.gen_config:
  -        with open(EXAMPLE_CONFIG_FILE, 'r') as conf:
  -            print(conf.read())
  -        sys.exit(0)
  +    """Opsdroid is a chat bot framework written in Python.
   
  +    It is designed to be extendable, scalable and simple.
  +    See https://opsdroid.github.io/ for more information.
  +    """
       check_dependencies()
   
       with OpsDroid() as opsdroid:
  
verification_info: {"golden_diff": "diff --git a/opsdroid/__main__.py b/opsdroid/__main__.py\n--- a/opsdroid/__main__.py\n+++ b/opsdroid/__main__.py\n@@ -3,12 +3,13 @@\n import os\n import sys\n import logging\n-import argparse\n import gettext\n \n+import click\n+\n from opsdroid.core import OpsDroid\n-from opsdroid.const import DEFAULT_LOG_FILENAME, EXAMPLE_CONFIG_FILE,\\\n-    DEFAULT_LANGUAGE, LOCALE_DIR\n+from opsdroid.const import __version__, DEFAULT_LOG_FILENAME, \\\n+    EXAMPLE_CONFIG_FILE, DEFAULT_LANGUAGE, LOCALE_DIR\n from opsdroid.web import Web\n \n \n@@ -85,14 +86,6 @@\n     return logging.INFO\n \n \n-def parse_args(args):\n-    \"\"\"Parse command line arguments.\"\"\"\n-    parser = argparse.ArgumentParser(description='Run opsdroid.')\n-    parser.add_argument('--gen-config', action=\"store_true\",\n-                        help='prints out an example configuration file')\n-    return parser.parse_args(args)\n-\n-\n def check_dependencies():\n     \"\"\"Check for system dependencies required by opsdroid.\"\"\"\n     if sys.version_info.major < 3 or sys.version_info.minor < 5:\n@@ -100,6 +93,23 @@\n         sys.exit(1)\n \n \n+def print_version(ctx, param, value):\n+    \"\"\"Print out the version of opsdroid that is installed.\"\"\"\n+    if not value or ctx.resilient_parsing:\n+        return\n+    click.echo('opsdroid v{version}'.format(version=__version__))\n+    ctx.exit(0)\n+\n+\n+def print_example_config(ctx, param, value):\n+    \"\"\"Print out the example config.\"\"\"\n+    if not value or ctx.resilient_parsing:\n+        return\n+    with open(EXAMPLE_CONFIG_FILE, 'r') as conf:\n+        click.echo(conf.read())\n+    ctx.exit(0)\n+\n+\n def welcome_message(config):\n     \"\"\"Add welcome message if set to true in configuration.\"\"\"\n     try:\n@@ -120,15 +130,19 @@\n                           \"configuration.yaml\"))\n \n \n+@click.command()\n+@click.option('--gen-config', is_flag=True, callback=print_example_config,\n+              expose_value=False, default=False,\n+              help='Print an example config and exit.')\n+@click.option('--version', '-v', is_flag=True, callback=print_version,\n+              expose_value=False, default=False, is_eager=True,\n+              help='Print the version and exit.')\n def main():\n-    \"\"\"Parse the args and then start the application.\"\"\"\n-    args = parse_args(sys.argv[1:])\n-\n-    if args.gen_config:\n-        with open(EXAMPLE_CONFIG_FILE, 'r') as conf:\n-            print(conf.read())\n-        sys.exit(0)\n+    \"\"\"Opsdroid is a chat bot framework written in Python.\n \n+    It is designed to be extendable, scalable and simple.\n+    See https://opsdroid.github.io/ for more information.\n+    \"\"\"\n     check_dependencies()\n \n     with OpsDroid() as opsdroid:\n", "issue": "Switch CLI to use click\nI recently discovered [`click`](http://click.pocoo.org/5/) which makes adding command line options and arguments to your python application super simple and much more robust.\r\n\r\nWe should look at replacing the [current argparse code](https://github.com/opsdroid/opsdroid/blob/master/opsdroid/__main__.py#L88) with `click`!\n", "before_files": [{"content": "\"\"\"Starts opsdroid.\"\"\"\n\nimport os\nimport sys\nimport logging\nimport argparse\nimport gettext\n\nfrom opsdroid.core import OpsDroid\nfrom opsdroid.const import DEFAULT_LOG_FILENAME, EXAMPLE_CONFIG_FILE,\\\n    DEFAULT_LANGUAGE, LOCALE_DIR\nfrom opsdroid.web import Web\n\n\ngettext.install('opsdroid')\n_LOGGER = logging.getLogger(\"opsdroid\")\n\n\ndef configure_lang(config):\n    \"\"\"Configure app language based on user config.\"\"\"\n    lang_code = config.get(\"lang\", DEFAULT_LANGUAGE)\n    if lang_code != DEFAULT_LANGUAGE:\n        lang = gettext.translation(\n            'opsdroid', LOCALE_DIR, (lang_code,), fallback=True)\n        lang.install()\n\n\ndef configure_logging(config):\n    \"\"\"Configure the root logger based on user config.\"\"\"\n    rootlogger = logging.getLogger()\n    while rootlogger.handlers:\n        rootlogger.handlers.pop()\n\n    try:\n        if config[\"logging\"][\"path\"]:\n            logfile_path = os.path.expanduser(config[\"logging\"][\"path\"])\n        else:\n            logfile_path = config[\"logging\"][\"path\"]\n    except KeyError:\n        logfile_path = DEFAULT_LOG_FILENAME\n\n    try:\n        log_level = get_logging_level(\n            config[\"logging\"][\"level\"])\n    except KeyError:\n        log_level = logging.INFO\n\n    rootlogger.setLevel(log_level)\n    formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')\n\n    console_handler = logging.StreamHandler()\n    console_handler.setLevel(log_level)\n    console_handler.setFormatter(formatter)\n    rootlogger.addHandler(console_handler)\n\n    try:\n        if not config[\"logging\"][\"console\"]:\n            console_handler.setLevel(logging.CRITICAL)\n    except KeyError:\n        pass\n\n    if logfile_path:\n        logdir = os.path.dirname(os.path.realpath(logfile_path))\n        if not os.path.isdir(logdir):\n            os.makedirs(logdir)\n        file_handler = logging.FileHandler(logfile_path)\n        file_handler.setLevel(log_level)\n        file_handler.setFormatter(formatter)\n        rootlogger.addHandler(file_handler)\n    _LOGGER.info(\"=\"*40)\n    _LOGGER.info(_(\"Started application\"))\n\n\ndef get_logging_level(logging_level):\n    \"\"\"Get the logger level based on the user configuration.\"\"\"\n    if logging_level == 'critical':\n        return logging.CRITICAL\n    elif logging_level == 'error':\n        return logging.ERROR\n    elif logging_level == 'warning':\n        return logging.WARNING\n    elif logging_level == 'debug':\n        return logging.DEBUG\n\n    return logging.INFO\n\n\ndef parse_args(args):\n    \"\"\"Parse command line arguments.\"\"\"\n    parser = argparse.ArgumentParser(description='Run opsdroid.')\n    parser.add_argument('--gen-config', action=\"store_true\",\n                        help='prints out an example configuration file')\n    return parser.parse_args(args)\n\n\ndef check_dependencies():\n    \"\"\"Check for system dependencies required by opsdroid.\"\"\"\n    if sys.version_info.major < 3 or sys.version_info.minor < 5:\n        logging.critical(_(\"Whoops! opsdroid requires python 3.5 or above.\"))\n        sys.exit(1)\n\n\ndef welcome_message(config):\n    \"\"\"Add welcome message if set to true in configuration.\"\"\"\n    try:\n        if config['welcome-message']:\n            _LOGGER.info(\"=\" * 40)\n            _LOGGER.info(_(\"You can customise your opsdroid by modifying \"\n                           \"your configuration.yaml\"))\n            _LOGGER.info(_(\"Read more at: \"\n                           \"http://opsdroid.readthedocs.io/#configuration\"))\n            _LOGGER.info(_(\"Watch the Get Started Videos at: \"\n                           \"http://bit.ly/2fnC0Fh\"))\n            _LOGGER.info(_(\"Install Opsdroid Desktop at: \\n\"\n                           \"https://github.com/opsdroid/opsdroid-desktop/\"\n                           \"releases\"))\n            _LOGGER.info(\"=\" * 40)\n    except KeyError:\n        _LOGGER.warning(_(\"'welcome-message: true/false' is missing in \"\n                          \"configuration.yaml\"))\n\n\ndef main():\n    \"\"\"Parse the args and then start the application.\"\"\"\n    args = parse_args(sys.argv[1:])\n\n    if args.gen_config:\n        with open(EXAMPLE_CONFIG_FILE, 'r') as conf:\n            print(conf.read())\n        sys.exit(0)\n\n    check_dependencies()\n\n    with OpsDroid() as opsdroid:\n        opsdroid.load()\n        configure_lang(opsdroid.config)\n        configure_logging(opsdroid.config)\n        welcome_message(opsdroid.config)\n        opsdroid.web_server = Web(opsdroid)\n        opsdroid.start_loop()\n\n\ndef init():\n    \"\"\"Enter the application.\"\"\"\n    if __name__ == \"__main__\":\n        main()\n\n\ninit()\n", "path": "opsdroid/__main__.py"}]}