eric7/DebugClients/Python/coverage/data.py

branch
eric7
changeset 8929
fcca2fa618bf
parent 8775
0802ae193343
equal deleted inserted replaced
8928:d856023fbeb0 8929:fcca2fa618bf
11 """ 11 """
12 12
13 import glob 13 import glob
14 import os.path 14 import os.path
15 15
16 from coverage.exceptions import CoverageException 16 from coverage.exceptions import CoverageException, NoDataError
17 from coverage.misc import file_be_gone 17 from coverage.misc import file_be_gone, human_sorted, plural
18 from coverage.sqldata import CoverageData 18 from coverage.sqldata import CoverageData
19 19
20 20
21 def line_counts(data, fullpath=False): 21 def line_counts(data, fullpath=False):
22 """Return a dict summarizing the line coverage data. 22 """Return a dict summarizing the line coverage data.
51 else: 51 else:
52 hasher.update(sorted(data.lines(filename) or [])) 52 hasher.update(sorted(data.lines(filename) or []))
53 hasher.update(data.file_tracer(filename)) 53 hasher.update(data.file_tracer(filename))
54 54
55 55
56 def combinable_files(data_file, data_paths=None):
57 """Make a list of data files to be combined.
58
59 `data_file` is a path to a data file. `data_paths` is a list of files or
60 directories of files.
61
62 Returns a list of absolute file paths.
63 """
64 data_dir, local = os.path.split(os.path.abspath(data_file))
65
66 data_paths = data_paths or [data_dir]
67 files_to_combine = []
68 for p in data_paths:
69 if os.path.isfile(p):
70 files_to_combine.append(os.path.abspath(p))
71 elif os.path.isdir(p):
72 pattern = os.path.join(os.path.abspath(p), f"{local}.*")
73 files_to_combine.extend(glob.glob(pattern))
74 else:
75 raise NoDataError(f"Couldn't combine from non-existent path '{p}'")
76 return files_to_combine
77
78
56 def combine_parallel_data( 79 def combine_parallel_data(
57 data, aliases=None, data_paths=None, strict=False, keep=False, message=None, 80 data, aliases=None, data_paths=None, strict=False, keep=False, message=None,
58 ): 81 ):
59 """Combine a number of data files together. 82 """Combine a number of data files together.
83
84 `data` is a CoverageData.
60 85
61 Treat `data.filename` as a file prefix, and combine the data from all 86 Treat `data.filename` as a file prefix, and combine the data from all
62 of the data files starting with that prefix plus a dot. 87 of the data files starting with that prefix plus a dot.
63 88
64 If `aliases` is provided, it's a `PathAliases` object that is used to 89 If `aliases` is provided, it's a `PathAliases` object that is used to
77 102
78 If `strict` is true, and no files are found to combine, an error is 103 If `strict` is true, and no files are found to combine, an error is
79 raised. 104 raised.
80 105
81 """ 106 """
82 # Because of the os.path.abspath in the constructor, data_dir will 107 files_to_combine = combinable_files(data.base_filename(), data_paths)
83 # never be an empty string.
84 data_dir, local = os.path.split(data.base_filename())
85 localdot = local + '.*'
86
87 data_paths = data_paths or [data_dir]
88 files_to_combine = []
89 for p in data_paths:
90 if os.path.isfile(p):
91 files_to_combine.append(os.path.abspath(p))
92 elif os.path.isdir(p):
93 pattern = os.path.join(os.path.abspath(p), localdot)
94 files_to_combine.extend(glob.glob(pattern))
95 else:
96 raise CoverageException(f"Couldn't combine from non-existent path '{p}'")
97 108
98 if strict and not files_to_combine: 109 if strict and not files_to_combine:
99 raise CoverageException("No data to combine") 110 raise NoDataError("No data to combine")
100 111
101 files_combined = 0 112 files_combined = 0
102 for f in files_to_combine: 113 for f in files_to_combine:
103 if f == data.data_filename(): 114 if f == data.data_filename():
104 # Sometimes we are combining into a file which is one of the 115 # Sometimes we are combining into a file which is one of the
125 if data._debug.should('dataio'): 136 if data._debug.should('dataio'):
126 data._debug.write(f"Deleting combined data file {f!r}") 137 data._debug.write(f"Deleting combined data file {f!r}")
127 file_be_gone(f) 138 file_be_gone(f)
128 139
129 if strict and not files_combined: 140 if strict and not files_combined:
130 raise CoverageException("No usable data files") 141 raise NoDataError("No usable data files")
142
143
144 def debug_data_file(filename):
145 """Implementation of 'coverage debug data'."""
146 data = CoverageData(filename)
147 filename = data.data_filename()
148 print(f"path: {filename}")
149 if not os.path.exists(filename):
150 print("No data collected: file doesn't exist")
151 return
152 data.read()
153 print(f"has_arcs: {data.has_arcs()!r}")
154 summary = line_counts(data, fullpath=True)
155 filenames = human_sorted(summary.keys())
156 nfiles = len(filenames)
157 print(f"{nfiles} file{plural(nfiles)}:")
158 for f in filenames:
159 line = f"{f}: {summary[f]} line{plural(summary[f])}"
160 plugin = data.file_tracer(f)
161 if plugin:
162 line += f" [{plugin}]"
163 print(line)

eric ide

mercurial