148 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~ ~ ~~ ~ ~~3#4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5# See https://llvm.org/LICENSE.txt for license information.6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7"""Base class for all subtools."""8 9import abc10import os11import tempfile12 13from dex import __version__14from dex.utils import ExtArgParse15from dex.utils import PrettyOutput16from dex.utils.ReturnCode import ReturnCode17 18 19class ToolBase(object, metaclass=abc.ABCMeta):20 def __init__(self, context):21 self.context = context22 self.parser = None23 24 @abc.abstractproperty25 def name(self):26 pass27 28 @abc.abstractmethod29 def add_tool_arguments(self, parser, defaults):30 pass31 32 def parse_command_line(self, args):33 """Define two parsers: pparser and self.parser.34 pparser deals with args that need to be parsed prior to any of those of35 self.parser. For example, any args which may affect the state of36 argparse error output.37 """38 39 class defaults(object):40 pass41 42 pparser = ExtArgParse.ExtArgumentParser(43 self.context, add_help=False, prog=self.name44 )45 46 pparser.add_argument(47 "--no-color-output",48 action="store_true",49 default=False,50 help="do not use colored output on stdout/stderr",51 )52 pparser.add_argument(53 "--time-report",54 action="store_true",55 default=False,56 help="display timing statistics",57 )58 59 self.parser = ExtArgParse.ExtArgumentParser(60 self.context, parents=[pparser], prog=self.name61 )62 self.parser.add_argument(63 "-v",64 "--verbose",65 action="store_true",66 default=False,67 help="enable verbose output (overrides --no-warnings)",68 )69 self.parser.add_argument(70 "-V",71 "--version",72 action="store_true",73 default=False,74 help="display the DExTer version and exit",75 )76 self.parser.add_argument(77 "-w",78 "--no-warnings",79 action="store_true",80 default=False,81 help="suppress warning output",82 )83 self.parser.add_argument(84 "--unittest",85 type=str,86 choices=["off", "show-failures", "show-all"],87 default="off",88 help="run the DExTer codebase unit tests",89 )90 91 suppress = ExtArgParse.SUPPRESS # pylint: disable=no-member92 self.parser.add_argument(93 "--colortest", action="store_true", default=False, help=suppress94 )95 self.parser.add_argument(96 "--error-debug", action="store_true", default=False, help=suppress97 )98 defaults.working_directory = os.path.join(tempfile.gettempdir(), "dexter")99 self.parser.add_argument(100 "--indent-timer-level", type=int, default=1, help=suppress101 )102 self.parser.add_argument(103 "--working-directory",104 type=str,105 metavar="<file>",106 default=None,107 display_default=defaults.working_directory,108 help="location of working directory",109 )110 self.parser.add_argument(111 "--save-temps",112 action="store_true",113 default=False,114 help="save temporary files",115 )116 117 self.add_tool_arguments(self.parser, defaults)118 119 # If an error is encountered during pparser, show the full usage text120 # including self.parser options. Strip the preceding 'usage: ' to avoid121 # having it appear twice.122 pparser.usage = self.parser.format_usage().lstrip("usage: ")123 124 options, args = pparser.parse_known_args(args)125 126 if options.no_color_output:127 PrettyOutput.stdout.color_enabled = False128 PrettyOutput.stderr.color_enabled = False129 130 options = self.parser.parse_args(args, namespace=options)131 return options, defaults132 133 def handle_base_options(self, defaults):134 self.handle_options(defaults)135 136 options = self.context.options137 138 if options.working_directory is None:139 options.working_directory = defaults.working_directory140 141 @abc.abstractmethod142 def handle_options(self, defaults):143 pass144 145 @abc.abstractmethod146 def go(self) -> ReturnCode:147 pass148