Repository: ocr-d/core
Issue: Processor decorator: --version fails due to missing parameters

In the current implementation of `Processor`, the CLI decorator handles calls to `--dump-json` and `--version` specially. But unlike the former, the latter does _not_ avoid going through the complete default constructor with its `ParameterValidator`. This causes simple `--version` invokations to fail for all processors that have required parameters in their tool json:

```
ocrd-keraslm-rate --version
Traceback (most recent call last):
  File "ocrd-keraslm-rate", line 11, in <module>
    load_entry_point('ocrd-keraslm', 'console_scripts', 'ocrd-keraslm-rate')()
  File "click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "ocrd_keraslm/wrapper/cli.py", line 9, in ocrd_keraslm_rate
    return ocrd_cli_wrap_processor(KerasRate, *args, **kwargs)
  File "ocrd/decorators.py", line 53, in ocrd_cli_wrap_processor
    p = processorClass(workspace=None)
  File "ocrd_keraslm/wrapper/rate.py", line 40, in __init__
    super(KerasRate, self).__init__(*args, **kwargs)
  File "ocrd/processor/base.py", line 135, in __init__
    raise Exception("Invalid parameters %s" % report.errors)
```

(I think this could be solved like `dump_json`, or by using `click.version_option` right away.)

Changed files:
tests/test_decorators.py, ocrd/ocrd/decorators.py

diff --git a/ocrd/ocrd/decorators.py b/ocrd/ocrd/decorators.py
index feb23cfa..ed204cbb 100644
--- a/ocrd/ocrd/decorators.py
+++ b/ocrd/ocrd/decorators.py
@@ -35,7 +35,10 @@ def ocrd_cli_wrap_processor(processorClass, ocrd_tool=None, mets=None, working_d
     if dump_json:
         processorClass(workspace=None, dump_json=True)
     elif version:
-        p = processorClass(workspace=None)
+        try:
+            p = processorClass(workspace=None)
+        except e:
+            pass
         print("Version %s, ocrd/core %s" % (p.version, OCRD_VERSION))
     elif mets is None:
         msg = 'Error: Missing option "-m" / "--mets".'
diff --git a/tests/test_decorators.py b/tests/test_decorators.py
index 5c174ac7..abf39fc4 100644
--- a/tests/test_decorators.py
+++ b/tests/test_decorators.py
@@ -11,7 +11,7 @@ from ocrd.decorators import (
     ocrd_cli_wrap_processor,
 )    # pylint: disable=protected-access
 from ocrd_utils.logging import setOverrideLogLevel, initLogging
-from ocrd_utils import pushd_popd
+from ocrd_utils import pushd_popd, VERSION as OCRD_VERSION
 
 @click.command()
 @ocrd_cli_options
@@ -23,7 +23,15 @@ def cli_with_ocrd_cli_options(*args, **kwargs):      # pylint: disable=unused-ar
 def cli_with_ocrd_loglevel(*args, **kwargs):         # pylint: disable=unused-argument
     pass
 
-DUMMY_TOOL = {'executable': 'ocrd-test', 'steps': ['recognition/post-correction']}
+DUMMY_TOOL = {
+    'executable': 'ocrd-test',
+    'steps': ['recognition/post-correction'],
+    'parameters': {
+        'foo': {
+            'required': True
+        }
+    }
+}
 
 class DummyProcessor(Processor):
 
@@ -72,6 +80,7 @@ class TestDecorators(TestCase):
 
     def test_processor_version(self):
         result = self.runner.invoke(cli_dummy_processor, ['--version'])
+        self.assertEqual(result.output, 'Version 0.0.1, ocrd/core %s\\n' % OCRD_VERSION)
         self.assertEqual(result.exit_code, 0)
 
     # XXX cannot be tested in this way because logging is reused and not part of output
@@ -83,7 +92,7 @@ class TestDecorators(TestCase):
     def test_processor_run(self):
         with copy_of_directory(assets.path_to('SBB0000F29300010000/data')) as tempdir:
             with pushd_popd(tempdir):
-                result = self.runner.invoke(cli_dummy_processor, ['--mets', 'mets.xml'])
+                result = self.runner.invoke(cli_dummy_processor, ['-p', '{"foo": 42}', '--mets', 'mets.xml'])
                 self.assertEqual(result.exit_code, 0)