summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'coverage')
-rw-r--r--coverage/cmdline.py48
-rw-r--r--coverage/data.py41
2 files changed, 55 insertions, 34 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index e996ffff..f3a466e3 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -17,7 +17,7 @@ import coverage
from coverage import Coverage
from coverage import env
from coverage.collector import CTracer
-from coverage.data import line_counts
+from coverage.data import CoverageData, combinable_files, line_counts
from coverage.debug import info_formatter, info_header, short_stack
from coverage.exceptions import BaseCoverageException, ExceptionDuringRun, NoSource
from coverage.execfile import PyRunner
@@ -601,8 +601,8 @@ class CoverageScript:
elif options.action == "combine":
if options.append:
self.coverage.load()
- data_dirs = args or None
- self.coverage.combine(data_dirs, strict=True, keep=bool(options.keep))
+ data_paths = args or None
+ self.coverage.combine(data_paths, strict=True, keep=bool(options.keep))
self.coverage.save()
return OK
@@ -786,23 +786,12 @@ class CoverageScript:
for line in info_formatter(sys_info):
print(f" {line}")
elif info == 'data':
- self.coverage.load()
- data = self.coverage.get_data()
print(info_header("data"))
- print(f"path: {data.data_filename()}")
- if data:
- print(f"has_arcs: {data.has_arcs()!r}")
- summary = line_counts(data, fullpath=True)
- filenames = human_sorted(summary.keys())
- print(f"\n{len(filenames)} files:")
- for f in filenames:
- line = f"{f}: {summary[f]} lines"
- plugin = data.file_tracer(f)
- if plugin:
- line += f" [{plugin}]"
- print(line)
- else:
- print("No data collected")
+ data_file = self.coverage.config.data_file
+ self.do_debug_data_file(data_file)
+ for filename in combinable_files(data_file):
+ print("-----")
+ self.do_debug_data_file(filename)
elif info == 'config':
print(info_header("config"))
config_info = self.coverage.config.__dict__.items()
@@ -817,6 +806,27 @@ class CoverageScript:
return OK
+ def do_debug_data_file(self, filename):
+ """Implementation of 'coverage debug data'."""
+ data = CoverageData(filename)
+ filename = data.data_filename()
+ print(f"path: {filename}")
+ if not os.path.exists(filename):
+ print("No data collected: file doesn't exist")
+ return
+ data.read()
+ print(f"has_arcs: {data.has_arcs()!r}")
+ summary = line_counts(data, fullpath=True)
+ filenames = human_sorted(summary.keys())
+ nfiles = len(filenames)
+ print(f"{nfiles} file{'' if nfiles == 1 else 's'}:")
+ for f in filenames:
+ line = f"{f}: {summary[f]} line{'' if summary[f] == 1 else 's'}"
+ plugin = data.file_tracer(f)
+ if plugin:
+ line += f" [{plugin}]"
+ print(line)
+
def unshell_list(s):
"""Turn a command-line argument into a list."""
diff --git a/coverage/data.py b/coverage/data.py
index 68ba7ec3..e7c94b4f 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -53,11 +53,36 @@ def add_data_to_hash(data, filename, hasher):
hasher.update(data.file_tracer(filename))
+def combinable_files(data_file, data_paths=None):
+ """Make a list of data files to be combined.
+
+ `data_file` is a path to a data file. `data_paths` is a list of files or
+ directories of files.
+
+ Returns a list of absolute file paths.
+ """
+ data_dir, local = os.path.split(os.path.abspath(data_file))
+
+ data_paths = data_paths or [data_dir]
+ files_to_combine = []
+ for p in data_paths:
+ if os.path.isfile(p):
+ files_to_combine.append(os.path.abspath(p))
+ elif os.path.isdir(p):
+ pattern = os.path.join(os.path.abspath(p), f"{local}.*")
+ files_to_combine.extend(glob.glob(pattern))
+ else:
+ raise CoverageException(f"Couldn't combine from non-existent path '{p}'")
+ return files_to_combine
+
+
def combine_parallel_data(
data, aliases=None, data_paths=None, strict=False, keep=False, message=None,
):
"""Combine a number of data files together.
+ `data` is a CoverageData.
+
Treat `data.filename` as a file prefix, and combine the data from all
of the data files starting with that prefix plus a dot.
@@ -79,21 +104,7 @@ def combine_parallel_data(
raised.
"""
- # Because of the os.path.abspath in the constructor, data_dir will
- # never be an empty string.
- data_dir, local = os.path.split(data.base_filename())
- localdot = local + '.*'
-
- data_paths = data_paths or [data_dir]
- files_to_combine = []
- for p in data_paths:
- if os.path.isfile(p):
- files_to_combine.append(os.path.abspath(p))
- elif os.path.isdir(p):
- pattern = os.path.join(os.path.abspath(p), localdot)
- files_to_combine.extend(glob.glob(pattern))
- else:
- raise CoverageException(f"Couldn't combine from non-existent path '{p}'")
+ files_to_combine = combinable_files(data.base_filename(), data_paths)
if strict and not files_to_combine:
raise CoverageException("No data to combine")