diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2019-07-30 16:28:50 -0400 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2019-07-30 16:28:50 -0400 |
commit | 28a50b8a3632b4f9eafb3bc8a36cc72023b13576 (patch) | |
tree | a487a0d19df2b52a4a318b44f3c770507f921981 /src | |
parent | dab233d6edeef2e15b8fcd4616ac01fbaea7e664 (diff) |
Fixing duplicate macro definition in umbrella edoc
When in umbrella mode (or through multiple profiles), users can specify
macros for EDocs based on either the {def, ...} or the {macros, ...}
arguments.
This patch replaces the prior options merging for umbrellas to use the
rebar3 tup_umerge utils to remove identical duplicates while preserving
correct ordering, and manually merges the {macros, ...} definitions
while ke eping the correct precedence rules since these appear (given
their behaviour) to be all individually extracted and passed as `{d,
...}` to the compiler so that epp expands them. This compiler
function freaks out on any re-defined macros and explodes.
Do note that the macros with `{def, ...}` are edoc macros and do not
suffer from that issue, safely deduplicating multiple definitions.
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar_prv_edoc.erl | 26 |
1 files changed, 25 insertions, 1 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. |