prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add --version flag to pyhf CLI
  # Description
  
  As [suggested by Lukas](https://github.com/diana-hep/pyhf/pull/304#issuecomment-428856809), adding a `--version` flag to the pyhf CLI could be useful.
  
  </issue>
  <code>
  [start of pyhf/commandline.py]
  1 import logging
  2 logging.basicConfig()
  3 log = logging.getLogger(__name__)
  4 
  5 import click
  6 import json
  7 import os
  8 import jsonpatch
  9 import sys
  10 
  11 from . import readxml
  12 from . import writexml
  13 from .utils import runOnePoint
  14 from .pdf import Model
  15 
  16 
  17 @click.group(context_settings=dict(help_option_names=['-h', '--help']))
  18 def pyhf():
  19     pass
  20 
  21 @pyhf.command()
  22 @click.argument('entrypoint-xml', type=click.Path(exists=True))
  23 @click.option('--basedir', help='The base directory for the XML files to point relative to.', type=click.Path(exists=True), default=os.getcwd())
  24 @click.option('--output-file', help='The location of the output json file. If not specified, prints to screen.', default=None)
  25 @click.option('--track-progress/--hide-progress', default=True)
  26 def xml2json(entrypoint_xml, basedir, output_file, track_progress):
  27     """ Entrypoint XML: The top-level XML file for the PDF definition. """
  28     spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)
  29     if output_file is None:
  30         print(json.dumps(spec, indent=4, sort_keys=True))
  31     else:
  32         with open(output_file, 'w+') as out_file:
  33             json.dump(spec, out_file, indent=4, sort_keys=True)
  34         log.debug("Written to {0:s}".format(output_file))
  35     sys.exit(0)
  36 
  37 @pyhf.command()
  38 @click.argument('workspace', default='-')
  39 @click.argument('xmlfile', default='-')
  40 @click.option('--specroot', default=click.Path(exists=True))
  41 @click.option('--dataroot', default=click.Path(exists=True))
  42 def json2xml(workspace, xmlfile, specroot, dataroot):
  43     with click.open_file(workspace, 'r') as specstream:
  44         d = json.load(specstream)
  45         with click.open_file(xmlfile, 'w') as outstream:
  46             outstream.write(writexml.writexml(d, specroot, dataroot,'').decode('utf-8'))
  47     sys.exit(0)
  48 
  49 @pyhf.command()
  50 @click.argument('workspace', default='-')
  51 @click.option('--output-file', help='The location of the output json file. If not specified, prints to screen.', default=None)
  52 @click.option('--measurement', default=None)
  53 @click.option('-p', '--patch', multiple=True)
  54 @click.option('--qualify-names/--no-qualify-names', default=False)
  55 def cls(workspace, output_file, measurement, qualify_names, patch):
  56     with click.open_file(workspace, 'r') as specstream:
  57         d = json.load(specstream)
  58     measurements = d['toplvl']['measurements']
  59     measurement_names = [m['name'] for m in measurements]
  60     measurement_index = 0
  61     log.debug('measurements defined:\n\t{0:s}'.format('\n\t'.join(measurement_names)))
  62     if measurement and measurement not in measurement_names:
  63         log.error('no measurement by name \'{0:s}\' exists, pick from one of the valid ones above'.format(measurement))
  64         sys.exit(1)
  65     else:
  66         if not measurement and len(measurements) > 1:
  67             log.warning('multiple measurements defined. Taking the first measurement.')
  68             measurement_index = 0
  69         elif measurement:
  70             measurement_index = measurement_names.index(measurement)
  71 
  72         log.debug('calculating CLs for measurement {0:s}'.format(measurements[measurement_index]['name']))
  73         spec = {'channels':d['channels']}
  74         for p in patch:
  75             with click.open_file(p, 'r') as read_file:
  76                 p = jsonpatch.JsonPatch(json.loads(read_file.read()))
  77             spec = p.apply(spec)
  78         p = Model(spec, poiname=measurements[measurement_index]['config']['poi'], qualify_names=qualify_names)
  79         result = runOnePoint(1.0, sum((d['data'][c['name']] for c in d['channels']),[]) + p.config.auxdata, p)
  80         result = {'CLs_obs': result[-2].tolist()[0], 'CLs_exp': result[-1].ravel().tolist()}
  81         if output_file is None:
  82             print(json.dumps(result, indent=4, sort_keys=True))
  83         else:
  84             with open(output_file, 'w+') as out_file:
  85                 json.dump(result, out_file, indent=4, sort_keys=True)
  86             log.debug("Written to {0:s}".format(output_file))
  87         sys.exit(0)
  88
  [end of pyhf/commandline.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/pyhf/commandline.py b/pyhf/commandline.py
  --- a/pyhf/commandline.py
  +++ b/pyhf/commandline.py
  @@ -12,9 +12,11 @@
   from . import writexml
   from .utils import runOnePoint
   from .pdf import Model
  +from .version import __version__
   
   
   @click.group(context_settings=dict(help_option_names=['-h', '--help']))
  +@click.version_option(version=__version__)
   def pyhf():
       pass
  
verification_info: {"golden_diff": "diff --git a/pyhf/commandline.py b/pyhf/commandline.py\n--- a/pyhf/commandline.py\n+++ b/pyhf/commandline.py\n@@ -12,9 +12,11 @@\n from . import writexml\n from .utils import runOnePoint\n from .pdf import Model\n+from .version import __version__\n \n \n @click.group(context_settings=dict(help_option_names=['-h', '--help']))\n+@click.version_option(version=__version__)\n def pyhf():\n     pass\n", "issue": "Add --version flag to pyhf CLI\n# Description\r\n\r\nAs [suggested by Lukas](https://github.com/diana-hep/pyhf/pull/304#issuecomment-428856809), adding a `--version` flag to the pyhf CLI could be useful.\n", "before_files": [{"content": "import logging\nlogging.basicConfig()\nlog = logging.getLogger(__name__)\n\nimport click\nimport json\nimport os\nimport jsonpatch\nimport sys\n\nfrom . import readxml\nfrom . import writexml\nfrom .utils import runOnePoint\nfrom .pdf import Model\n\n\n@click.group(context_settings=dict(help_option_names=['-h', '--help']))\ndef pyhf():\n    pass\n\n@pyhf.command()\n@click.argument('entrypoint-xml', type=click.Path(exists=True))\n@click.option('--basedir', help='The base directory for the XML files to point relative to.', type=click.Path(exists=True), default=os.getcwd())\n@click.option('--output-file', help='The location of the output json file. If not specified, prints to screen.', default=None)\n@click.option('--track-progress/--hide-progress', default=True)\ndef xml2json(entrypoint_xml, basedir, output_file, track_progress):\n    \"\"\" Entrypoint XML: The top-level XML file for the PDF definition. \"\"\"\n    spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)\n    if output_file is None:\n        print(json.dumps(spec, indent=4, sort_keys=True))\n    else:\n        with open(output_file, 'w+') as out_file:\n            json.dump(spec, out_file, indent=4, sort_keys=True)\n        log.debug(\"Written to {0:s}\".format(output_file))\n    sys.exit(0)\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.argument('xmlfile', default='-')\n@click.option('--specroot', default=click.Path(exists=True))\n@click.option('--dataroot', default=click.Path(exists=True))\ndef json2xml(workspace, xmlfile, specroot, dataroot):\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n        with click.open_file(xmlfile, 'w') as outstream:\n            outstream.write(writexml.writexml(d, specroot, dataroot,'').decode('utf-8'))\n    sys.exit(0)\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option('--output-file', help='The location of the output json file. If not specified, prints to screen.', default=None)\n@click.option('--measurement', default=None)\n@click.option('-p', '--patch', multiple=True)\n@click.option('--qualify-names/--no-qualify-names', default=False)\ndef cls(workspace, output_file, measurement, qualify_names, patch):\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n    measurements = d['toplvl']['measurements']\n    measurement_names = [m['name'] for m in measurements]\n    measurement_index = 0\n    log.debug('measurements defined:\\n\\t{0:s}'.format('\\n\\t'.join(measurement_names)))\n    if measurement and measurement not in measurement_names:\n        log.error('no measurement by name \\'{0:s}\\' exists, pick from one of the valid ones above'.format(measurement))\n        sys.exit(1)\n    else:\n        if not measurement and len(measurements) > 1:\n            log.warning('multiple measurements defined. Taking the first measurement.')\n            measurement_index = 0\n        elif measurement:\n            measurement_index = measurement_names.index(measurement)\n\n        log.debug('calculating CLs for measurement {0:s}'.format(measurements[measurement_index]['name']))\n        spec = {'channels':d['channels']}\n        for p in patch:\n            with click.open_file(p, 'r') as read_file:\n                p = jsonpatch.JsonPatch(json.loads(read_file.read()))\n            spec = p.apply(spec)\n        p = Model(spec, poiname=measurements[measurement_index]['config']['poi'], qualify_names=qualify_names)\n        result = runOnePoint(1.0, sum((d['data'][c['name']] for c in d['channels']),[]) + p.config.auxdata, p)\n        result = {'CLs_obs': result[-2].tolist()[0], 'CLs_exp': result[-1].ravel().tolist()}\n        if output_file is None:\n            print(json.dumps(result, indent=4, sort_keys=True))\n        else:\n            with open(output_file, 'w+') as out_file:\n                json.dump(result, out_file, indent=4, sort_keys=True)\n            log.debug(\"Written to {0:s}\".format(output_file))\n        sys.exit(0)\n", "path": "pyhf/commandline.py"}]}