diff --git a/src/jcloud_docsgen/cli/cli.py b/src/jcloud_docsgen/cli/cli.py index d54fde5..a9a6db2 100644 --- a/src/jcloud_docsgen/cli/cli.py +++ b/src/jcloud_docsgen/cli/cli.py @@ -22,9 +22,11 @@ __all__ = [ import argparse import pathlib +import sys from .parsers.python import VALID_SECTIONS as VALID_PYTHON_SECTIONS _LANG_PYTHON = 'python' +_PROGRAM_NAME = 'jcloud-docsgen' def existing_directory(path: str) -> pathlib.Path: _path = path @@ -35,6 +37,19 @@ def existing_directory(path: str) -> pathlib.Path: raise argparse.ArgumentTypeError(f'{_path}: not a directory') return path +def error(message: str, exit_code: int = 1): + ''' + Shows an error message and returns the exit code. + + :param message: The error message to show. + :type message: str + :param exit_code: The exit code. + :type exit_code: int + ''' + + print(f'{_PROGRAM_NAME}: error: {message}', file = sys.stderr) + return exit_code + def main(argv = None) -> int: common_parser = argparse.ArgumentParser(add_help = False) common_parser.add_argument( @@ -93,15 +108,38 @@ def main(argv = None) -> int: if args.output_dir is None: args.output_dir = args.project_directory / 'docs/reference' - if args.language == _LANG_PYTHON: - from .parsers.python import generate - generate( - args.project_directory, - args.output_dir, - include_sections = args.sections, - exclude_sections = args.sections_exclude, - allow_html = args.allow_html, - allow_tables = args.allow_tables - ) + try: + if args.language == _LANG_PYTHON: + from .parsers.python import generate + generate( + args.project_directory, + args.output_dir, + include_sections = args.sections, + exclude_sections = args.sections_exclude, + allow_html = args.allow_html, + allow_tables = args.allow_tables + ) + except FileNotFoundError as exc: + return error(f'{exc.filename}: no such file or directory') + except NotADirectoryError as exc: + return error(f'{exc.filename}: not a directory') + except IsADirectoryError as exc: + return error(f'{exc.filename}: is a directory') + except FileExistsError as exc: + return error(f'{exc.filename}: file already exists') + except PermissionError as exc: + return error(f'{exc.filename}: permission denied') + except OSError as exc: + return error(f'{exc.filename}: {exc.args[1]}') + except UnicodeError: + return error('invalid text encoding') + except SyntaxError: + # TODO: add a custom exception class to clearify that a project + # parsing syntax error is meant. + return error(f'syntax error in project source code') + except KeyboardInterrupt: + return 130 + except BrokenPipeError: + return 141 return 0