554ccacf Andy McCall 1 month ago ↶
1
{% extends "base.html" %}
2
{% import "repo_tabs.html" as m %}
3
{% block title %}Coverage · {{ repo.owner }}/{{ repo.name }}{% endblock %}
4
{% block tabs %}{% call m::tabs(repo, "coverage") %}{% endblock %}
5
{% block content %}
6
{% if let Some(r) = report %}
c987c865 Andy McCall 1 month ago ↶
7
< section class = " cov-hero " >
8
< div class = " cov-hero-head " >
9
< div >
10
< h1 > Coverage</ h1 >
11
< div class = " cov-sub " > {% if bookmarks.len() > 1 %}< form class = " inline " method = " get" action = " {{ repo.url }}/coverage" > < label for = " cov-bm" class = " mute " > bookmark</ label > < select id = " cov-bm " name = " bookmark" onchange = " this . form . submit ( ) " > {% for b in bookmarks %}< option value = " {{ b }}" {% if b.as_str () == bookmark.as_str () %} selected {% endif %}> {{ b }}</ option > {% endfor %}</ select > < noscript > < button > Show</ button > </ noscript > </ form > {% else %}< span class = " mute " > on</ span > < strong > {{ bookmark }}</ strong > {% endif %}
40dd3f86 Andy McCall 25 days ago ↶
12
· {% if r.uploaded() %}< span class = " tag warn " title = " Uploaded with oh coverage upload: measured off the hub, not by a Flow job" > uploaded by {{ r.uploader }}</ span > {% else %}< a href = " {{ repo.url }}/flow/{{ r.run_number }}" > run #{{ r.run_number }}</ a > {% endif %} · < time title = " {{ r.created_ms|when_i }}" > {{ r.created_ms|ago_i }}</ time > </ div >
c987c865 Andy McCall 1 month ago ↶
13
</ div >
14
< div class = " cov-score {{ self.class_of(r.percent()) }} " >
15
< div class = " cov-big " > {{ self.pct(r.percent()) }}</ div >
40dd3f86 Andy McCall 25 days ago ↶
16
{% if let Some(d) = delta %}< div class = " cov-change {{ self.delta_class(d) }} " title = " Against {% if let Some(p) = previous %}{{ p.source() }}{% endif %}" > {{ self.signed(d) }} since the run before</ div > {% else %}< div class = " cov-change same " > the first report here</ div > {% endif %}
c987c865 Andy McCall 1 month ago ↶
17
</ div >
18
</ div >
19
{% if runs > 1 %}< div class = " cov-hero-chart " > {{ coverage_chart|safe }}</ div > {% endif %}
20
</ section >
21
22
< section class = " cov-facts " >
23
< div > < span class = " k " > Lines covered</ span > < span class = " v " > {{ r.lines_hit }} < small > of {{ r.lines_found }}</ small > </ span > </ div >
24
< div > < span class = " k " > Hits per line</ span > < span class = " v " > {{ self.hits(r) }}</ span > </ div >
25
{% if r.functions_found > 0 %}< div > < span class = " k " > Functions</ span > < span class = " v " > {{ self.pct(r.functions_percent()) }} < small > {{ r.functions_hit }} of {{ r.functions_found }}</ small > </ span > </ div > {% endif %}
26
{% if r.branches_found > 0 %}< div > < span class = " k " > Branches</ span > < span class = " v " > {{ self.pct(r.branches_percent()) }} < small > {{ r.branches_hit }} of {{ r.branches_found }}</ small > </ span > </ div > {% endif %}
27
< div > < span class = " k " > Files</ span > < span class = " v " > {{ r.files }}</ span > </ div >
28
{% if let Some(t) = first_ms %}< div > < span class = " k " > Reporting since</ span > < span class = " v small " > < time title = " {{ t|when_i }}" > {{ t|ago_i }}</ time > </ span > </ div > {% endif %}
29
< div > < span class = " k " > Badge</ span > < span class = " v " > < img src = " {{ repo.url }}/coverage/badge.svg" alt = " coverage {{ self.pct(r.percent()) }}" class = " cov-badge " > < button type = " button" class = " cov-copy " data-copy = " []({{ shell.base_url }}{{ repo.url }}/coverage)" title = " Copy the Markdown for a README" > copy Markdown</ button > </ span > </ div >
554ccacf Andy McCall 1 month ago ↶
30
</ section >
c987c865 Andy McCall 1 month ago ↶
31
32
< div class = " cov-grid " >
33
< section class = " panel cov-card " >
34
< h2 > This run</ h2 >
35
< ul class = " cov-stats " >
36
< li > < strong > {{ r.lines_hit }}</ strong > of < strong > {{ r.lines_found }}</ strong > relevant lines covered < span class = " {{ self.class_of(r.percent()) }} " > ({{ self.pct(r.percent()) }})</ span > </ li >
40dd3f86 Andy McCall 25 days ago ↶
37
{% if let Some((found, hit)) = self.lines_delta() %}< li > {% if *found >= 0 %}+{% endif %}{{ found }} relevant lines, {% if *hit >= 0 %}+{% endif %}{{ hit }} covered, against {% if let Some(p) = previous %}{{ p.source() }}{% endif %}</ li > {% endif %}
c987c865 Andy McCall 1 month ago ↶
38
< li > < strong > {{ self.hits(r) }}</ strong > hits per line</ li >
40dd3f86 Andy McCall 25 days ago ↶
39
< li > {% if r.uploaded() %}Uploaded by < strong > {{ r.uploader }}</ strong > , measured off the hub{% else %}Job < strong > {{ r.job }}</ strong > {% endif %}{% if r.dropped > 0 %}; {{ r.dropped }} files the report named are not in this state and are left out{% endif %}</ li >
c987c865 Andy McCall 1 month ago ↶
40
{% if added > 0 %}< li > {{ added }} new files</ li > {% endif %}
41
</ ul >
42
{% if !moved.is_empty() %}< h3 > Coverage moved in</ h3 >
43
< table class = " cov-moved " > {% for f in moved %}< tr > < td > < a href = " {{ repo.url }}/coverage/{{ r.id }}/file/{{ f.path }}" > {{ f.path }}</ a > </ td > < td class = " num mute " > {{ self.pct_of(f.before) }} → {{ self.pct_of(f.after) }}</ td > < td class = " num cov-change {{ self.delta_class(&f.delta) }} " > {{ self.signed(& f.delta) }}</ td > </ tr > {% endfor %}</ table > {% endif %}
44
</ section >
45
< section class = " panel cov-card " >
46
< h2 > Files by coverage</ h2 >
47
< div class = " cov-bands " > {% for b in bands %}< div class = " cov-band " > < span class = " cov-band-lbl " > {{ b.label }}</ span > < span class = " bar {{ b.class }} " > < span style = " width : {{ b.width }}%" > </ span > </ span > < span class = " n " > {{ b.files }}</ span > </ div > {% endfor %}</ div >
48
</ section >
49
</ div >
50
51
{% if runs > 1 %}< section class = " panel " >
52
< h2 > Relevant lines covered < small class = " mute " > < span class = " cov-key covered " > covered</ span > < span class = " cov-key relevant " > missed</ span > </ small > </ h2 >
53
{{ lines_chart|safe }}
54
</ section > {% endif %}
55
56
{% if recent.len() > 1 %}< section class = " panel " >
57
< h2 > Recent runs on {{ bookmark }}</ h2 >
58
< div class = " table " > < table class = " cov-runs " >
59
< tr > < th > Run</ th > < th > Job</ th > < th > Coverage</ th > < th class = " num " > Change</ th > < th class = " num " > Lines</ th > < th > When</ th > </ tr >
60
{% for x in recent %}< tr {% if x.report.id = = r.id %} class = " on " {% endif %}>
40dd3f86 Andy McCall 25 days ago ↶
61
< td > < a href = " {{ repo.url }}/coverage?report={{ x.report.id }}" > {% if x.report.uploaded() %}upload by {{ x.report.uploader }}{% else %}#{{ x.report.run_number }}{% endif %}</ a > </ td >
c987c865 Andy McCall 1 month ago ↶
62
< td > {{ x.report.job }}</ td >
63
< td > < span class = " cov-bar {{ self.class_of(x.report.percent()) }} " > < span style = " width : {% if let Some(p ) = x .report .percent () %}{{ p }}{% else %}0{% endif %}%" > </ span > </ span > {{ self.pct(x.report.percent()) }}</ td >
64
< td class = " num " > {% if let Some(d) = x.delta %}< span class = " cov-change {{ self.delta_class(d) }} " > {{ self.signed(d) }}</ span > {% endif %}</ td >
65
< td class = " num " > {{ x.report.lines_hit }} / {{ x.report.lines_found }}</ td >
66
< td class = " small " > < time title = " {{ x.report.created_ms|when_i }}" > {{ x.report.created_ms|ago_i }}</ time > </ td >
67
</ tr > {% endfor %}
68
</ table > </ div >
69
</ section > {% endif %}
70
554ccacf Andy McCall 1 month ago ↶
71
< section class = " panel " >
72
< h2 > Files < small class = " mute " > sorted by {% if sort == "missed" %}lines missed{% else if sort == "percent" %}coverage, lowest first{% else %}path{% endif %}:
73
{% if sort != "missed" %}< a href = " ?report={{ r.id }}&sort=missed" > lines missed</ a > {% endif %}{% if sort != "percent" %}< a href = " ?report={{ r.id }}&sort=percent" > lowest first</ a > {% endif %}{% if sort != "path" %}< a href = " ?report={{ r.id }}&sort=path" > path</ a > {% endif %}</ small > </ h2 >
74
< div class = " table " > < table class = " cov-files " >
75
< tr > < th > File</ th > < th > Coverage</ th > < th class = " num " > Lines</ th > < th class = " num " > Missed</ th > </ tr >
76
{% for f in files %}< tr >
77
< td > < a href = " {{ repo.url }}/coverage/{{ r.id }}/file/{{ f.path }}" > {{ f.path }}</ a > </ td >
78
< td > < span class = " cov-bar {{ self.class_of(f.percent()) }} " role = " img" aria-label = " {{ self.pct(f.percent()) }}" > < span style = " width : {% if let Some(p ) = f .percent () %}{{ p }}{% else %}0{% endif %}%" > </ span > </ span > {{ self.pct(f.percent()) }}</ td >
79
< td class = " num " > {{ f.lines_found }}</ td >
80
< td class = " num " > {{ f.missed() }}</ td >
81
</ tr > {% endfor %}
82
</ table > </ div >
83
</ section >
84
{% else %}
c987c865 Andy McCall 1 month ago ↶
85
< div class = " head " > < h1 > Coverage < small > of {{ bookmark }}</ small > </ h1 > </ div >
554ccacf Andy McCall 1 month ago ↶
86
< section class = " panel " >
87
< p > No coverage report for < strong > {{ bookmark }}</ strong > yet.</ p >
88
< p > Give a job in < code > .flow/pipeline.kdl</ code > an artifact named < code > coverage</ code > holding an LCOV report, and the hub reads it when the job uploads it. For Rust:</ p >
89
< pre > job "coverage" {
90
sandbox "rust"
91
exec "cargo" "llvm-cov" "--workspace" "--lcov" "--output-path" "/src/target/lcov.info"
92
output {
93
artifact "coverage" { path "/src/target/lcov.info" }
94
}
95
}</ pre >
7fff30c4 Andy McCall 1 month ago ↶
96
< p class = " small mute " > Istanbul (< code > --reporter=lcov</ code > ), coverage.py (< code > coverage lcov</ code > ) and gcov with lcov write LCOV too; Cobertura XML (< code > coverage xml</ code > , Coverlet, JaCoCo through cover2cover) is read as well. Paths are read relative to the job's < code > /src</ code > .</ p >
554ccacf Andy McCall 1 month ago ↶
97
</ section >
98
{% endif %}
99
{% endblock %}