Added parser.py

Added soypak parser module using argparse to parse arguments, also have a custom help screen.
This commit is contained in:
Ethan Smith-Coss 2023-07-04 20:51:45 +01:00
parent 14864aff8f
commit 23fd41ce03
Signed by: TheOnePath
GPG Key ID: 4E7D436CE1A0BAF1

74
soypak/cli/parser.py Normal file
View File

@ -0,0 +1,74 @@
import argparse
import textwrap
from typing import Iterable
import soypak.__version__ as module_info
class OverrideHelpFormatter(argparse.RawDescriptionHelpFormatter, argparse.HelpFormatter):
"""Override class for argparse help message display.
Using both `argparse@RawDescriptionHelpFormatter` and `argparse@HelpFormatter` to gain custom epilogue and usage
title. To be used as parameter value for `formatter_class=` during `argparse@ArgumentParser` construction.
"""
def add_usage(self, usage: str | None, actions: Iterable[argparse.Action],
groups: Iterable[argparse._MutuallyExclusiveGroup], prefix: str | None = None) -> None:
return super().add_usage(usage, actions, groups, 'Usage: ')
class SoypakParser(argparse.ArgumentParser):
"""soypak parsing and translating program arguments given by `sys.argv`.
Class constructs a custom help message display which is shown with arguments `-h|--help` or when an invalid argument
is passed. There is mangling of attributes in in the parent class to provide a modern, simplistic, and coherent help
message display found with other package managers.
"""
def __init__(self) -> None:
self.NAME = module_info.__title__
USAGE = "%(prog)s [options] <command> [arguments]"
DESC = module_info.__description__
EPILOGUE = textwrap.dedent("""\
Author(s): %(authors)s.
Contacts: %(emails)s
Thanks for using our software %(biscuit)s
%(copyright)s. Licensed under %(licence)s
""" % {
"authors": ", ".join(module_info.__authors__),
"emails": ", ".join(module_info.__emails__),
"copyright": module_info.__copyright__,
"licence": module_info.__licence__,
"biscuit": module_info.__biscuit__
})
self.VERSION = "%s %s" % (self.NAME, module_info.__version__)
super().__init__(
prog=self.NAME, usage=USAGE, description=DESC, epilog=EPILOGUE,
allow_abbrev=False, formatter_class=OverrideHelpFormatter,
)
# override the default title for positional arguments
self._positionals.title = "Where <command> is one of"
self._optionals.title = "Options"
# this argument will take the value of whatever the first argument supplied is. Any additional positional
# arguments will be collected separately
self.add_argument("command", nargs='?')
# overwrite the action group. @Note: this is to give custom positional arguments in the help message but aren't
# actual arguments. They are stored in the "command" attribute (defined above).
# :@TODO: When commands are registered, allow the register to submit info for the action group. This overwrite
# will then be configured using all the register commands.
self._positionals._group_actions = []
### argparse._StoreAction(option_strings=[], dest=cmd, help=desc)
# optional arguments
self.add_argument("--version", action="store_true",
help="show the program's version number and exit")
def parse_args(self) -> tuple[str, list]:
# we use `parse_known_args` to allow for splitting of largs/rargs
self.namespace, self.rargs = self.parse_known_args()
return (self.namespace.command, self.rargs)