DebugClients/Python/coverage/html.py

changeset 6219
d6c795b5ce33
parent 5178
878ce843ca9f
equal deleted inserted replaced
6218:bedab77d0fa3 6219:d6c795b5ce33
10 10
11 import coverage 11 import coverage
12 from coverage import env 12 from coverage import env
13 from coverage.backward import iitems 13 from coverage.backward import iitems
14 from coverage.files import flat_rootname 14 from coverage.files import flat_rootname
15 from coverage.misc import CoverageException, Hasher, isolate_module 15 from coverage.misc import CoverageException, file_be_gone, Hasher, isolate_module
16 from coverage.report import Reporter 16 from coverage.report import Reporter
17 from coverage.results import Numbers 17 from coverage.results import Numbers
18 from coverage.templite import Templite 18 from coverage.templite import Templite
19 19
20 os = isolate_module(os) 20 os = isolate_module(os)
76 # These files will be copied from the htmlfiles directory to the output 76 # These files will be copied from the htmlfiles directory to the output
77 # directory. 77 # directory.
78 STATIC_FILES = [ 78 STATIC_FILES = [
79 ("style.css", ""), 79 ("style.css", ""),
80 ("jquery.min.js", "jquery"), 80 ("jquery.min.js", "jquery"),
81 ("jquery.debounce.min.js", "jquery-debounce"), 81 ("jquery.ba-throttle-debounce.min.js", "jquery-throttle-debounce"),
82 ("jquery.hotkeys.js", "jquery-hotkeys"), 82 ("jquery.hotkeys.js", "jquery-hotkeys"),
83 ("jquery.isonscreen.js", "jquery-isonscreen"), 83 ("jquery.isonscreen.js", "jquery-isonscreen"),
84 ("jquery.tablesorter.min.js", "jquery-tablesorter"), 84 ("jquery.tablesorter.min.js", "jquery-tablesorter"),
85 ("coverage_html.js", ""), 85 ("coverage_html.js", ""),
86 ("keybd_closed.png", ""), 86 ("keybd_closed.png", ""),
103 self.source_tmpl = Templite(read_data("pyfile.html"), self.template_globals) 103 self.source_tmpl = Templite(read_data("pyfile.html"), self.template_globals)
104 104
105 self.coverage = cov 105 self.coverage = cov
106 106
107 self.files = [] 107 self.files = []
108 self.all_files_nums = []
108 self.has_arcs = self.coverage.data.has_arcs() 109 self.has_arcs = self.coverage.data.has_arcs()
109 self.status = HtmlStatus() 110 self.status = HtmlStatus()
110 self.extra_css = None 111 self.extra_css = None
111 self.totals = Numbers() 112 self.totals = Numbers()
112 self.time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M') 113 self.time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
135 self.extra_css = os.path.basename(self.config.extra_css) 136 self.extra_css = os.path.basename(self.config.extra_css)
136 137
137 # Process all the files. 138 # Process all the files.
138 self.report_files(self.html_file, morfs, self.config.html_dir) 139 self.report_files(self.html_file, morfs, self.config.html_dir)
139 140
140 if not self.files: 141 if not self.all_files_nums:
141 raise CoverageException("No data to report.") 142 raise CoverageException("No data to report.")
142 143
143 # Write the index file. 144 # Write the index file.
144 self.index_file() 145 self.index_file()
145 146
169 self.coverage.data.add_to_hash(fr.filename, m) 170 self.coverage.data.add_to_hash(fr.filename, m)
170 return m.hexdigest() 171 return m.hexdigest()
171 172
172 def html_file(self, fr, analysis): 173 def html_file(self, fr, analysis):
173 """Generate an HTML file for one source file.""" 174 """Generate an HTML file for one source file."""
175 rootname = flat_rootname(fr.relative_filename())
176 html_filename = rootname + ".html"
177 html_path = os.path.join(self.directory, html_filename)
178
179 # Get the numbers for this file.
180 nums = analysis.numbers
181 self.all_files_nums.append(nums)
182
183 if self.config.skip_covered:
184 # Don't report on 100% files.
185 no_missing_lines = (nums.n_missing == 0)
186 no_missing_branches = (nums.n_partial_branches == 0)
187 if no_missing_lines and no_missing_branches:
188 # If there's an existing file, remove it.
189 file_be_gone(html_path)
190 return
191
174 source = fr.source() 192 source = fr.source()
175 193
176 # Find out if the file on disk is already correct. 194 # Find out if the file on disk is already correct.
177 rootname = flat_rootname(fr.relative_filename())
178 this_hash = self.file_hash(source.encode('utf-8'), fr) 195 this_hash = self.file_hash(source.encode('utf-8'), fr)
179 that_hash = self.status.file_hash(rootname) 196 that_hash = self.status.file_hash(rootname)
180 if this_hash == that_hash: 197 if this_hash == that_hash:
181 # Nothing has changed to require the file to be reported again. 198 # Nothing has changed to require the file to be reported again.
182 self.files.append(self.status.index_info(rootname)) 199 self.files.append(self.status.index_info(rootname))
183 return 200 return
184 201
185 self.status.set_file_hash(rootname, this_hash) 202 self.status.set_file_hash(rootname, this_hash)
186
187 # Get the numbers for this file.
188 nums = analysis.numbers
189 203
190 if self.has_arcs: 204 if self.has_arcs:
191 missing_branch_arcs = analysis.missing_branch_arcs() 205 missing_branch_arcs = analysis.missing_branch_arcs()
192 arcs_executed = analysis.arcs_executed() 206 arcs_executed = analysis.arcs_executed()
193 207
267 'nums': nums, 281 'nums': nums,
268 'lines': lines, 282 'lines': lines,
269 'time_stamp': self.time_stamp, 283 'time_stamp': self.time_stamp,
270 }) 284 })
271 285
272 html_filename = rootname + ".html"
273 html_path = os.path.join(self.directory, html_filename)
274 write_html(html_path, html) 286 write_html(html_path, html)
275 287
276 # Save this file's information for the index file. 288 # Save this file's information for the index file.
277 index_info = { 289 index_info = {
278 'nums': nums, 290 'nums': nums,
284 296
285 def index_file(self): 297 def index_file(self):
286 """Write the index.html file for this report.""" 298 """Write the index.html file for this report."""
287 index_tmpl = Templite(read_data("index.html"), self.template_globals) 299 index_tmpl = Templite(read_data("index.html"), self.template_globals)
288 300
289 self.totals = sum(f['nums'] for f in self.files) 301 self.totals = sum(self.all_files_nums)
290 302
291 html = index_tmpl.render({ 303 html = index_tmpl.render({
292 'has_arcs': self.has_arcs, 304 'has_arcs': self.has_arcs,
293 'extra_css': self.extra_css, 305 'extra_css': self.extra_css,
294 'files': self.files, 306 'files': self.files,
382 'version': coverage.__version__, 394 'version': coverage.__version__,
383 'settings': self.settings, 395 'settings': self.settings,
384 'files': files, 396 'files': files,
385 } 397 }
386 with open(status_file, "w") as fout: 398 with open(status_file, "w") as fout:
387 json.dump(status, fout) 399 json.dump(status, fout, separators=(',', ':'))
388 400
389 # Older versions of ShiningPanda look for the old name, status.dat. 401 # Older versions of ShiningPanda look for the old name, status.dat.
390 # Accomodate them if we are running under Jenkins. 402 # Accommodate them if we are running under Jenkins.
391 # https://issues.jenkins-ci.org/browse/JENKINS-28428 403 # https://issues.jenkins-ci.org/browse/JENKINS-28428
392 if "JENKINS_URL" in os.environ: 404 if "JENKINS_URL" in os.environ:
393 with open(os.path.join(directory, "status.dat"), "w") as dat: 405 with open(os.path.join(directory, "status.dat"), "w") as dat:
394 dat.write("https://issues.jenkins-ci.org/browse/JENKINS-28428\n") 406 dat.write("https://issues.jenkins-ci.org/browse/JENKINS-28428\n")
395 407

eric ide

mercurial