summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-08-04 07:36:13 -0400
committerNed Batchelder <ned@nedbatchelder.com>2018-08-04 07:59:50 -0400
commit2f0d57856550ef7ad248e4e6127700bdabb91e7d (patch)
treeb464de6cd75fd80b3825d2606ef397eced11e51f
parent0c5af4612210fa08113ea93372f877ef13aaa007 (diff)
downloadpython-coveragepy-git-2f0d57856550ef7ad248e4e6127700bdabb91e7d.tar.gz
Pull combine_parallel_data out of CoverageData
-rw-r--r--coverage/control.py4
-rw-r--r--coverage/data.py134
-rw-r--r--tests/test_data.py12
3 files changed, 77 insertions, 73 deletions
diff --git a/coverage/control.py b/coverage/control.py
index 1760ee78..2f084cc2 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -15,7 +15,7 @@ from coverage.annotate import AnnotateReporter
from coverage.backward import string_class, iitems
from coverage.collector import Collector
from coverage.config import read_coverage_config
-from coverage.data import CoverageData
+from coverage.data import CoverageData, combine_parallel_data
from coverage.debug import DebugControl, write_formatted_info
from coverage.disposition import disposition_debug_msg
from coverage.files import PathAliases, set_relative_directory, abs_file
@@ -536,7 +536,7 @@ class Coverage(object):
for pattern in paths[1:]:
aliases.add(pattern, result)
- self._data.combine_parallel_data(aliases=aliases, data_paths=data_paths, strict=strict)
+ combine_parallel_data(self._data, aliases=aliases, data_paths=data_paths, strict=strict)
def get_data(self):
"""Get the collected data.
diff --git a/coverage/data.py b/coverage/data.py
index e9243166..0b3b640b 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -594,69 +594,6 @@ class CoverageJsonData(object):
self._validate()
- def combine_parallel_data(self, aliases=None, data_paths=None, strict=False):
- """Combine a number of data files together.
-
- Treat `self.filename` as a file prefix, and combine the data from all
- of the data files starting with that prefix plus a dot.
-
- If `aliases` is provided, it's a `PathAliases` object that is used to
- re-map paths to match the local machine's.
-
- If `data_paths` is provided, it is a list of directories or files to
- combine. Directories are searched for files that start with
- `self.filename` plus dot as a prefix, and those files are combined.
-
- If `data_paths` is not provided, then the directory portion of
- `self.filename` is used as the directory to search for data files.
-
- Every data file found and combined is then deleted from disk. If a file
- cannot be read, a warning will be issued, and the file will not be
- deleted.
-
- If `strict` is true, and no files are found to combine, an error is
- raised.
-
- """
- # Because of the os.path.abspath in the constructor, data_dir will
- # never be an empty string.
- data_dir, local = os.path.split(self.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("Couldn't combine from non-existent path '%s'" % (p,))
-
- if strict and not files_to_combine:
- raise CoverageException("No data to combine")
-
- files_combined = 0
- for f in files_to_combine:
- new_data = CoverageData(debug=self._debug)
- try:
- new_data._read_file(f)
- except CoverageException as exc:
- if self._warn:
- # The CoverageException has the file name in it, so just
- # use the message as the warning.
- self._warn(str(exc))
- else:
- self.update(new_data, aliases=aliases)
- files_combined += 1
- if self._debug and self._debug.should('dataio'):
- self._debug.write("Deleting combined data file %r" % (f,))
- file_be_gone(f)
-
- if strict and not files_combined:
- raise CoverageException("No usable data files")
-
##
## Miscellaneous
##
@@ -731,9 +668,76 @@ class CoverageJsonData(object):
return self._arcs is not None
-from coverage.sqldata import CoverageSqliteData
-CoverageData = CoverageSqliteData
+which = os.environ.get("COV_STORAGE", "json")
+if which == "json":
+ CoverageData = CoverageJsonData
+elif which == "sql":
+ from coverage.sqldata import CoverageSqliteData
+ CoverageData = CoverageSqliteData
+
+def combine_parallel_data(data, aliases=None, data_paths=None, strict=False):
+ """Combine a number of data files together.
+
+ Treat `data.filename` as a file prefix, and combine the data from all
+ of the data files starting with that prefix plus a dot.
+
+ If `aliases` is provided, it's a `PathAliases` object that is used to
+ re-map paths to match the local machine's.
+
+ If `data_paths` is provided, it is a list of directories or files to
+ combine. Directories are searched for files that start with
+ `data.filename` plus dot as a prefix, and those files are combined.
+
+ If `data_paths` is not provided, then the directory portion of
+ `data.filename` is used as the directory to search for data files.
+
+ Every data file found and combined is then deleted from disk. If a file
+ cannot be read, a warning will be issued, and the file will not be
+ deleted.
+
+ If `strict` is true, and no files are found to combine, an error is
+ 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.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("Couldn't combine from non-existent path '%s'" % (p,))
+
+ if strict and not files_to_combine:
+ raise CoverageException("No data to combine")
+
+ files_combined = 0
+ for f in files_to_combine:
+ try:
+ new_data = CoverageData(f, debug=data._debug)
+ new_data.read()
+ except CoverageException as exc:
+ if data._warn:
+ # The CoverageException has the file name in it, so just
+ # use the message as the warning.
+ data._warn(str(exc))
+ else:
+ data.update(new_data, aliases=aliases)
+ files_combined += 1
+ if data._debug and data._debug.should('dataio'):
+ data._debug.write("Deleting combined data file %r" % (f,))
+ file_be_gone(f)
+
+ if strict and not files_combined:
+ raise CoverageException("No usable data files")
def canonicalize_json_data(data):
"""Canonicalize our JSON data so it can be compared."""
diff --git a/tests/test_data.py b/tests/test_data.py
index 5deccef0..702f4554 100644
--- a/tests/test_data.py
+++ b/tests/test_data.py
@@ -11,7 +11,7 @@ import re
import mock
-from coverage.data import CoverageData, debug_main, canonicalize_json_data
+from coverage.data import CoverageData, debug_main, canonicalize_json_data, combine_parallel_data
from coverage.debug import DebugControlString
from coverage.files import PathAliases, canonical_filename
from coverage.misc import CoverageException
@@ -611,7 +611,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
self.assert_exists(".coverage.2")
covdata3 = CoverageData()
- covdata3.combine_parallel_data()
+ combine_parallel_data(covdata3)
self.assert_line_counts(covdata3, SUMMARY_1_2)
self.assert_measured_files(covdata3, MEASURED_FILES_1_2)
self.assert_doesnt_exist(".coverage.1")
@@ -713,7 +713,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
aliases = PathAliases()
aliases.add("/home/ned/proj/src/", "./")
aliases.add(r"c:\ned\test", "./")
- covdata3.combine_parallel_data(aliases=aliases)
+ combine_parallel_data(covdata3, aliases=aliases)
apy = canonical_filename('./a.py')
sub_bpy = canonical_filename('./sub/b.py')
@@ -740,7 +740,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
covdata_xxx.write()
covdata3 = CoverageData()
- covdata3.combine_parallel_data(data_paths=['cov1', 'cov2'])
+ combine_parallel_data(covdata3, data_paths=['cov1', 'cov2'])
self.assert_line_counts(covdata3, SUMMARY_1_2)
self.assert_measured_files(covdata3, MEASURED_FILES_1_2)
@@ -769,7 +769,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
covdata_2xxx.write()
covdata3 = CoverageData()
- covdata3.combine_parallel_data(data_paths=['cov1', 'cov2/.coverage.2'])
+ combine_parallel_data(covdata3, data_paths=['cov1', 'cov2/.coverage.2'])
self.assert_line_counts(covdata3, SUMMARY_1_2)
self.assert_measured_files(covdata3, MEASURED_FILES_1_2)
@@ -782,4 +782,4 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
covdata = CoverageData()
msg = "Couldn't combine from non-existent path 'xyzzy'"
with self.assertRaisesRegex(CoverageException, msg):
- covdata.combine_parallel_data(data_paths=['xyzzy'])
+ combine_parallel_data(covdata, data_paths=['xyzzy'])