mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
11a48d4cca
This is a refactoring with no functionality change. The common.py file is split up so we will be able to use the parts that have no third party dependencies separately. For now, keep common.py and re-export everything, so we do not introduce issues in other tools. BUG=b:267499599 TEST=presubmit Change-Id: Idf6d45bd90f5cf448fb9dd88df540af3da0f7f88 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4482141 Reviewed-by: Zihan Chen <zihanchen@google.com> Commit-Queue: Dennis Kempin <denniskempin@google.com>
89 lines
2.4 KiB
Python
89 lines
2.4 KiB
Python
#!/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)
|