diff options
Diffstat (limited to 'src/rebar_prv_cover.erl')
-rw-r--r-- | src/rebar_prv_cover.erl | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/src/rebar_prv_cover.erl b/src/rebar_prv_cover.erl index 2345b18..7412038 100644 --- a/src/rebar_prv_cover.erl +++ b/src/rebar_prv_cover.erl @@ -12,6 +12,7 @@ maybe_write_coverdata/2, format_error/1]). +-include_lib("providers/include/providers.hrl"). -include("rebar.hrl"). -define(PROVIDER, cover). @@ -62,6 +63,9 @@ maybe_write_coverdata(State, Task) -> end. -spec format_error(any()) -> iolist(). +format_error({min_coverage_failed, {PassRate, Total}}) -> + io_lib:format("Requiring ~p% coverage to pass. Only ~p% obtained", + [PassRate, Total]); format_error(Reason) -> io_lib:format("~p", [Reason]). @@ -102,13 +106,13 @@ do_analyze(State) -> %% redirect cover output true = redirect_cover_output(State, CoverPid), %% analyze! - ok = case analyze(State, CoverFiles) of - [] -> ok; + case analyze(State, CoverFiles) of + [] -> {ok, State}; Analysis -> print_analysis(Analysis, verbose(State)), - write_index(State, Analysis) - end, - {ok, State}. + write_index(State, Analysis), + maybe_fail_coverage(Analysis, State) + end. get_all_coverdata(CoverDir) -> ok = filelib:ensure_dir(filename:join([CoverDir, "dummy.log"])), @@ -213,11 +217,11 @@ format_table(Stats, CoverFiles) -> Header = header(MaxLength), Separator = separator(MaxLength), TotalLabel = format("total", MaxLength), - TotalCov = format(calculate_total(Stats), 8), + TotalCov = format(calculate_total_string(Stats), 8), [io_lib:format("~ts~n~ts~n~ts~n", [Separator, Header, Separator]), lists:map(fun({Mod, Coverage, _}) -> Name = format(Mod, MaxLength), - Cov = format(percentage(Coverage), 8), + Cov = format(percentage_string(Coverage), 8), io_lib:format(" | ~ts | ~ts |~n", [Name, Cov]) end, Stats), io_lib:format("~ts~n", [Separator]), @@ -239,6 +243,9 @@ separator(Width) -> format(String, Width) -> io_lib:format("~*.ts", [Width, String]). +calculate_total_string(Stats) -> + integer_to_list(calculate_total(Stats))++"%". + calculate_total(Stats) -> percentage(lists:foldl( fun({_Mod, {Cov, Not}, _File}, {CovAcc, NotAcc}) -> @@ -248,8 +255,10 @@ calculate_total(Stats) -> Stats )). -percentage({_, 0}) -> "100%"; -percentage({Cov, Not}) -> integer_to_list(trunc((Cov / (Cov + Not)) * 100)) ++ "%". +percentage_string(Data) -> integer_to_list(percentage(Data))++"%". + +percentage({_, 0}) -> 100; +percentage({Cov, Not}) -> trunc((Cov / (Cov + Not)) * 100). write_index(State, Coverage) -> CoverDir = cover_dir(State), @@ -279,14 +288,25 @@ write_index_section(F, [{Section, DataFile, Mods}|Rest]) -> FmtLink = fun({Mod, Cov, Report}) -> ?FMT("<tr><td><a href='~ts'>~ts</a></td><td>~ts</td>\n", - [strip_coverdir(Report), Mod, percentage(Cov)]) + [strip_coverdir(Report), Mod, percentage_string(Cov)]) end, lists:foreach(fun(M) -> ok = file:write(F, FmtLink(M)) end, Mods), ok = file:write(F, ?FMT("<tr><td><strong>Total</strong></td><td>~ts</td>\n", - [calculate_total(Mods)])), + [calculate_total_string(Mods)])), ok = file:write(F, "</table>\n"), write_index_section(F, Rest). +maybe_fail_coverage(Analysis, State) -> + {_, _CoverFiles, Stats} = lists:keyfind("aggregate", 1, Analysis), + Total = calculate_total(Stats), + PassRate = min_coverage(State), + ?DEBUG("Comparing ~p to pass rate ~p", [Total, PassRate]), + if Total >= PassRate -> + {ok, State} + ; Total < PassRate -> + ?PRV_ERROR({min_coverage_failed, {PassRate, Total}}) + end. + %% fix for r15b which doesn't put the correct path in the `source` section %% of `module_info(compile)` strip_coverdir([]) -> ""; @@ -401,12 +421,23 @@ verbose(State) -> {Verbose, _} -> Verbose end. +min_coverage(State) -> + Command = proplists:get_value(min_coverage, command_line_opts(State), undefined), + Config = proplists:get_value(min_coverage, config_opts(State), undefined), + case {Command, Config} of + {undefined, undefined} -> 0; + {undefined, Rate} -> Rate; + {Rate, _} -> Rate + end. + cover_dir(State) -> filename:join([rebar_dir:base_dir(State), "cover"]). cover_opts(_State) -> [{reset, $r, "reset", boolean, help(reset)}, - {verbose, $v, "verbose", boolean, help(verbose)}]. + {verbose, $v, "verbose", boolean, help(verbose)}, + {min_coverage, $m, "min_coverage", integer, help(min_coverage)}]. help(reset) -> "Reset all coverdata."; -help(verbose) -> "Print coverage analysis.". +help(verbose) -> "Print coverage analysis."; +help(min_coverage) -> "Mandate a coverage percentage required to succeed (0..100)". |