summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2019-08-06 11:17:25 -0400
committerGitHub <noreply@github.com>2019-08-06 11:17:25 -0400
commit6abe440ec550dc91354456417d03d5b77dd7adfe (patch)
tree167500dd49e1b01685dfcf9730a49ae4ae6e0b2b
parenteed2d6f43886401efa8966798cbebf0c5546040b (diff)
parent91381bf006f8bb2939de1b463a6311a2bf4bf340 (diff)
Merge pull request #2133 from ferd/fix-duplicate-edoc-macros
Fixing duplicate macro definition in umbrella edoc
-rw-r--r--src/rebar_prv_edoc.erl26
-rw-r--r--test/rebar_edoc_SUITE.erl57
2 files changed, 81 insertions, 2 deletions
diff --git a/src/rebar_prv_edoc.erl b/src/rebar_prv_edoc.erl
index 5e563ab..0c03f7b 100644
--- a/src/rebar_prv_edoc.erl
+++ b/src/rebar_prv_edoc.erl
@@ -47,7 +47,7 @@ do(State) ->
AppDir = rebar_app_info:dir(AppInfo),
AppOpts = rebar_app_info:opts(AppInfo),
%% order of the merge is important to allow app opts overrides
- AppEdocOpts = rebar_opts:get(AppOpts, edoc_opts, []) ++ EdocOptsAcc,
+ AppEdocOpts = merge_opts(rebar_opts:get(AppOpts, edoc_opts, []), EdocOptsAcc),
AppRes = (catch edoc:application(list_to_atom(AppName), AppDir, AppEdocOpts)),
rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, AppInfo, State),
case {AppRes, ShouldAccPaths} of
@@ -93,3 +93,27 @@ add_to_paths([{doc_path, Paths}|T], Path) ->
[{doc_path, [Path | Paths]} | T];
add_to_paths([H|T], Path) ->
[H | add_to_paths(T, Path)].
+
+merge_opts(AppOpts, BaseOpts) ->
+ merge_epp_macros(rebar_utils:tup_umerge(AppOpts, BaseOpts)).
+
+%% @private the `{macros, ...}' definitions for epp can't be
+%% containing duplicate definitions even if multiple macro lists
+%% are supported, so we need to manually remove duplicates
+%% and merge the many lists into a single one.
+merge_epp_macros([]) ->
+ [];
+merge_epp_macros([{macros, M1}, {macros, M2} | Rest]) ->
+ NewMacros = dedupe_macros(lists:usort(M1), lists:usort(M2)),
+ merge_epp_macros( [{macros, NewMacros} | Rest]);
+merge_epp_macros([H | T]) ->
+ [H | merge_epp_macros(T)].
+
+dedupe_macros([], Bs) -> Bs;
+dedupe_macros(As, []) -> As;
+dedupe_macros([{K, V1} | As], [{K, _} | Bs]) ->
+ [{K, V1} | dedupe_macros(As, Bs)];
+dedupe_macros([{KA, VA} | As], [{KB, VB} | Bs]) ->
+ if KA < KB -> [{KA, VA} | dedupe_macros(As, [{KB, VB} | Bs])];
+ KA > KB -> [{KB, VB} | dedupe_macros([{KA, VA} | As], Bs)]
+ end.
diff --git a/test/rebar_edoc_SUITE.erl b/test/rebar_edoc_SUITE.erl
index 2f0fad0..5f8cad6 100644
--- a/test/rebar_edoc_SUITE.erl
+++ b/test/rebar_edoc_SUITE.erl
@@ -3,7 +3,7 @@
-include_lib("eunit/include/eunit.hrl").
-compile(export_all).
-all() -> [multiapp, error_survival].
+all() -> [multiapp, multiapp_macros, error_survival].
init_per_testcase(multiapp, Config) ->
application:load(rebar),
@@ -17,6 +17,19 @@ init_per_testcase(multiapp, Config) ->
State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
,{root_dir, AppsDir}]),
[{apps, AppsDir}, {state, State}, {name, Name} | Config];
+init_per_testcase(multiapp_macros, Config) ->
+ application:load(rebar),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Name = rebar_test_utils:create_random_name("multiapp_macros"),
+ AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]),
+ ec_file:copy(filename:join([DataDir, "foo"]), AppsDir, [recursive]),
+ ok = ec_file:remove(filename:join([AppsDir, "apps", "foo"]), [recursive]),
+ Verbosity = rebar3:log_level(),
+ rebar_log:init(command_line, Verbosity),
+ State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
+ ,{root_dir, AppsDir}]),
+ [{apps, AppsDir}, {state, State}, {name, Name} | Config];
init_per_testcase(error_survival, Config) ->
application:load(rebar),
DataDir = ?config(data_dir, Config),
@@ -61,6 +74,48 @@ multiapp(Config) ->
)),
ok.
+multiapp_macros(Config) ->
+ RebarConfig = [{edoc_opts, [
+ preprocess,
+ {macros, [{m1, x1}, {m2, x2}]},
+ {def, [{d1, "1"}, {d2, "1"}]}
+ ]}],
+ AppConfig = {edoc_opts, [
+ {preprocess, true},
+ {macros, [{m2, f2}, {m3, f3}]},
+ {def, [{d2, "2"}, {d3, "2"}]}
+ ]},
+ DebugModule = "
+ -module(debug).
+ -ifndef(m1). -define(m1,z1). -endif.
+ -ifndef(m2). -define(m2,z2). -endif.
+ -ifndef(m3). -define(m3,z3). -endif.
+ -export([?m1 /0, ?m2 /0, ?m3 /0]).
+
+ %% @doc
+ %% d1:{@d1}
+ %% d2:{@d2}
+ %% d3:{@d3}
+ %% @end
+ ?m1 () -> ok.
+ ?m2 () -> ok.
+ ?m3 () -> ok.
+ ",
+ AppsDir = ?config(apps, Config),
+ ct:pal("AppsDir: ~s", [AppsDir]),
+ ok = file:write_file(filename:join([AppsDir, "apps", "bar1", "rebar.config"]),
+ io_lib:format("~p.~n", [AppConfig])),
+ ok = file:write_file(filename:join([AppsDir, "apps", "bar1", "src", "debug.erl"]),
+ DebugModule),
+ rebar_test_utils:run_and_check(Config, RebarConfig, ["edoc"], {ok, []}),
+ DocFile = filename:join([AppsDir, "apps", "bar1", "doc", "debug.html"]),
+ ?assert(file_content_matches(DocFile, "d1:1")), % config layered
+ ?assert(file_content_matches(DocFile, "d2:2")),
+ ?assert(file_content_matches(DocFile, "d3:2")),
+ ?assert(file_content_matches(DocFile, "x1/0")), % elided in config drop
+ ?assert(file_content_matches(DocFile, "f2/0")),
+ ?assert(file_content_matches(DocFile, "f3/0")),
+ ok.
error_survival(Config) ->
RebarConfig = [],