Skip to content

Commit cbcdedb

Browse files
committed
coverage run: add an output option (-o)
Similar to coverage report/xml/json, coverage run now has a -o option to configure the file the SQLite coverage data will be stored in. The default is still ".coverage", as previously. Since data_file now needs to be specified in cmdline.py, _DEFAULT_DATAFILE needs to be exposed (to avoid hacks like constructing the argument dictionary manually). Rename it to non-undescore and create an alias for it under the previous name (just in case someone used it anyway).
1 parent 3d85264 commit cbcdedb

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

coverage/cmdline.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from coverage import env
1919
from coverage.collector import CTracer
2020
from coverage.config import CoverageConfig
21+
from coverage.control import DEFAULT_DATAFILE
2122
from coverage.data import combinable_files, debug_data_file
2223
from coverage.debug import info_formatter, info_header, short_stack
2324
from coverage.exceptions import _BaseCoverageException, _ExceptionDuringRun, NoSource
@@ -123,6 +124,11 @@ class Opts:
123124
metavar="OUTFILE",
124125
help="Write the JSON report to this file. Defaults to 'coverage.json'",
125126
)
127+
output_coverage = optparse.make_option(
128+
'-o', '', action='store', dest="outfile",
129+
metavar="OUTFILE",
130+
help="Write the recorded coverage information to this file. Defaults to '.coverage'"
131+
)
126132
json_pretty_print = optparse.make_option(
127133
'', '--pretty-print', action='store_true',
128134
help="Format the JSON for human readers.",
@@ -450,6 +456,7 @@ def get_prog_name(self):
450456
Opts.include,
451457
Opts.module,
452458
Opts.omit,
459+
Opts.output_coverage,
453460
Opts.pylib,
454461
Opts.parallel_mode,
455462
Opts.source,
@@ -572,8 +579,11 @@ def command_line(self, argv):
572579
else:
573580
concurrency = None
574581

582+
data_file = options.outfile if options.action in ["run", "combine"] \
583+
else getattr(options, "input_coverage", None)
575584
# Do something.
576585
self.coverage = Coverage(
586+
data_file=data_file or DEFAULT_DATAFILE,
577587
data_suffix=options.parallel_mode,
578588
cover_pylib=options.pylib,
579589
timid=options.timid,

coverage/control.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ def override_config(cov, **kwargs):
6060
cov.config = original_config
6161

6262

63-
_DEFAULT_DATAFILE = DefaultValue("MISSING")
63+
DEFAULT_DATAFILE = DefaultValue("MISSING")
64+
_DEFAULT_DATAFILE = DEFAULT_DATAFILE # Just in case, for backwards compatibility
6465

6566
class Coverage:
6667
"""Programmatic access to coverage.py.
@@ -101,7 +102,7 @@ def current(cls):
101102
return None
102103

103104
def __init__(
104-
self, data_file=_DEFAULT_DATAFILE, data_suffix=None, cover_pylib=None,
105+
self, data_file=DEFAULT_DATAFILE, data_suffix=None, cover_pylib=None,
105106
auto_data=False, timid=None, branch=None, config_file=True,
106107
source=None, source_pkgs=None, omit=None, include=None, debug=None,
107108
concurrency=None, check_preimported=False, context=None,
@@ -198,7 +199,7 @@ def __init__(
198199
# data_file=None means no disk file at all. data_file missing means
199200
# use the value from the config file.
200201
self._no_disk = data_file is None
201-
if data_file is _DEFAULT_DATAFILE:
202+
if data_file is DEFAULT_DATAFILE:
202203
data_file = None
203204

204205
self.config = None

tests/test_cmdline.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import coverage
1515
import coverage.cmdline
1616
from coverage import env
17+
from coverage.control import DEFAULT_DATAFILE
1718
from coverage.config import CoverageConfig
1819
from coverage.exceptions import _ExceptionDuringRun
1920
from coverage.version import __url__
@@ -53,6 +54,7 @@ class BaseCmdLineTest(CoverageTest):
5354
contexts=None, pretty_print=None, show_contexts=None,
5455
)
5556
_defaults.Coverage(
57+
data_file=DEFAULT_DATAFILE,
5658
cover_pylib=None, data_suffix=None, timid=None, branch=None,
5759
config_file=True, source=None, include=None, omit=None, debug=None,
5860
concurrency=None, check_preimported=True, context=None, messages=True,
@@ -636,6 +638,15 @@ def test_run(self):
636638
cov.stop()
637639
cov.save()
638640
""")
641+
self.cmd_executes("run -o output.coverage foo.py", """\
642+
cov = Coverage(data_file="output.coverage")
643+
runner = PyRunner(['foo.py'], as_module=False)
644+
runner.prepare()
645+
cov.start()
646+
runner.run()
647+
cov.stop()
648+
cov.save()
649+
""")
639650

640651
def test_multiprocessing_needs_config_file(self):
641652
# You can't use command-line args to add options to multiprocessing

0 commit comments

Comments
 (0)