1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #!/usr/bin/env python3
- # Copyright 2023 The ChromiumOS Authors
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """
- Provides a framework for command line interfaces based on argh.
- It automatically adds common arguments, such as -v, -vv and --color to provide consistent
- behavior.
- """
- import argparse
- import sys
- import traceback
- from typing import (
- Any,
- Callable,
- Optional,
- )
- from .util import (
- add_common_args,
- parse_common_args,
- print_timing_info,
- record_time,
- verbose,
- ensure_packages_exist,
- )
- ensure_packages_exist("argh")
- import argh # type: ignore
- # Hack: argh does not support type annotations. This prevents type errors.
- argh: Any # type: ignore
- def run_main(main_fn: Callable[..., Any], usage: Optional[str] = None):
- run_commands(default_fn=main_fn, usage=usage)
- def run_commands(
- *functions: Callable[..., Any],
- default_fn: Optional[Callable[..., Any]] = None,
- usage: Optional[str] = None,
- ):
- """
- Allow the user to call the provided functions with command line arguments translated to
- function arguments via argh: https://pythonhosted.org/argh
- """
- exit_code = 0
- try:
- parser = argparse.ArgumentParser(
- description=usage,
- # Docstrings are used as the description in argparse, preserve their formatting.
- formatter_class=argparse.RawDescriptionHelpFormatter,
- # Do not allow implied abbreviations. Abbreviations should be manually specified.
- allow_abbrev=False,
- )
- add_common_args(parser)
- # Add provided commands to parser. Do not use sub-commands if we just got one function.
- if functions:
- argh.add_commands(parser, functions) # type: ignore
- if default_fn:
- argh.set_default_command(parser, default_fn) # type: ignore
- with record_time("Total Time"):
- # Call main method
- argh.dispatch(parser) # type: ignore
- except Exception as e:
- if verbose():
- traceback.print_exc()
- else:
- print(e)
- exit_code = 1
- if parse_common_args().timing_info:
- print_timing_info()
- sys.exit(exit_code)
- if __name__ == "__main__":
- import doctest
- (failures, num_tests) = doctest.testmod(optionflags=doctest.ELLIPSIS)
- sys.exit(1 if failures > 0 else 0)
|