|
#!python |
|
|
|
"""See main.__doc__""" |
|
|
|
import os |
|
import logging |
|
import glob |
|
import unittest |
|
import sys |
|
|
|
import click |
|
import click.testing |
|
|
|
|
|
module = sys.modules["__main__"].__file__ |
|
log = logging.getLogger(module) |
|
|
|
|
|
def process(filename, output): |
|
"""Do something more useful that printing out the file name""" |
|
print(filename) |
|
|
|
|
|
@click.command() |
|
@click.argument("files", nargs=-1) |
|
@click.option( |
|
"--output", |
|
help="output directory where to write to", |
|
default=os.getenv("TEMP"), |
|
type=click.Path(), |
|
) |
|
@click.option("--verbose", "-v", help="increases verbosity", count=True) |
|
def main(files, output, verbose): |
|
"""This help line will show in the command line --help output""" |
|
logging.root.setLevel(max(3 - verbose, 0) * 10) # impact all loggers |
|
log.debug("log level: %s", log.getEffectiveLevel()) |
|
log.debug("output: %s", output) |
|
# credit https://stackoverflow.com/questions/48604754 |
|
all_files = [] |
|
for argument in files: |
|
log.debug("processing argument %s ...", argument) |
|
# if our shell does not do filename globbing |
|
expanded = list(glob.glob(argument)) |
|
if len(expanded) == 0 and "*" not in argument: |
|
raise (click.BadParameter("{}: file not found".format(argument))) |
|
all_files.extend(expanded) |
|
# Actual processing of the files. |
|
for filename in all_files: |
|
log.info("processing file %s ...", filename) |
|
process(filename, output) |
|
|
|
|
|
if __name__ == "__main__": |
|
logging.basicConfig( |
|
stream=sys.stderr, |
|
level=logging.DEBUG, |
|
format="%(name)s (%(levelname)s): %(message)s", |
|
) |
|
try: |
|
main() |
|
except KeyboardInterrupt: |
|
log.info("%s interrupted", module) |
|
finally: |
|
logging.shutdown() |
|
|
|
|
|
class BasicCommandLineTest(unittest.TestCase): |
|
"""Tests can be run with python -m unittest <script>""" |
|
|
|
def setUp(self): |
|
self.runner = click.testing.CliRunner() |
|
|
|
def test_offers_help_for_invalid_option(self): |
|
"""Shows usage when the option is not valid""" |
|
result = self.runner.invoke(main, ["--invalid"]) |
|
self.assertEqual(result.exit_code, 2) |
|
self.assertRegex(result.output, r"Try.*--help") |
|
|
|
def test_shows_help(self): |
|
"""Makes sure the help is available.""" |
|
result = self.runner.invoke(main, ["--help"]) |
|
self.assertEqual(result.exit_code, 0) |
|
self.assertRegex(result.output, r"Usage: ") |
|
|
|
def test_one_v_for_info_level_logging(self): |
|
"""-v sets logging to info.""" |
|
_ = self.runner.invoke(main, ["-v"]) |
|
self.assertEqual(log.getEffectiveLevel(), logging.INFO) |
|
|
|
def test_two_v_for_info_level_logging(self): |
|
"""-vv sets logging to debug.""" |
|
_ = self.runner.invoke(main, ["-vv"]) |
|
self.assertEqual(log.getEffectiveLevel(), logging.DEBUG) |
The getopt module is deprecated, I'd suggest learning the new argparse module.