diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2019-08-06 11:17:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-06 11:17:25 -0400 |
commit | 6abe440ec550dc91354456417d03d5b77dd7adfe (patch) | |
tree | 167500dd49e1b01685dfcf9730a49ae4ae6e0b2b | |
parent | eed2d6f43886401efa8966798cbebf0c5546040b (diff) | |
parent | 91381bf006f8bb2939de1b463a6311a2bf4bf340 (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.erl | 26 | ||||
-rw-r--r-- | test/rebar_edoc_SUITE.erl | 57 |
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 = [], |