From 9b099f41d6100f87dcb334d4acdcfbcdac2c97f1 Mon Sep 17 00:00:00 2001
From: Drew Varner <andrew@go-factory.net>
Date: Mon, 30 Jan 2017 02:22:16 -0500
Subject: Allow exclusion of apps in cover

Adds a new option `{cover_excl_apps, Apps}` to exclude apps from coverage
analysis by name.
---
 THANKS                     |  1 +
 src/rebar_prv_cover.erl    | 17 +++++++++--------
 test/rebar_cover_SUITE.erl | 19 +++++++++++++------
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/THANKS b/THANKS
index e91d941..d6e3869 100644
--- a/THANKS
+++ b/THANKS
@@ -139,3 +139,4 @@ Derek Brown
 Heinz N. Gies
 Roberto Aloi
 Andrew McRobb
+Drew Varner
diff --git a/src/rebar_prv_cover.erl b/src/rebar_prv_cover.erl
index e53a687..865c557 100644
--- a/src/rebar_prv_cover.erl
+++ b/src/rebar_prv_cover.erl
@@ -303,7 +303,8 @@ strip_coverdir(File) ->
                                               2))).
 
 cover_compile(State, apps) ->
-    Apps = filter_checkouts(rebar_state:project_apps(State)),
+    ExclApps = [list_to_binary(A) || A <- rebar_state:get(State, cover_excl_apps, [])],
+    Apps = filter_checkouts_and_excluded(rebar_state:project_apps(State), ExclApps),
     AppDirs = app_dirs(Apps),
     cover_compile(State, lists:filter(fun(D) -> ec_file:is_dir(D) end, AppDirs));
 cover_compile(State, Dirs) ->
@@ -313,7 +314,6 @@ cover_compile(State, Dirs) ->
     %% redirect cover output
     true = redirect_cover_output(State, CoverPid),
     ExclMods = rebar_state:get(State, cover_excl_mods, []),
-
     lists:foreach(fun(Dir) ->
         case file:list_dir(Dir) of
             {ok, Files} ->
@@ -356,13 +356,14 @@ app_dirs(Apps) ->
 app_ebin_dirs(App, Acc) ->
     [rebar_app_info:ebin_dir(App)|Acc].
 
-filter_checkouts(Apps) -> filter_checkouts(Apps, []).
+filter_checkouts_and_excluded(Apps, ExclApps) ->
+    filter_checkouts_and_excluded(Apps, ExclApps, []).
 
-filter_checkouts([], Acc) -> lists:reverse(Acc);
-filter_checkouts([App|Rest], Acc) ->
-    case rebar_app_info:is_checkout(App) of
-        true  -> filter_checkouts(Rest, Acc);
-        false -> filter_checkouts(Rest, [App|Acc])
+filter_checkouts_and_excluded([], _ExclApps, Acc) -> lists:reverse(Acc);
+filter_checkouts_and_excluded([App|Rest], ExclApps, Acc) ->
+    case rebar_app_info:is_checkout(App) orelse lists:member(rebar_app_info:name(App), ExclApps) of
+        true  -> filter_checkouts_and_excluded(Rest, ExclApps, Acc);
+        false -> filter_checkouts_and_excluded(Rest, ExclApps, [App|Acc])
     end.
 
 start_cover() ->
diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl
index 4192f4a..cc06c95 100644
--- a/test/rebar_cover_SUITE.erl
+++ b/test/rebar_cover_SUITE.erl
@@ -13,7 +13,7 @@
          index_written/1,
          flag_verbose/1,
          config_verbose/1,
-         excl_mods/1,
+         excl_mods_and_apps/1,
          coverdata_is_reset_on_write/1]).
 
 -include_lib("common_test/include/ct.hrl").
@@ -38,7 +38,7 @@ all() ->
      root_extra_src_dirs,
      index_written,
      flag_verbose, config_verbose,
-     excl_mods, coverdata_is_reset_on_write].
+     excl_mods_and_apps, coverdata_is_reset_on_write].
 
 flag_coverdata_written(Config) ->
     AppDir = ?config(apps, Config),
@@ -210,7 +210,7 @@ config_verbose(Config) ->
 
     true = filelib:is_file(filename:join([AppDir, "_build", "test", "cover", "index.html"])).
 
-excl_mods(Config) ->
+excl_mods_and_apps(Config) ->
     AppDir = ?config(apps, Config),
 
     Name1 = rebar_test_utils:create_random_name("relapp1_"),
@@ -221,18 +221,25 @@ excl_mods(Config) ->
     Vsn2 = rebar_test_utils:create_random_vsn(),
     rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
 
+    Name3 = rebar_test_utils:create_random_name("excludeme_"),
+    Vsn3 = rebar_test_utils:create_random_vsn(),
+    rebar_test_utils:create_app(filename:join([AppDir, "apps", Name3]), Name3, Vsn3, [kernel, stdlib]),
+
     Mod1 = list_to_atom(Name1),
     Mod2 = list_to_atom(Name2),
+    Mod3 = list_to_atom(Name3),
     RebarConfig = [{erl_opts, [{d, some_define}]},
-                   {cover_excl_mods, [Mod2]}],
+                   {cover_excl_mods, [Mod2]},
+                   {cover_excl_apps, [Name3]}],
 
     rebar_test_utils:run_and_check(Config,
                                    RebarConfig,
                                    ["eunit", "--cover"],
-                                   {ok, [{app, Name1}, {app, Name2}]}),
+                                   {ok, [{app, Name1}, {app, Name2}, {app, Name3}]}),
 
     {file, _} = cover:is_compiled(Mod1),
-    false = cover:is_compiled(Mod2).
+    false = cover:is_compiled(Mod2),
+    false = cover:is_compiled(Mod3).
 
 coverdata_is_reset_on_write(Config) ->
     AppDir = ?config(apps, Config),
-- 
cgit v1.1