Feat(cli): add base command-line interface #16

Merged
jakob.scheid merged 21 commits from feature/cli into main 2026-09-13 20:11:00 +02:00
Showing only changes of commit 3ab9884be0 - Show all commits
+48 -10
View File
1
@@ -22,9 +22,11 @@ __all__ = [
import argparse import argparse
import pathlib import pathlib
import sys
from .parsers.python import VALID_SECTIONS as VALID_PYTHON_SECTIONS from .parsers.python import VALID_SECTIONS as VALID_PYTHON_SECTIONS
_LANG_PYTHON = 'python' _LANG_PYTHON = 'python'
_PROGRAM_NAME = 'jcloud-docsgen'
def existing_directory(path: str) -> pathlib.Path: def existing_directory(path: str) -> pathlib.Path:
_path = path _path = path
@@ -35,6 +37,19 @@ def existing_directory(path: str) -> pathlib.Path:
raise argparse.ArgumentTypeError(f'{_path}: not a directory') raise argparse.ArgumentTypeError(f'{_path}: not a directory')
return path 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: def main(argv = None) -> int:
common_parser = argparse.ArgumentParser(add_help = False) common_parser = argparse.ArgumentParser(add_help = False)
common_parser.add_argument( common_parser.add_argument(
@@ -93,15 +108,38 @@ def main(argv = None) -> int:
if args.output_dir is None: if args.output_dir is None:
args.output_dir = args.project_directory / 'docs/reference' args.output_dir = args.project_directory / 'docs/reference'
if args.language == _LANG_PYTHON: try:
from .parsers.python import generate if args.language == _LANG_PYTHON:
generate( from .parsers.python import generate
args.project_directory, generate(
args.output_dir, args.project_directory,
include_sections = args.sections, args.output_dir,
exclude_sections = args.sections_exclude, include_sections = args.sections,
allow_html = args.allow_html, exclude_sections = args.sections_exclude,
allow_tables = args.allow_tables 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 return 0