summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/cmdline.py87
-rw-r--r--test/test_cmdline.py2
2 files changed, 49 insertions, 40 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index f02c9e76..f7f92ee9 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -55,15 +55,44 @@ COVERAGE_FILE environment variable to save it somewhere else.
class OptionParser(optparse.OptionParser, object):
- """Command-line parser for coverage.py."""
+ """A better OptionParser: Problems don't exit the program."""
def __init__(self, help_fn, *args, **kwargs):
super(OptionParser, self).__init__(
add_help_option=False, *args, **kwargs
)
+ self.disable_interspersed_args()
+ self.help_fn = help_fn
+
+ class OptionParserError(Exception):
+ """Used to stop the optparse error handler ending the process."""
+ pass
+
+ def parse_args(self, args=None, options=None):
+ """Call optparse.parse_args, but return a triple:
+
+ (ok, options, args)
+
+ """
+ try:
+ options, args = super(OptionParser, self).parse_args(args, options)
+ except self.OptionParserError:
+ return False, None, None
+ return True, options, args
+
+ def error(self, msg):
+ """Override optparse.error so sys.exit doesn't get called."""
+ self.help_fn(msg)
+ raise self.OptionParserError
+
+
+class ClassicOptionParser(OptionParser):
+ """Command-line parser for coverage.py classic arguments."""
+
+ def __init__(self, help_fn, *args, **kwargs):
+ super(ClassicOptionParser, self).__init__(help_fn, *args, **kwargs)
self.set_defaults(actions=[])
- self.disable_interspersed_args()
self.help_fn = help_fn
@@ -85,40 +114,19 @@ class OptionParser(optparse.OptionParser, object):
def add_action(self, dash, dashdash, action):
"""Add a specialized option that is the action to execute."""
option = self.add_option(dash, dashdash, action='callback',
- callback=self.append_action
+ callback=self._append_action
)
option.action_code = action
- def append_action(self, option, opt_unused, value_unused, parser):
+ def _append_action(self, option, opt_unused, value_unused, parser):
"""Callback for an option that adds to the `actions` list."""
parser.values.actions.append(option.action_code)
- class OptionParserError(Exception):
- """Used to stop the optparse error handler ending the process."""
- pass
-
- def parse_args(self, args=None, options=None):
- """Call optparse.parse_args, but return a triple:
-
- (ok, options, args)
-
- """
- try:
- options, args = super(OptionParser, self).parse_args(args, options)
- except self.OptionParserError:
- return False, None, None
- return True, options, args
-
- def error(self, msg):
- """Override optparse.error so sys.exit doesn't get called."""
- self.help_fn(msg)
- raise self.OptionParserError
-
class CoverageScript:
"""The command-line interface to Coverage."""
- def __init__(self, _covpkg=None, _run_python_file=None):
+ def __init__(self, _covpkg=None, _run_python_file=None, _help_fn=None):
# _covpkg is for dependency injection, so we can test this code.
if _covpkg:
self.covpkg = _covpkg
@@ -129,6 +137,9 @@ class CoverageScript:
# _run_python_file is for dependency injection also.
self.run_python_file = _run_python_file or run_python_file
+ # _help_fn is for dependency injection.
+ self.help_fn = _help_fn or self.help
+
self.coverage = None
def help(self, error=None):
@@ -139,47 +150,45 @@ class CoverageScript:
else:
print USAGE % self.covpkg.__dict__
- def command_line(self, argv, help_fn=None):
+ def command_line(self, argv):
"""The bulk of the command line interface to Coverage.
`argv` is the argument list to process.
- `help_fn` is the help function to use when something goes wrong.
"""
# Collect the command-line options.
- help_fn = help_fn or self.help
OK, ERR = 0, 1
- parser = OptionParser(help_fn)
+ parser = ClassicOptionParser(self.help_fn)
ok, options, args = parser.parse_args(argv)
if not ok:
return ERR
if options.help:
- help_fn()
+ self.help_fn()
return OK
# Check for conflicts and problems in the options.
for i in ['erase', 'execute']:
for j in ['annotate', 'html', 'report', 'combine']:
if (i in options.actions) and (j in options.actions):
- help_fn("You can't specify the '%s' and '%s' "
+ self.help_fn("You can't specify the '%s' and '%s' "
"options at the same time." % (i, j))
return ERR
+ if not options.actions:
+ self.help_fn(
+ "You must specify at least one of -e, -x, -c, -r, -a, or -b."
+ )
+ return ERR
args_needed = (
'execute' in options.actions or
'annotate' in options.actions or
'html' in options.actions or
'report' in options.actions
)
- if not options.actions:
- help_fn(
- "You must specify at least one of -e, -x, -c, -r, -a, or -b."
- )
- return ERR
if not args_needed and args:
- help_fn("Unexpected arguments: %s" % " ".join(args))
+ self.help_fn("Unexpected arguments: %s" % " ".join(args))
return ERR
# Do something.
@@ -196,7 +205,7 @@ class CoverageScript:
if 'execute' in options.actions:
if not args:
- help_fn("Nothing to do.")
+ self.help_fn("Nothing to do.")
return ERR
# Run the script.
diff --git a/test/test_cmdline.py b/test/test_cmdline.py
index 8b58a66c..a53e3734 100644
--- a/test/test_cmdline.py
+++ b/test/test_cmdline.py
@@ -26,7 +26,7 @@ class CmdLineParserTest(CoverageTest):
"""
self.help_out = ""
argv = shlex.split(args)
- ret_code = coverage.CoverageScript().command_line(argv, self.help_fn)
+ ret_code = coverage.CoverageScript(_help_fn=self.help_fn).command_line(argv)
self.assertEqual(ret_code, ret)
self.assertEqual(self.help_out, help_out)