@@ -122,6 +122,15 @@ def data_for_file(self, fr, analysis):
122
122
return file_data
123
123
124
124
125
+ class FileToReport :
126
+ """A file we're considering reporting."""
127
+ def __init__ (self , fr , analysis ):
128
+ self .fr = fr
129
+ self .analysis = analysis
130
+ self .rootname = flat_rootname (fr .relative_filename ())
131
+ self .html_filename = self .rootname + ".html"
132
+
133
+
125
134
class HtmlReporter :
126
135
"""HTML reporting."""
127
136
@@ -207,40 +216,50 @@ def report(self, morfs):
207
216
self .incr .check_global_data (self .config , self .pyfile_html_source )
208
217
209
218
# Process all the files. For each page we need to supply a link
210
- # to the next page. Therefore in each iteration of the loop we
211
- # work on the fr and analysis from the previous iteration. We
212
- # also need a link to the preceding page (i.e. 2 before the
213
- # current iteration).
214
- analysis_to_report = get_analysis_to_report (self .coverage , morfs )
215
- pluprev_fr , prev_fr = None , None
216
- prev_analysis = None
217
-
218
- for fr , analysis in analysis_to_report :
219
- if prev_fr is not None :
220
- self .html_file (prev_fr , prev_analysis , pluprev_fr , fr )
219
+ # to the next and previous page.
220
+ files_to_report = []
221
+
222
+ for fr , analysis in get_analysis_to_report (self .coverage , morfs ):
223
+ ftr = FileToReport (fr , analysis )
224
+ should = self .should_report_file (ftr )
225
+ if should :
226
+ files_to_report .append (ftr )
221
227
else :
222
- # This is the first file processed
223
- self .first_fr = fr
224
- pluprev_fr , prev_fr , prev_analysis = prev_fr , fr , analysis
228
+ file_be_gone (os .path .join (self .directory , ftr .html_filename ))
225
229
226
- # One more iteration for the final file. (Or not, if there are
227
- # no files at all.)
228
- if prev_fr is not None :
229
- self .html_file (prev_fr , prev_analysis , pluprev_fr , None )
230
- # This is the last file processed
231
- self .final_fr = prev_fr
230
+ for i , ftr in enumerate (files_to_report ):
231
+ if i == 0 :
232
+ prev_html = "index.html"
233
+ else :
234
+ prev_html = files_to_report [i - 1 ].html_filename
235
+ if i == len (files_to_report ) - 1 :
236
+ next_html = "index.html"
237
+ else :
238
+ next_html = files_to_report [i + 1 ].html_filename
239
+ self .write_html_file (ftr , prev_html , next_html )
232
240
233
241
if not self .all_files_nums :
234
242
raise NoDataError ("No data to report." )
235
243
236
244
self .totals = sum (self .all_files_nums )
237
245
238
246
# Write the index file.
239
- self .index_file ()
247
+ if files_to_report :
248
+ first_html = files_to_report [0 ].html_filename
249
+ final_html = files_to_report [- 1 ].html_filename
250
+ else :
251
+ first_html = final_html = "index.html"
252
+ self .index_file (first_html , final_html )
240
253
241
254
self .make_local_static_report_files ()
242
255
return self .totals .n_statements and self .totals .pc_covered
243
256
257
+ def make_directory (self ):
258
+ """Make sure our htmlcov directory exists."""
259
+ ensure_dir (self .directory )
260
+ if not os .listdir (self .directory ):
261
+ self .directory_was_empty = True
262
+
244
263
def make_local_static_report_files (self ):
245
264
"""Make local instances of static files for HTML report."""
246
265
# The files we provide must always be copied.
@@ -258,27 +277,10 @@ def make_local_static_report_files(self):
258
277
if self .extra_css :
259
278
shutil .copyfile (self .config .extra_css , os .path .join (self .directory , self .extra_css ))
260
279
261
- def html_file (self , fr , analysis , prev_fr , next_fr ):
262
- """Generate an HTML file for one source file."""
263
- rootname = flat_rootname (fr .relative_filename ())
264
- html_filename = rootname + ".html"
265
- if prev_fr is not None :
266
- prev_html = flat_rootname (prev_fr .relative_filename ()) + ".html"
267
- else :
268
- prev_html = "index.html"
269
-
270
- if next_fr is not None :
271
- next_html = flat_rootname (next_fr .relative_filename ()) + ".html"
272
- else :
273
- next_html = "index.html"
274
-
275
- ensure_dir (self .directory )
276
- if not os .listdir (self .directory ):
277
- self .directory_was_empty = True
278
- html_path = os .path .join (self .directory , html_filename )
279
-
280
+ def should_report_file (self , ftr ):
281
+ """Determine if we'll report this file."""
280
282
# Get the numbers for this file.
281
- nums = analysis .numbers
283
+ nums = ftr . analysis .numbers
282
284
self .all_files_nums .append (nums )
283
285
284
286
if self .skip_covered :
@@ -287,24 +289,28 @@ def html_file(self, fr, analysis, prev_fr, next_fr):
287
289
no_missing_branches = (nums .n_partial_branches == 0 )
288
290
if no_missing_lines and no_missing_branches :
289
291
# If there's an existing file, remove it.
290
- file_be_gone (html_path )
291
292
self .skipped_covered_count += 1
292
- return
293
+ return False
293
294
294
295
if self .skip_empty :
295
296
# Don't report on empty files.
296
297
if nums .n_statements == 0 :
297
- file_be_gone (html_path )
298
298
self .skipped_empty_count += 1
299
- return
299
+ return False
300
+
301
+ return True
302
+
303
+ def write_html_file (self , ftr , prev_html , next_html ):
304
+ """Generate an HTML file for one source file."""
305
+ self .make_directory ()
300
306
301
307
# Find out if the file on disk is already correct.
302
- if self .incr .can_skip_file (self .data , fr , rootname ):
303
- self .file_summaries .append (self .incr .index_info (rootname ))
308
+ if self .incr .can_skip_file (self .data , ftr . fr , ftr . rootname ):
309
+ self .file_summaries .append (self .incr .index_info (ftr . rootname ))
304
310
return
305
311
306
312
# Write the HTML page for this file.
307
- file_data = self .datagen .data_for_file (fr , analysis )
313
+ file_data = self .datagen .data_for_file (ftr . fr , ftr . analysis )
308
314
for ldata in file_data .lines :
309
315
# Build the HTML for the line.
310
316
html = []
@@ -348,6 +354,7 @@ def html_file(self, fr, analysis, prev_fr, next_fr):
348
354
css_classes .append (self .template_globals ['category' ][ldata .category ])
349
355
ldata .css_class = ' ' .join (css_classes ) or "pln"
350
356
357
+ html_path = os .path .join (self .directory , ftr .html_filename )
351
358
html = self .source_tmpl .render ({
352
359
** file_data .__dict__ ,
353
360
'prev_html' : prev_html ,
@@ -357,15 +364,16 @@ def html_file(self, fr, analysis, prev_fr, next_fr):
357
364
358
365
# Save this file's information for the index file.
359
366
index_info = {
360
- 'nums' : nums ,
361
- 'html_filename' : html_filename ,
362
- 'relative_filename' : fr .relative_filename (),
367
+ 'nums' : ftr . analysis . numbers ,
368
+ 'html_filename' : ftr . html_filename ,
369
+ 'relative_filename' : ftr . fr .relative_filename (),
363
370
}
364
371
self .file_summaries .append (index_info )
365
- self .incr .set_index_info (rootname , index_info )
372
+ self .incr .set_index_info (ftr . rootname , index_info )
366
373
367
- def index_file (self ):
374
+ def index_file (self , first_html , final_html ):
368
375
"""Write the index.html file for this report."""
376
+ self .make_directory ()
369
377
index_tmpl = Templite (read_data ("index.html" ), self .template_globals )
370
378
371
379
skipped_covered_msg = skipped_empty_msg = ""
@@ -376,16 +384,6 @@ def index_file(self):
376
384
n = self .skipped_empty_count
377
385
skipped_empty_msg = f"{ n } empty file{ plural (n )} skipped."
378
386
379
- if self .first_fr is not None :
380
- first_html = flat_rootname (self .first_fr .relative_filename ()) + ".html"
381
- else :
382
- first_html = "index.html"
383
-
384
- if self .final_fr is not None :
385
- final_html = flat_rootname (self .final_fr .relative_filename ()) + ".html"
386
- else :
387
- final_html = "index.html"
388
-
389
387
html = index_tmpl .render ({
390
388
'files' : self .file_summaries ,
391
389
'totals' : self .totals ,
0 commit comments