Skip to content

Commit

Permalink
Allow per-file minimum coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
vereis committed Mar 16, 2023
1 parent 3341fd6 commit 3b42538
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ to `false`:
- A custom path for html reports. This defaults to the htmlcov report in the excoveralls lib.
- `minimum_coverage`
- When set to a number greater than 0, this setting causes the `mix coveralls` and `mix coveralls.html` tasks to exit with a status code of 1 if test coverage falls below the specified threshold (defaults to 0). This is useful to interrupt CI pipelines with strict code coverage rules. Should be expressed as a number between 0 and 100 signifying the minimum percentage of lines covered.
- Can also be set to a nested object of filepath and minimum coverage key-value pairs. If this is the case, then `mix coveralls` and `mix coveralls.html` tasks will exit with a status code of 1 if test coverage falls below the specified threshold for any of the configured files.
- `html_filter_full_covered`
- A boolean, when `true` files with 100% coverage are not shown in the HTML report. Default to `false`.
Expand Down
36 changes: 31 additions & 5 deletions lib/excoveralls/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,44 @@ defmodule ExCoveralls.Stats do
Exit the process with a status of 1 if coverage is below the minimum.
"""
def ensure_minimum_coverage(stats) do
coverage_options = ExCoveralls.Settings.get_coverage_options
coverage_options = ExCoveralls.Settings.get_coverage_options()
minimum_coverage = coverage_options["minimum_coverage"] || 0
if minimum_coverage > 0, do: check_coverage_threshold(stats, minimum_coverage)

check_coverage_threshold(stats, minimum_coverage)
end

defp check_coverage_threshold(stats, minimum_coverages) when is_map(minimum_coverages) do
file_results = stats |> source() |> Map.get(:files, []) |> Map.new(&{&1.filename, &1})

messages =
for {file, minimum_coverage} <- minimum_coverages,
%Source{coverage: file_coverage, filename: filename} = file_results[file],
minimum_coverage > 0 && file_coverage < minimum_coverage do
"FAILED: Expected minimum coverage of #{minimum_coverage}% for `#{filename}`, got #{file_coverage}%."
end

unless Enum.empty?(messages) do
IO.puts(IO.ANSI.format([:red, :bright, Enum.join(messages, "\n\n")]))
exit({:shutdown, 1})
end

:ok
end

defp check_coverage_threshold(stats, minimum_coverage) do
defp check_coverage_threshold(stats, minimum_coverage) when minimum_coverage > 0 do
result = source(stats)

if result.coverage < minimum_coverage do
message = "FAILED: Expected minimum coverage of #{minimum_coverage}%, got #{result.coverage}%."
IO.puts IO.ANSI.format([:red, :bright, message])
message =
"FAILED: Expected minimum coverage of #{minimum_coverage}%, got #{result.coverage}%."

IO.puts(IO.ANSI.format([:red, :bright, message]))
exit({:shutdown, 1})
end
end

defp check_coverage_threshold(_stats, _minimum_coverage) do
:ok
end

end

0 comments on commit 3b42538

Please sign in to comment.