17757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch"""Command-line support for Coverage."""
27757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
37757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochimport optparse, re, sys, traceback
47757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
57757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochfrom coverage.backward import sorted                # pylint: disable=W0622
67757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochfrom coverage.execfile import run_python_file, run_python_module
77757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochfrom coverage.misc import CoverageException, ExceptionDuringRun, NoSource
87757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
97757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass Opts(object):
117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """A namespace class for individual options we'll build parsers from."""
127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    append = optparse.make_option(
147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-a', '--append', action='store_false', dest="erase_first",
157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Append coverage data to .coverage, otherwise it is started "
167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "clean with each run."
177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    branch = optparse.make_option(
197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--branch', action='store_true',
207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Measure branch coverage in addition to statement coverage."
217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    directory = optparse.make_option(
237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-d', '--directory', action='store',
247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        metavar="DIR",
257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Write the output files to DIR."
267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    help = optparse.make_option(
287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-h', '--help', action='store_true',
297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Get help on this command."
307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ignore_errors = optparse.make_option(
327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-i', '--ignore-errors', action='store_true',
337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Ignore errors while reading source files."
347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    include = optparse.make_option(
367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--include', action='store',
377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        metavar="PAT1,PAT2,...",
387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Include files only when their filename path matches one of "
397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "these patterns.  Usually needs quoting on the command line."
407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    pylib = optparse.make_option(
427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-L', '--pylib', action='store_true',
437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Measure coverage even inside the Python installed library, "
447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "which isn't done by default."
457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    show_missing = optparse.make_option(
477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-m', '--show-missing', action='store_true',
487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Show line numbers of statements in each module that weren't "
497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "executed."
507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    old_omit = optparse.make_option(
527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-o', '--omit', action='store',
537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        metavar="PAT1,PAT2,...",
547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Omit files when their filename matches one of these patterns. "
557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "Usually needs quoting on the command line."
567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    omit = optparse.make_option(
587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--omit', action='store',
597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        metavar="PAT1,PAT2,...",
607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Omit files when their filename matches one of these patterns. "
617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "Usually needs quoting on the command line."
627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    output_xml = optparse.make_option(
647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-o', '', action='store', dest="outfile",
657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        metavar="OUTFILE",
667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Write the XML report to this file. Defaults to 'coverage.xml'"
677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    parallel_mode = optparse.make_option(
697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-p', '--parallel-mode', action='store_true',
707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Append the machine name, process id and random number to the "
717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                ".coverage data file name to simplify collecting data from "
727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "many processes."
737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    module = optparse.make_option(
757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '-m', '--module', action='store_true',
767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="<pyfile> is an importable Python module, not a script path, "
777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "to be run as 'python -m' would run it."
787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    rcfile = optparse.make_option(
807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--rcfile', action='store',
817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Specify configuration file.  Defaults to '.coveragerc'"
827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    source = optparse.make_option(
847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--source', action='store', metavar="SRC1,SRC2,...",
857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="A list of packages or directories of code to be measured."
867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    timid = optparse.make_option(
887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--timid', action='store_true',
897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Use a simpler but slower trace method.  Try this if you get "
907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "seemingly impossible results!"
917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    version = optparse.make_option(
937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        '', '--version', action='store_true',
947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        help="Display version information and exit."
957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass CoverageOptionParser(optparse.OptionParser, object):
997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """Base OptionParser for coverage.
1007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Problems don't exit the program.
1027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Defaults are initialized for all options.
1037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """
1057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def __init__(self, *args, **kwargs):
1077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        super(CoverageOptionParser, self).__init__(
1087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            add_help_option=False, *args, **kwargs
1097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
1107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.set_defaults(
1117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            actions=[],
1127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            branch=None,
1137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            directory=None,
1147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            help=None,
1157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ignore_errors=None,
1167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            include=None,
1177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            omit=None,
1187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            parallel_mode=None,
1197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            module=None,
1207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            pylib=None,
1217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            rcfile=True,
1227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            show_missing=None,
1237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            source=None,
1247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            timid=None,
1257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            erase_first=None,
1267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            version=None,
1277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
1287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.disable_interspersed_args()
1307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.help_fn = self.help_noop
1317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def help_noop(self, error=None, topic=None, parser=None):
1337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """No-op help function."""
1347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        pass
1357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    class OptionParserError(Exception):
1377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Used to stop the optparse error handler ending the process."""
1387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        pass
1397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def parse_args(self, args=None, options=None):
1417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Call optparse.parse_args, but return a triple:
1427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        (ok, options, args)
1447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """
1467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        try:
1477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            options, args = \
1487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                super(CoverageOptionParser, self).parse_args(args, options)
1497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        except self.OptionParserError:
1507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return False, None, None
1517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return True, options, args
1527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def error(self, msg):
1547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Override optparse.error so sys.exit doesn't get called."""
1557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.help_fn(msg)
1567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        raise self.OptionParserError
1577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass ClassicOptionParser(CoverageOptionParser):
1607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """Command-line parser for coverage.py classic arguments."""
1617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def __init__(self):
1637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        super(ClassicOptionParser, self).__init__()
1647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-a', '--annotate', 'annotate')
1667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-b', '--html', 'html')
1677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-c', '--combine', 'combine')
1687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-e', '--erase', 'erase')
1697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-r', '--report', 'report')
1707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_action('-x', '--execute', 'execute')
1717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.add_options([
1737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.directory,
1747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.help,
1757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.ignore_errors,
1767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.pylib,
1777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.show_missing,
1787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.old_omit,
1797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.parallel_mode,
1807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.timid,
1817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.version,
1827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ])
1837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def add_action(self, dash, dashdash, action_code):
1857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Add a specialized option that is the action to execute."""
1867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        option = self.add_option(dash, dashdash, action='callback',
1877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            callback=self._append_action
1887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
1897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        option.action_code = action_code
1907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def _append_action(self, option, opt_unused, value_unused, parser):
1927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Callback for an option that adds to the `actions` list."""
1937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        parser.values.actions.append(option.action_code)
1947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass CmdOptionParser(CoverageOptionParser):
1977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """Parse one of the new-style commands for coverage.py."""
1987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
1997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def __init__(self, action, options=None, defaults=None, usage=None,
2007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                cmd=None, description=None
2017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                ):
2027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Create an OptionParser for a coverage command.
2037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `action` is the slug to put into `options.actions`.
2057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `options` is a list of Option's for the command.
2067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `defaults` is a dict of default value for options.
2077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `usage` is the usage string to display in help.
2087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `cmd` is the command name, if different than `action`.
2097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `description` is the description of the command, for the help text.
2107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """
2127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if usage:
2137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            usage = "%prog " + usage
2147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        super(CmdOptionParser, self).__init__(
2157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            prog="coverage %s" % (cmd or action),
2167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            usage=usage,
2177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            description=description,
2187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        )
2197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.set_defaults(actions=[action], **(defaults or {}))
2207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if options:
2217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.add_options(options)
2227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.cmd = cmd or action
2237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def __eq__(self, other):
2257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # A convenience equality, so that I can put strings in unit test
2267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # results, and they will compare equal to objects.
2277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return (other == "<CmdOptionParser:%s>" % self.cmd)
2287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochGLOBAL_ARGS = [
2307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Opts.rcfile,
2317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Opts.help,
2327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ]
2337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCMDS = {
2357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'annotate': CmdOptionParser("annotate",
2367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        [
2377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.directory,
2387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.ignore_errors,
2397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.omit,
2407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.include,
2417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ] + GLOBAL_ARGS,
2427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[options] [modules]",
2437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Make annotated copies of the given files, marking "
2447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "statements that are executed with > and statements that are "
2457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "missed with !."
2467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'combine': CmdOptionParser("combine", GLOBAL_ARGS,
2497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = " ",
2507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Combine data from multiple coverage files collected "
2517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "with 'run -p'.  The combined results are written to a single "
2527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "file representing the union of the data."
2537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'debug': CmdOptionParser("debug", GLOBAL_ARGS,
2567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "<topic>",
2577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Display information on the internals of coverage.py, "
2587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "for diagnosing problems. "
2597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "Topics are 'data' to show a summary of the collected data, "
2607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "or 'sys' to show installation information."
2617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'erase': CmdOptionParser("erase", GLOBAL_ARGS,
2647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = " ",
2657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Erase previously collected coverage data."
2667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'help': CmdOptionParser("help", GLOBAL_ARGS,
2697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[command]",
2707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Describe how to use coverage.py"
2717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'html': CmdOptionParser("html",
2747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        [
2757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.directory,
2767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.ignore_errors,
2777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.omit,
2787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.include,
2797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ] + GLOBAL_ARGS,
2807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[options] [modules]",
2817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Create an HTML report of the coverage of the files.  "
2827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "Each file gets its own page, with the source decorated to show "
2837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "executed, excluded, and missed lines."
2847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'report': CmdOptionParser("report",
2877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        [
2887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.ignore_errors,
2897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.omit,
2907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.include,
2917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.show_missing,
2927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ] + GLOBAL_ARGS,
2937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[options] [modules]",
2947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Report coverage statistics on modules."
2957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
2967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'run': CmdOptionParser("execute",
2987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        [
2997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.append,
3007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.branch,
3017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.pylib,
3027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.parallel_mode,
3037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.module,
3047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.timid,
3057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.source,
3067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.omit,
3077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.include,
3087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ] + GLOBAL_ARGS,
3097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        defaults = {'erase_first': True},
3107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        cmd = "run",
3117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[options] <pyfile> [program options]",
3127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Run a Python program, measuring code execution."
3137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
3147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    'xml': CmdOptionParser("xml",
3167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        [
3177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.ignore_errors,
3187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.omit,
3197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.include,
3207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            Opts.output_xml,
3217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ] + GLOBAL_ARGS,
3227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        cmd = "xml",
3237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        defaults = {'outfile': 'coverage.xml'},
3247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        usage = "[options] [modules]",
3257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        description = "Generate an XML report of coverage results."
3267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ),
3277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
3287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochOK, ERR = 0, 1
3317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochclass CoverageScript(object):
3347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """The command-line interface to Coverage."""
3357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def __init__(self, _covpkg=None, _run_python_file=None,
3377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                 _run_python_module=None, _help_fn=None):
3387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # _covpkg is for dependency injection, so we can test this code.
3397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if _covpkg:
3407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.covpkg = _covpkg
3417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
3427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            import coverage
3437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.covpkg = coverage
3447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # For dependency injection:
3467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.run_python_file = _run_python_file or run_python_file
3477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.run_python_module = _run_python_module or run_python_module
3487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.help_fn = _help_fn or self.help
3497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.coverage = None
3517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def help(self, error=None, topic=None, parser=None):
3537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """Display an error message, or the named topic."""
3547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        assert error or topic or parser
3557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if error:
3567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            print(error)
3577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            print("Use 'coverage help' for help.")
3587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        elif parser:
3597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            print(parser.format_help().strip())
3607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
3617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            # Parse out the topic we want from HELP_TOPICS
3627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            topic_list = re.split("(?m)^=+ (\w+) =+$", HELP_TOPICS)
3637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            topics = dict(zip(topic_list[1::2], topic_list[2::2]))
3647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            help_msg = topics.get(topic, '').strip()
3657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            if help_msg:
3667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                print(help_msg % self.covpkg.__dict__)
3677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            else:
3687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                print("Don't know topic %r" % topic)
3697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    def command_line(self, argv):
3717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """The bulk of the command line interface to Coverage.
3727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        `argv` is the argument list to process.
3747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        Returns 0 if all is well, 1 if something went wrong.
3767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        """
3787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Collect the command-line options.
3797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if not argv:
3817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.help_fn(topic='minimum_help')
3827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return OK
3837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # The command syntax we parse depends on the first argument.  Classic
3857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # syntax always starts with an option.
3867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        classic = argv[0].startswith('-')
3877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if classic:
3887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            parser = ClassicOptionParser()
3897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
3907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            parser = CMDS.get(argv[0])
3917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            if not parser:
3927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                self.help_fn("Unknown command: '%s'" % argv[0])
3937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                return ERR
3947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            argv = argv[1:]
3957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
3967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        parser.help_fn = self.help_fn
3977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        ok, options, args = parser.parse_args(argv)
3987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if not ok:
3997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return ERR
4007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Handle help.
4027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if options.help:
4037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            if classic:
4047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                self.help_fn(topic='help')
4057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            else:
4067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                self.help_fn(parser=parser)
4077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return OK
4087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if "help" in options.actions:
4107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            if args:
4117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                for a in args:
4127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    parser = CMDS.get(a)
4137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    if parser:
4147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        self.help_fn(parser=parser)
4157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    else:
4167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        self.help_fn(topic=a)
4177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            else:
4187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                self.help_fn(topic='help')
4197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return OK
4207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Handle version.
4227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if options.version:
4237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.help_fn(topic='version')
4247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return OK
4257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Check for conflicts and problems in the options.
4277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        for i in ['erase', 'execute']:
4287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            for j in ['annotate', 'html', 'report', 'combine']:
4297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                if (i in options.actions) and (j in options.actions):
4307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    self.help_fn("You can't specify the '%s' and '%s' "
4317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                              "options at the same time." % (i, j))
4327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    return ERR
4337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if not options.actions:
4357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.help_fn(
4367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                "You must specify at least one of -e, -x, -c, -r, -a, or -b."
4377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                )
4387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return ERR
4397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        args_allowed = (
4407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'execute' in options.actions or
4417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'annotate' in options.actions or
4427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'html' in options.actions or
4437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'debug' in options.actions or
4447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'report' in options.actions or
4457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            'xml' in options.actions
4467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
4477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if not args_allowed and args:
4487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.help_fn("Unexpected arguments: %s" % " ".join(args))
4497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return ERR
4507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'execute' in options.actions and not args:
4527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.help_fn("Nothing to do.")
4537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return ERR
4547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Listify the list options.
4567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        source = unshell_list(options.source)
4577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        omit = unshell_list(options.omit)
4587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        include = unshell_list(options.include)
4597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Do something.
4617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        self.coverage = self.covpkg.coverage(
4627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            data_suffix = options.parallel_mode,
4637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            cover_pylib = options.pylib,
4647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            timid = options.timid,
4657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            branch = options.branch,
4667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            config_file = options.rcfile,
4677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            source = source,
4687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            omit = omit,
4697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            include = include,
4707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
4717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
4727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'debug' in options.actions:
4737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            if not args:
4747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                self.help_fn("What information would you like: data, sys?")
4757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                return ERR
4767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            for info in args:
4777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                if info == 'sys':
4787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    print("-- sys ----------------------------------------")
4797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    for label, info in self.coverage.sysinfo():
4807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        if info == []:
4817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            info = "-none-"
4827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        if isinstance(info, list):
4837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            print("%15s:" % label)
4847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            for e in info:
4857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                                print("%15s  %s" % ("", e))
4867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        else:
4877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            print("%15s: %s" % (label, info))
4887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                elif info == 'data':
4897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    print("-- data ---------------------------------------")
4907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    self.coverage.load()
4917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    print("path: %s" % self.coverage.data.filename)
4927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    print("has_arcs: %r" % self.coverage.data.has_arcs())
4937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    summary = self.coverage.data.summary(fullpath=True)
4947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    if summary:
4957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        filenames = sorted(summary.keys())
4967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        print("\n%d files:" % len(filenames))
4977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        for f in filenames:
4987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                            print("%s: %d lines" % (f, summary[f]))
4997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    else:
5007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        print("No data collected")
5017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                else:
5027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    self.help_fn("Don't know what you mean by %r" % info)
5037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    return ERR
5047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            return OK
5057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'erase' in options.actions or options.erase_first:
5077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.erase()
5087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
5097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.load()
5107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'execute' in options.actions:
5127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            # Run the script.
5137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.start()
5147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            code_ran = True
5157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            try:
5167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                try:
5177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    if options.module:
5187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        self.run_python_module(args[0], args)
5197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    else:
5207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                        self.run_python_file(args[0], args)
5217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                except NoSource:
5227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    code_ran = False
5237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    raise
5247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            finally:
5257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                if code_ran:
5267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    self.coverage.stop()
5277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                    self.coverage.save()
5287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'combine' in options.actions:
5307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.combine()
5317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.save()
5327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # Remaining actions are reporting, with some common options.
5347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        report_args = dict(
5357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            morfs = args,
5367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            ignore_errors = options.ignore_errors,
5377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            omit = omit,
5387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            include = include,
5397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            )
5407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'report' in options.actions:
5427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.report(
5437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                show_missing=options.show_missing, **report_args)
5447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'annotate' in options.actions:
5457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.annotate(
5467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                directory=options.directory, **report_args)
5477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'html' in options.actions:
5487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.html_report(
5497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch                directory=options.directory, **report_args)
5507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if 'xml' in options.actions:
5517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            outfile = options.outfile
5527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            self.coverage.xml_report(outfile=outfile, **report_args)
5537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return OK
5557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochdef unshell_list(s):
5587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """Turn a command-line argument into a list."""
5597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if not s:
5607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return None
5617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if sys.platform == 'win32':
5627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # When running coverage as coverage.exe, some of the behavior
5637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # of the shell is emulated: wildcards are expanded into a list of
5647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # filenames.  So you have to single-quote patterns on the command
5657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # line, but (not) helpfully, the single quotes are included in the
5667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # argument, so we have to strip them off here.
5677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        s = s.strip("'")
5687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    return s.split(',')
5697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochHELP_TOPICS = r"""
5727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch== classic ====================================================================
5747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCoverage.py version %(__version__)s
5757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochMeasure, collect, and report on code coverage in Python programs.
5767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochUsage:
5787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -x [-p] [-L] [--timid] MODULE.py [ARG1 ARG2 ...]
5807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Execute the module, passing the given command-line arguments, collecting
5817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    coverage data.  With the -p option, include the machine name and process
5827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    id in the .coverage file name.  With -L, measure coverage even inside the
5837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Python installed library, which isn't done by default.  With --timid, use a
5847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    simpler but slower trace method.
5857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -e
5877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Erase collected coverage data.
5887757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5897757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -c
5907757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Combine data from multiple coverage files (as created by -p option above)
5917757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    and store it into a single file representing the union of the coverage.
5927757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5937757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -r [-m] [-i] [-o DIR,...] [FILE1 FILE2 ...]
5947757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Report on the statement coverage for the given files.  With the -m
5957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    option, show line numbers of the statements that weren't executed.
5967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
5977757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -b -d DIR [-i] [-o DIR,...] [FILE1 FILE2 ...]
5987757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Create an HTML report of the coverage of the given files.  Each file gets
5997757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    its own page, with the file listing decorated to show executed, excluded,
6007757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    and missed lines.
6017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6027757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochcoverage -a [-d DIR] [-i] [-o DIR,...] [FILE1 FILE2 ...]
6037757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Make annotated copies of the given files, marking statements that
6047757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    are executed with > and statements that are missed with !.
6057757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch-d DIR
6077757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Write output files for -b or -a to this directory.
6087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch-i  Ignore errors while reporting or annotating.
6107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch-o DIR,...
6127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    Omit reporting or annotating files when their filename path starts with
6137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    a directory listed in the omit list.
6147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    e.g. coverage -i -r -o c:\python25,lib\enthought\traits
6157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCoverage data is saved in the file .coverage by default.  Set the
6177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCOVERAGE_FILE environment variable to save it somewhere else.
6187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch== help =======================================================================
6207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCoverage.py, version %(__version__)s
6217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochMeasure, collect, and report on code coverage in Python programs.
6227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochusage: coverage <command> [options] [args]
6247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCommands:
6267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    annotate    Annotate source files with execution information.
6277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    combine     Combine a number of data files.
6287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    erase       Erase previously collected coverage data.
6297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    help        Get help on using coverage.py.
6307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    html        Create an HTML report.
6317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    report      Report coverage stats on modules.
6327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    run         Run a Python program and measure code execution.
6337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    xml         Create an XML report of coverage results.
6347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochUse "coverage help <command>" for detailed help on any command.
6367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochUse "coverage help classic" for help on older command syntax.
6377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochFor more information, see %(__url__)s
6387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch== minimum_help ===============================================================
6407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCode coverage for Python.  Use 'coverage help' for help.
6417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch== version ====================================================================
6437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochCoverage.py, version %(__version__)s.  %(__url__)s
6447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch"""
6467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochdef main(argv=None):
6497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """The main entrypoint to Coverage.
6507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    This is installed as the script entrypoint.
6527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
6537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    """
6547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if argv is None:
6557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        argv = sys.argv[1:]
6567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    try:
6577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        status = CoverageScript().command_line(argv)
6587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    except ExceptionDuringRun:
6597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # An exception was caught while running the product code.  The
6607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # sys.exc_info() return tuple is packed into an ExceptionDuringRun
6617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # exception.
6627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        _, err, _ = sys.exc_info()
6637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        traceback.print_exception(*err.args)
6647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        status = ERR
6657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    except CoverageException:
6667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # A controlled error inside coverage.py: print the message to the user.
6677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        _, err, _ = sys.exc_info()
6687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        print(err)
6697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        status = ERR
6707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    except SystemExit:
6717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        # The user called `sys.exit()`.  Exit with their argument, if any.
6727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        _, err, _ = sys.exc_info()
6737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if err.args:
6747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            status = err.args[0]
6757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
6767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            status = None
6777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    return status
678