Skip to content

Commit 7488770

Browse files
committed
Add combine --keep
Related to nedbat#1108
1 parent 0143891 commit 7488770

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

coverage/cmdline.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class Opts(object):
3131
'-a', '--append', action='store_true',
3232
help="Append coverage data to .coverage, otherwise it starts clean each time.",
3333
)
34+
keep = optparse.make_option(
35+
'', '--keep', action='store_true',
36+
help="Keep combined coverage files, otherwise they are deleted.",
37+
)
3438
branch = optparse.make_option(
3539
'', '--branch', action='store_true',
3640
help="Measure branch coverage in addition to statement coverage.",
@@ -215,6 +219,7 @@ def __init__(self, *args, **kwargs):
215219
help=None,
216220
ignore_errors=None,
217221
include=None,
222+
keep=None,
218223
module=None,
219224
omit=None,
220225
contexts=None,
@@ -333,6 +338,7 @@ def get_prog_name(self):
333338
"combine",
334339
[
335340
Opts.append,
341+
Opts.keep,
336342
] + GLOBAL_ARGS,
337343
usage="[options] <path1> <path2> ... <pathN>",
338344
description=(
@@ -585,7 +591,7 @@ def command_line(self, argv):
585591
if options.append:
586592
self.coverage.load()
587593
data_dirs = args or None
588-
self.coverage.combine(data_dirs, strict=True)
594+
self.coverage.combine(data_dirs, strict=True, keep=options.keep)
589595
self.coverage.save()
590596
return OK
591597

coverage/control.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def save(self):
659659
data = self.get_data()
660660
data.write()
661661

662-
def combine(self, data_paths=None, strict=False):
662+
def combine(self, data_paths=None, strict=False, keep=False):
663663
"""Combine together a number of similarly-named coverage data files.
664664
665665
All coverage data files whose name starts with `data_file` (from the
@@ -674,6 +674,8 @@ def combine(self, data_paths=None, strict=False):
674674
If `strict` is true, then it is an error to attempt to combine when
675675
there are no data files to combine.
676676
677+
If `keep` is true, then combined data files won't be deleted.
678+
677679
.. versionadded:: 4.0
678680
The `data_paths` parameter.
679681
@@ -694,7 +696,7 @@ def combine(self, data_paths=None, strict=False):
694696
for pattern in paths[1:]:
695697
aliases.add(pattern, result)
696698

697-
combine_parallel_data(self._data, aliases=aliases, data_paths=data_paths, strict=strict)
699+
combine_parallel_data(self._data, aliases=aliases, data_paths=data_paths, strict=strict, keep=keep)
698700

699701
def get_data(self):
700702
"""Get the collected data.

coverage/data.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def add_data_to_hash(data, filename, hasher):
5252
hasher.update(data.file_tracer(filename))
5353

5454

55-
def combine_parallel_data(data, aliases=None, data_paths=None, strict=False):
55+
def combine_parallel_data(data, aliases=None, data_paths=None, strict=False, keep=False):
5656
"""Combine a number of data files together.
5757
5858
Treat `data.filename` as a file prefix, and combine the data from all
@@ -68,7 +68,7 @@ def combine_parallel_data(data, aliases=None, data_paths=None, strict=False):
6868
If `data_paths` is not provided, then the directory portion of
6969
`data.filename` is used as the directory to search for data files.
7070
71-
Every data file found and combined is then deleted from disk. If a file
71+
Unless `keep` is True every data file found and combined is then deleted from disk. If a file
7272
cannot be read, a warning will be issued, and the file will not be
7373
deleted.
7474
@@ -116,9 +116,10 @@ def combine_parallel_data(data, aliases=None, data_paths=None, strict=False):
116116
else:
117117
data.update(new_data, aliases=aliases)
118118
files_combined += 1
119-
if data._debug.should('dataio'):
120-
data._debug.write("Deleting combined data file %r" % (f,))
121-
file_be_gone(f)
119+
if not keep:
120+
if data._debug.should('dataio'):
121+
data._debug.write("Deleting combined data file %r" % (f,))
122+
file_be_gone(f)
122123

123124
if strict and not files_combined:
124125
raise CoverageException("No usable data files")

doc/python-coverage.1.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ COMMAND REFERENCE
108108

109109
Combine data from multiple coverage files collected with ``run -p``.
110110
The combined results are written to a single file representing the
111-
union of the data.
111+
union of the data. Unless --keep is provided the combined coverage files are deleted.
112112

113113
If `PATH` is specified, they are files or directories containing data to
114114
be combined.
@@ -119,6 +119,9 @@ COMMAND REFERENCE
119119
Append coverage data to .coverage, otherwise it starts clean each
120120
time.
121121

122+
\--keep
123+
Keep combined coverage file.
124+
122125
**debug** `TOPIC` ...
123126

124127
Display information about the internals of coverage.py, for diagnosing

tests/test_process.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,28 @@ def test_combine_parallel_data_no_append(self):
244244
data.read()
245245
self.assertEqual(line_counts(data)['b_or_c.py'], 7)
246246

247+
def test_combine_parallel_data_keep(self):
248+
self.make_b_or_c_py()
249+
out = self.run_command("coverage run -p b_or_c.py b")
250+
self.assertEqual(out, 'done\n')
251+
self.assert_doesnt_exist(".coverage")
252+
self.assert_file_count(".coverage.*", 1)
253+
254+
out = self.run_command("coverage run -p b_or_c.py c")
255+
self.assertEqual(out, 'done\n')
256+
self.assert_doesnt_exist(".coverage")
257+
258+
# After two -p runs, there should be two .coverage.machine.123 files.
259+
self.assert_file_count(".coverage.*", 2)
260+
261+
# Combine the parallel coverage data files into .coverage with the keep flag.
262+
self.run_command("coverage combine --keep")
263+
self.assert_exists(".coverage")
264+
265+
# After combining, there should be the .coverage file and the original combined file should still be there.
266+
self.assert_file_count(".coverage.*", 3)
267+
268+
247269
def test_append_data(self):
248270
self.make_b_or_c_py()
249271

0 commit comments

Comments
 (0)