covr
covr copied to clipboard
add a markdown output function
an exported function like cover::markdown_output()
to print a coverage report in markdown, which could then easily be used to add either a Job Summary for a GH Action, or potentially to add a comment to a PR thread with a coverage report.
I played around making a more sophisticated markdown()
function than what @jimhester suggested here. In my GH Action, I ran a coverage test on both HEAD and on MAIN and generated a markdown coverage report comparing the diff. (This is quick and dirty, but maybe of interest for ideas.)
- name: test-coverage
id: coverage
run: |
markdown_cov_diff <- function(head, main) {
group <- "filename"
by = "line"
sig_num <- 2
tally_head <- covr::tally_coverage(head, by = by)
tally_main <- covr::tally_coverage(main, by = by)
percs_head <- tapply(tally_head$value, tally_head[[group]], FUN = function(x) sum(x > 0) / length(x) * 100)
percs_main <- tapply(tally_main$value, tally_main[[group]], FUN = function(x) sum(x > 0) / length(x) * 100)
percs_diff <- unname(percs_head - percs_main)
ttl_perc_head <- covr::percent_coverage(tally_head, by = by)
ttl_perc_main <- covr::percent_coverage(tally_main, by = by)
ttl_perc_diff <- ttl_perc_head - ttl_perc_main
percs_head <- format(percs_head, digits = sig_num)
percs_main <- format(percs_main, digits = sig_num)
percs_diff <- paste0(ifelse(percs_diff < 0, ":small_red_triangle_down: ", ""), ifelse(percs_diff > 0, ":arrow_up: ", ""), format(percs_diff, digits = sig_num))
ttl_perc_head <- format(ttl_perc_head, digits = sig_num)
ttl_perc_main <- format(ttl_perc_main, digits = sig_num)
ttl_perc_diff <- paste0(ifelse(ttl_perc_diff < 0, ":small_red_triangle_down: ", ""), ifelse(ttl_perc_diff > 0, ":arrow_up: ", ""), format(ttl_perc_diff, digits = sig_num))
paste0(
"<details>\n",
"<summary>Coverage Report</summary>\n\n",
"|file|head|main|diff|\n|",
" :-- | --: | --: | --: |\n",
paste0("|Overall|", ttl_perc_head, "%|", ttl_perc_main, "%|", ttl_perc_diff, "%|", "\n"),
paste0("|", names(percs_head), "|", percs_head, "%|", percs_main, "%|", percs_diff, "%|", collapse = "\n"),
"\n",
"</details>"
)
}
head <- covr::package_coverage()
system2("git", c("checkout", "main"))
main <- covr::package_coverage()
writeLines(markdown_cov_diff(head, main), "coverage-report.md")
shell: Rscript {0}
I've experimented with this a bit, and I have been successful with both.
job summary looked like this:
PR thread comment looks like:
example markdown table for a PR thread comment:
<details>
<summary>Coverage Report</summary>
|file|head|diff|
| :-- | --: | --: |
|Overall|57%|:small_red_triangle_down: -0.074%|
|R/function_one.R|91%|0.0%|
|R/function_two.R|71%|:arrow_up: 0.0%|
|R/function_three.R|94%|:small_red_triangle_down: -1.1%|
</details>
renders as:
Coverage Report
file | head | diff |
---|---|---|
Overall | 57% | :small_red_triangle_down: -0.074% |
R/function_one.R | 91% | 0.0% |
R/function_two.R | 71% | :arrow_up: 0.0% |
R/function_three.R | 94% | :small_red_triangle_down: -1.1% |
@cjyetman I think that is a good idea, could you open a new issue so it doesn't get lost.
Originally posted by @jimhester in https://github.com/r-lib/covr/issues/207#issuecomment-1332325205
I doubt you want to add {knitr} as a dependency for just this, but knitr::kable()
can convert objects to a markdown table easily...
x <- covr::package_coverage()
coverages <- covr:::per_line(x)
overall <- covr::percent_coverage(x)
full <- lapply(coverages, function(coverage) {
lines <- coverage$file$file_lines
values <- coverage$coverage
values[is.na(values)] <- ""
data.frame(line = seq_along(lines), source = lines, coverage = values,
stringsAsFactors = FALSE)
})
file_stats <- covr:::compute_file_stats(full)
file_stats$File <- row.names(file_stats)
row.names(file_stats) <- NULL
cov_table <- rbind(data.frame(File = "total", Coverage = sprintf("%.2f%%", overall)), file_stats[, c("File", "Coverage")])
knitr::kable(cov_table, align = "lr")
this exists in covrpage already
Let's get this added; it seems really valuable for github actions! If a PR is requested, let me know!