Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ jobs:
# stop the build if there are Python syntax errors or undefined names
flake8 src --count --exit-zero --select=E9,F63,F7,F82 --show-source --statistics --format=github
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --format=github
flake8 src --count --exit-zero --per-file-ignores=src/ocrd/cli/__init__.py:E402,src/ocrd/__init__.py:F401,src/ocrd/__init__.py:F403,src/ocrd/decorators/__init__.py:F401,src/ocrd/processor/__init__.py:F401,src/ocrd_modelfactory/__init__.py:F401,src/ocrd_models/__init__.py:F401,src/ocrd_network/__init__.py:F401,src/ocrd_utils/__init__.py:F401,src/ocrd_validators/__init__.py:F401,src/ocrd_models/constants.py:E221 --extend-exclude=src/ocrd_models/ocrd_page_generateds.py,src/ocrd_page_user_methods/*.py --max-complexity=10 --max-line-length=127 --statistics --format=github
8 changes: 6 additions & 2 deletions src/ocrd/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@

from ocrd_utils import config


# pylint: disable=wrong-import-position

def command_with_replaced_help(*replacements):

class CommandWithReplacedHelp(click.Command):
def get_help(self, ctx):
newhelp : str = super().get_help(ctx)
newhelp: str = super().get_help(ctx)
for replacement in replacements:
newhelp = re.sub(*replacement, newhelp)
# print(newhelp)
return newhelp

return CommandWithReplacedHelp


# pylint: enable=wrong-import-position

from ..decorators import ocrd_loglevel
Expand Down Expand Up @@ -102,14 +104,16 @@ def get_help(self, ctx):
{config.describe('OCRD_LOGGING_DEBUG')}
"""


@click.group(epilog=_epilog)
@click.version_option(package_name='ocrd')
@ocrd_loglevel
def cli(**kwargs): # pylint: disable=unused-argument
def cli(**kwargs): # pylint: disable=unused-argument
"""
Entry-point of multi-purpose CLI for OCR-D
"""


cli.add_command(ocrd_tool_cli)
cli.add_command(workspace_cli)
cli.add_command(process_cli)
Expand Down
9 changes: 7 additions & 2 deletions src/ocrd/cli/bashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
# ocrd bashlib
# ----------------------------------------------------------------------


@click.group('bashlib')
def bashlib_cli():
"""
Expand All @@ -39,6 +40,7 @@ def bashlib_cli():
# ocrd bashlib filename
# ----------------------------------------------------------------------


@bashlib_cli.command('filename')
def bashlib_filename():
"""
Expand All @@ -48,6 +50,7 @@ def bashlib_filename():
"""
print(BASHLIB_FILENAME)


@bashlib_cli.command('constants')
@click.argument('name')
def bashlib_constants(name):
Expand All @@ -72,6 +75,7 @@ def bashlib_constants(name):
else:
print(val)


@bashlib_cli.command('input-files')
@click.option('--ocrd-tool', help="path to ocrd-tool.json of processor to feed", default=None)
@click.option('--executable', help="name of processor executable in ocrd-tool.json", default=None)
Expand Down Expand Up @@ -122,6 +126,7 @@ class FullBashlibProcessor(BashlibProcessor):
def metadata_location(self):
# needed for metadata loading and validation mechanism
return ocrd_tool

@property
def executable(self):
# needed for ocrd_tool lookup
Expand All @@ -137,8 +142,8 @@ def ocrd_tool(self):
# required now
'input_file_grp_cardinality': 1,
'output_file_grp_cardinality': 1,
'steps': ['']
}
'steps': ['']}

@property
def version(self):
# needed to satisfy the validator and wrapper
Expand Down
9 changes: 7 additions & 2 deletions src/ocrd/cli/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""
import click
from ocrd_utils import initLogging, getLogger, getLevelName
import logging


class LogCtx():

Expand All @@ -18,10 +18,13 @@ def log(self, lvl, *args, **kwargs):
logger = getLogger(self.name)
logger.log(getLevelName(lvl), *args, **kwargs)


pass_log = click.make_pass_decorator(LogCtx)


@click.group("log")
@click.option('-n', '--name', envvar='OCRD_TOOL_NAME', default='log_cli', metavar='LOGGER_NAME', help='Name of the logger', show_default=True)
@click.option('-n', '--name', envvar='OCRD_TOOL_NAME', default='log_cli', metavar='LOGGER_NAME',
help='Name of the logger', show_default=True)
Comment on lines +26 to +27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@click.option('-n', '--name', envvar='OCRD_TOOL_NAME', default='log_cli', metavar='LOGGER_NAME',
help='Name of the logger', show_default=True)
@click.option(
'-n', '--name', envvar='OCRD_TOOL_NAME', default='log_cli', metavar='LOGGER_NAME', help='Name of the logger', show_default=True)

How about that convention on all click options? That should still be acceptable from the POV of the linter. For click commands with more parameters, there will be less leading whitespace on each line. Same for all occurrences.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the follow-up line still be indented 4 spaces, though?

IMO these 13 characters are not much of a saving to warrant this pattern in general – most of our lines will be much longer, anyway. I would still favour breaking only when needed, and aligning indentation to the opening parentheses.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the follow-up line still be indented 4 spaces, though?

Yes.

@click.pass_context
def log_cli(ctx, name, *args, **kwargs):
"""
Expand All @@ -33,6 +36,7 @@ def log_cli(ctx, name, *args, **kwargs):
initLogging()
ctx.obj = LogCtx('ocrd.' + name)


def _bind_log_command(lvl):
@click.argument('msgs', nargs=-1)
@pass_log
Expand All @@ -47,5 +51,6 @@ def _log_wrapper(ctx, msgs):
ctx.log(lvl.upper(), msg)
return _log_wrapper


for _lvl in ['trace', 'debug', 'info', 'warning', 'error', 'critical']:
log_cli.command(_lvl, help="Log a %s message" % _lvl.upper())(_bind_log_command(_lvl))
30 changes: 26 additions & 4 deletions src/ocrd/cli/ocrd_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from ocrd_validators import ParameterValidator, OcrdToolValidator


class OcrdToolCtx():

def __init__(self, filename):
Expand All @@ -36,25 +37,31 @@ def __init__(self, filename):

class BashProcessor(Processor):
@property
def metadata(inner_self): # pylint: disable=no-self-argument,arguments-renamed
def metadata(inner_self): # pylint: disable=no-self-argument,arguments-renamed
return self.json

@property
def executable(inner_self): # pylint: disable=no-self-argument,arguments-renamed
def executable(inner_self): # pylint: disable=no-self-argument,arguments-renamed
return self.tool_name

@property
def moduledir(inner_self): # pylint: disable=no-self-argument,arguments-renamed
def moduledir(inner_self): # pylint: disable=no-self-argument,arguments-renamed
return os.path.dirname(self.filename)

# set docstrings to empty
__doc__ = None
# HACK: override the module-level docstring, too
getmodule(OcrdToolCtx).__doc__ = None
def process(inner_self): # pylint: disable=no-self-argument,arguments-renamed

def process(inner_self): # pylint: disable=no-self-argument,arguments-renamed
return super()

self.processor = BashProcessor


pass_ocrd_tool = click.make_pass_decorator(OcrdToolCtx)


# ----------------------------------------------------------------------
# ocrd ocrd-tool
# ----------------------------------------------------------------------
Expand All @@ -65,6 +72,7 @@ def process(inner_self): # pylint: disable=no-self-argument,arguments-renamed
def ocrd_tool_cli(ctx, json_file):
ctx.obj = OcrdToolCtx(json_file)


# ----------------------------------------------------------------------
# ocrd ocrd-tool version
# ----------------------------------------------------------------------
Expand All @@ -74,6 +82,7 @@ def ocrd_tool_cli(ctx, json_file):
def ocrd_tool_version(ctx):
print(ctx.json['version'])


# ----------------------------------------------------------------------
# ocrd ocrd-tool validate
# ----------------------------------------------------------------------
Expand All @@ -86,6 +95,7 @@ def ocrd_tool_validate(ctx):
if not report.is_valid:
return 128


# ----------------------------------------------------------------------
# ocrd ocrd-tool list-tools
# ----------------------------------------------------------------------
Expand All @@ -96,6 +106,7 @@ def ocrd_tool_list(ctx):
for tool in ctx.json['tools']:
print(tool)


# ----------------------------------------------------------------------
# ocrd ocrd-tool dump-tools
# ----------------------------------------------------------------------
Expand All @@ -105,13 +116,15 @@ def ocrd_tool_list(ctx):
def ocrd_tool_dump(ctx):
print(dumps(ctx.json['tools'], indent=True))


@ocrd_tool_cli.command('dump-module-dirs', help="Dump module directory of each tool")
@pass_ocrd_tool
def ocrd_tool_dump_module_dirs(ctx):
print(dumps({tool_name: get_moduledir(tool_name)
for tool_name in ctx.json['tools']},
indent=True))


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool
# ----------------------------------------------------------------------
Expand All @@ -124,6 +137,7 @@ def ocrd_tool_tool(ctx, tool_name):
raise Exception("No such tool: %s" % tool_name)
ctx.tool_name = tool_name


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool description
# ----------------------------------------------------------------------
Expand All @@ -133,29 +147,34 @@ def ocrd_tool_tool(ctx, tool_name):
def ocrd_tool_tool_description(ctx):
print(ctx.json['tools'][ctx.tool_name]['description'])


@ocrd_tool_tool.command('list-resources', help="List tool's file resources")
@pass_ocrd_tool
def ocrd_tool_tool_list_resources(ctx):
ctx.processor(None).list_resources()


@ocrd_tool_tool.command('resolve-resource', help="Get a tool's file resource full path name")
@click.argument('res_name')
@pass_ocrd_tool
def ocrd_tool_tool_resolve_resource(ctx, res_name):
print(ctx.processor(None).resolve_resource(res_name))


@ocrd_tool_tool.command('show-resource', help="Dump a tool's file resource")
@click.argument('res_name')
@pass_ocrd_tool
def ocrd_tool_tool_show_resource(ctx, res_name):
ctx.processor(None).show_resource(res_name)


@ocrd_tool_tool.command('help', help="Generate help for processors")
@click.argument('subcommand', required=False)
@pass_ocrd_tool
def ocrd_tool_tool_params_help(ctx, subcommand):
ctx.processor(None).show_help(subcommand=subcommand)


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool categories
# ----------------------------------------------------------------------
Expand All @@ -165,6 +184,7 @@ def ocrd_tool_tool_params_help(ctx, subcommand):
def ocrd_tool_tool_categories(ctx):
print('\n'.join(ctx.json['tools'][ctx.tool_name]['categories']))


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool steps
# ----------------------------------------------------------------------
Expand All @@ -174,6 +194,7 @@ def ocrd_tool_tool_categories(ctx):
def ocrd_tool_tool_steps(ctx):
print('\n'.join(ctx.json['tools'][ctx.tool_name]['steps']))


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool dump
# ----------------------------------------------------------------------
Expand All @@ -183,6 +204,7 @@ def ocrd_tool_tool_steps(ctx):
def ocrd_tool_tool_dump(ctx):
print(dumps(ctx.json['tools'][ctx.tool_name], indent=True))


# ----------------------------------------------------------------------
# ocrd ocrd-tool tool parse-params
# ----------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/ocrd/cli/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from ..decorators import ocrd_loglevel


# ----------------------------------------------------------------------
# ocrd process
# ----------------------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion src/ocrd/cli/resmgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
getLogger,
get_moduledir,
get_ocrd_tool_json,
resource_filename,
initLogging,
RESOURCE_LOCATIONS,
)
Expand Down
Loading