Skip to content

Instantly share code, notes, and snippets.

@elmotec
Last active December 1, 2021 17:14
Show Gist options
  • Select an option

  • Save elmotec/6008118 to your computer and use it in GitHub Desktop.

Select an option

Save elmotec/6008118 to your computer and use it in GitHub Desktop.

Revisions

  1. elmotec revised this gist Jun 4, 2021. 1 changed file with 19 additions and 12 deletions.
    31 changes: 19 additions & 12 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@
    import click.testing


    module = sys.modules['__main__'].__file__
    module = sys.modules["__main__"].__file__
    log = logging.getLogger(module)


    @@ -23,8 +23,12 @@ def process(filename, output):

    @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(
    "--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"""
    @@ -37,8 +41,8 @@ def main(files, output, verbose):
    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)))
    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:
    @@ -47,12 +51,15 @@ def main(files, output, verbose):


    if __name__ == "__main__":
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
    format='%(name)s (%(levelname)s): %(message)s')
    logging.basicConfig(
    stream=sys.stderr,
    level=logging.DEBUG,
    format="%(name)s (%(levelname)s): %(message)s",
    )
    try:
    main()
    except KeyboardInterrupt:
    log.info(f'{module} interrupted!')
    log.info("%s interrupted", module)
    finally:
    logging.shutdown()

    @@ -65,22 +72,22 @@ def setUp(self):

    def test_offers_help_for_invalid_option(self):
    """Shows usage when the option is not valid"""
    result = self.runner.invoke(main, ['--invalid'])
    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'])
    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.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.runner.invoke(main, ["-vv"])
    self.assertEqual(log.getEffectiveLevel(), logging.DEBUG)
  2. elmotec revised this gist Jun 4, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ def process(filename, output):
    @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"""
    log.setLevel(max(3 - verbose, 0) * 10)
    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
  3. elmotec revised this gist Oct 17, 2020. 1 changed file with 70 additions and 37 deletions.
    107 changes: 70 additions & 37 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -1,53 +1,86 @@
    #!/usr/bin/env python
    # encoding: utf-8
    #!python

    """See main.__doc__"""

    """Minimal python commad line."""

    import sys
    import argparse
    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 parse_command_line(argv):
    """Parse command line argument. See -h option
    :param argv: arguments on the command line must include caller file name.
    """
    formatter_class = argparse.RawDescriptionHelpFormatter
    parser = argparse.ArgumentParser(description=module,
    formatter_class=formatter_class)
    parser.add_argument("--version", action="version",
    version="%(prog)s {}".format(__version__))
    parser.add_argument("-v", "--verbose", dest="verbose_count",
    action="count", default=0,
    help="increases log verbosity for each occurence.")
    parser.add_argument('-o', metavar="output",
    type=argparse.FileType('w'), default=sys.stdout,
    help="redirect output to a file")
    parser.add_argument('input', metavar="input", nargs='+',
    argparse.REMAINDER, help="input if any...")
    arguments = parser.parse_args(argv[1:])
    # Sets log level to WARN going more verbose for each new -v.
    log.setLevel(max(3 - arguments.verbose_count, 0) * 10)
    return arguments


    def main():
    """Main program. Sets up logging and do some work."""
    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"""
    log.setLevel(max(3 - verbose, 0) * 10)
    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:
    arguments = parse_command_line(sys.argv)
    # Do something with arguments.
    main()
    except KeyboardInterrupt:
    log.error('Program interrupted!')
    log.info(f'{module} interrupted!')
    finally:
    logging.shutdown()

    if __name__ == "__main__":
    sys.exit(main())

    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)
  4. elmotec revised this gist May 24, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,7 @@ def parse_command_line(argv):
    def main():
    """Main program. Sets up logging and do some work."""
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
    format='%(name)s (%(levelname)s): %(message)s'))
    format='%(name)s (%(levelname)s): %(message)s')
    try:
    arguments = parse_command_line(sys.argv)
    # Do something with arguments.
  5. elmotec revised this gist May 24, 2015. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -29,9 +29,8 @@ def parse_command_line(argv):
    parser.add_argument('-o', metavar="output",
    type=argparse.FileType('w'), default=sys.stdout,
    help="redirect output to a file")
    #parser.add_argument('input', metavar="input",
    ## nargs='+', # argparse.REMAINDER,
    #help="input if any...")
    parser.add_argument('input', metavar="input", nargs='+',
    argparse.REMAINDER, help="input if any...")
    arguments = parser.parse_args(argv[1:])
    # Sets log level to WARN going more verbose for each new -v.
    log.setLevel(max(3 - arguments.verbose_count, 0) * 10)
  6. elmotec revised this gist Nov 16, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -45,6 +45,8 @@ def main():
    try:
    arguments = parse_command_line(sys.argv)
    # Do something with arguments.
    except KeyboardInterrupt:
    log.error('Program interrupted!')
    finally:
    logging.shutdown()

  7. elmotec revised this gist Nov 25, 2013. 1 changed file with 8 additions and 11 deletions.
    19 changes: 8 additions & 11 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,8 @@
    #!/usr/bin/env python
    # encoding: utf-8

    """Minimal python commad line."""

    __version__ = "1.0"

    """Minimal python commad line."""

    import sys
    import argparse
    @@ -15,32 +14,32 @@


    def parse_command_line(argv):
    """Parses command line argument. See -h option
    """Parse command line argument. See -h option
    Arguments:
    argv: arguments on the command line must include caller file name.
    :param argv: arguments on the command line must include caller file name.
    """
    formatter_class = argparse.RawDescriptionHelpFormatter
    parser = argparse.ArgumentParser(description=module,
    formatter_class=formatter_class)
    parser.add_argument("--version", action="version",
    version="%(prog)s {}".format(__version__))
    version="%(prog)s {}".format(__version__))
    parser.add_argument("-v", "--verbose", dest="verbose_count",
    action="count", default=0,
    help="increases log verbosity for each occurence.")
    parser.add_argument('-o', metavar="output",
    type=argparse.FileType('w'), default=sys.stdout,
    help="redirect output to a file")
    #parser.add_argument('input', metavar="input",
    ## nargs='+', # argparse.REMAINDER,
    #help="input if any...")
    ## nargs='+', # argparse.REMAINDER,
    #help="input if any...")
    arguments = parser.parse_args(argv[1:])
    # Sets log level to WARN going more verbose for each new -v.
    log.setLevel(max(3 - arguments.verbose_count, 0) * 10)
    return arguments


    def main():
    """Main program. Sets up logging and do some work."""
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
    format='%(name)s (%(levelname)s): %(message)s'))
    try:
    @@ -49,7 +48,5 @@ def main():
    finally:
    logging.shutdown()


    if __name__ == "__main__":
    sys.exit(main())

  8. elmotec revised this gist Jul 17, 2013. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -17,10 +17,9 @@
    def parse_command_line(argv):
    """Parses command line argument. See -h option
    Arguments:
    argv: arguments on the command line must include caller file name.
    """
    module = argv[0]
    Arguments:
    argv: arguments on the command line must include caller file name.
    """
    formatter_class = argparse.RawDescriptionHelpFormatter
    parser = argparse.ArgumentParser(description=module,
    formatter_class=formatter_class)
  9. elmotec revised this gist Jul 17, 2013. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions bootstrap_cmdline.py
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,8 @@
    import logging


    log = logging.getLogger(__name__)
    module = sys.modules['__main__'].__file__
    log = logging.getLogger(module)


    def parse_command_line(argv):
    @@ -41,7 +42,8 @@ def parse_command_line(argv):


    def main():
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
    format='%(name)s (%(levelname)s): %(message)s'))
    try:
    arguments = parse_command_line(sys.argv)
    # Do something with arguments.
  10. elmotec renamed this gist Jul 16, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  11. elmotec created this gist Jul 16, 2013.
    54 changes: 54 additions & 0 deletions bootstrap_python.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    #!/usr/bin/env python

    """Minimal python commad line."""

    __version__ = "1.0"


    import sys
    import argparse
    import logging


    log = logging.getLogger(__name__)


    def parse_command_line(argv):
    """Parses command line argument. See -h option
    Arguments:
    argv: arguments on the command line must include caller file name.
    """
    module = argv[0]
    formatter_class = argparse.RawDescriptionHelpFormatter
    parser = argparse.ArgumentParser(description=module,
    formatter_class=formatter_class)
    parser.add_argument("--version", action="version",
    version="%(prog)s {}".format(__version__))
    parser.add_argument("-v", "--verbose", dest="verbose_count",
    action="count", default=0,
    help="increases log verbosity for each occurence.")
    parser.add_argument('-o', metavar="output",
    type=argparse.FileType('w'), default=sys.stdout,
    help="redirect output to a file")
    #parser.add_argument('input', metavar="input",
    ## nargs='+', # argparse.REMAINDER,
    #help="input if any...")
    arguments = parser.parse_args(argv[1:])
    # Sets log level to WARN going more verbose for each new -v.
    log.setLevel(max(3 - arguments.verbose_count, 0) * 10)
    return arguments


    def main():
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
    try:
    arguments = parse_command_line(sys.argv)
    # Do something with arguments.
    finally:
    logging.shutdown()


    if __name__ == "__main__":
    sys.exit(main())