boilerplate-python/main.py

170 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
# coding: utf8
"""<SCRIPT_NAME>.
<SHORT_DESCRIPTION>
Author: {developer} <{mail}> {date}
Licence: GNU AGPL v3: http://www.gnu.org/licenses/
This file is part of [`<GIT REPO NAME>`](<GIT REPO URL>)
"""
import argparse
import logging
import logging.handlers
from os import environ, path
import sys
logger = logging.getLogger(path.splitext(path.basename(sys.argv[0]))[0])
def setup_logging(options):
"""Configure logging."""
root = logging.getLogger("")
logger.setLevel(options.debug and logging.DEBUG or logging.INFO)
format_debug = "%(levelname)s\t[%(name)s] %(message)s"
format_default = "%(message)s"
if options.debug:
# Logging with --debug option
if not sys.stderr.isatty():
# Logging in a file when launched not in a terminal
facility = logging.handlers.SysLogHandler.LOG_DAEMON
handler_syslog = logging.handlers.SysLogHandler(
address="/dev/log", facility=facility
)
handler_syslog.setFormatter(logging.Formatter(format_default))
root.addHandler(handler_syslog)
else:
# Logging on terminal standard output
handler_console = logging.StreamHandler()
handler_console.setFormatter(logging.Formatter(format_debug))
root.addHandler(handler_console)
else:
# Logging default setings
handler_console = logging.StreamHandler()
handler_console.setFormatter(logging.Formatter(format_default))
root.addHandler(handler_console)
class CustomFormatter(
argparse.RawDescriptionHelpFormatter, argparse.ArgumentDefaultsHelpFormatter
):
"""This convert file docstring into help text."""
pass # pylint: disable=W0107
def parse_args(args=sys.argv[1:]): # pylint: disable=W0102
"""Argument parser.
Put values & describe parameters here not in your code
Ease usage with help & docs
"""
parser = argparse.ArgumentParser(
description=sys.modules[__name__].__doc__, formatter_class=CustomFormatter
)
group = parser.add_argument_group("foobar settings")
group.add_argument(
"-d",
"--debug",
action="store_true",
default=False,
help="Log activity in console",
)
group.add_argument(
"-f",
"--foo",
action="store_true",
dest="foo",
help="Using foo",
)
group.add_argument(
"-b",
"--bar",
const="BAR",
help="Using bar",
metavar="BAR",
nargs="?",
type=str,
)
if len(sys.argv) == 1:
parser.print_help(sys.stderr)
sys.exit(1)
return parser.parse_args(args)
def i_am_bar(option):
"""Print a variable string.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> i_am_bar("FOOBAR")
'I am FOOBAR'
>>> i_am_bar()
Traceback (most recent call last):
...
TypeError: i_am_bar() missing 1 required positional argument: 'option'
"""
return f"I am {str(option)}"
def i_am_foo():
"""Print a constant string.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> i_am_foo()
'I am foo'
>>> i_am_foo("FOO")
Traceback (most recent call last):
...
TypeError: i_am_foo() takes 0 positional arguments but 1 was given
"""
return "I am foo"
def main():
"""CLI function, options passed as arguments.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> var = 1
>>> var + 1
2
"""
pargs = parse_args()
setup_logging(pargs)
if pargs.foo:
logger.info(i_am_foo())
elif pargs.bar:
logger.info(i_am_bar(pargs.bar))
if pargs.debug and pargs:
logger.debug(pargs)
if __name__ == "__main__":
import doctest
# When running on GitLab CI, a doctest error raised an error
doctest.testmod(raise_on_error=environ.get("CI", False))
sys.exit(main())