summaryrefslogtreecommitdiff
path: root/src/rebar_utils.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_utils.erl')
-rw-r--r--src/rebar_utils.erl93
1 files changed, 92 insertions, 1 deletions
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index 7363d0a..9f66181 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -69,7 +69,11 @@
escape_double_quotes_weak/1,
check_min_otp_version/1,
check_blacklisted_otp_versions/1,
- info_useless/2]).
+ info_useless/2,
+ apply_overrides/3,
+ add_to_profile/3,
+ merge_opts/2,
+ merge_opts/3]).
%% for internal use only
-export([otp_release/0]).
@@ -397,6 +401,93 @@ abort_if_blacklisted(BlacklistedRegex, OtpRelease) ->
[OtpRelease, BlacklistedRegex])
end.
+apply_overrides(Opts, Name, Overrides) ->
+ %% Inefficient. We want the order we get here though.
+ Opts1 = lists:foldl(fun({override, O}, OptsAcc) ->
+ lists:foldl(fun({deps, Value}, OptsAcc1) ->
+ rebar_utils:set(OptsAcc1, {deps,default}, Value);
+ ({Key, Value}, OptsAcc1) ->
+ rebar_utils:set(OptsAcc1, Key, Value)
+ end, OptsAcc, O);
+ (_, OptsAcc) ->
+ OptsAcc
+ end, Opts, Overrides),
+
+ Opts2 = lists:foldl(fun({override, N, O}, OptsAcc) when N =:= Name ->
+ lists:foldl(fun({deps, Value}, OptsAcc1) ->
+ rebar_utils:set(OptsAcc1, {deps,default}, Value);
+ ({Key, Value}, OptsAcc1) ->
+ rebar_utils:set(OptsAcc1, Key, Value)
+ end, OptsAcc, O);
+ (_, OptsAcc) ->
+ OptsAcc
+ end, Opts1, Overrides),
+
+ lists:foldl(fun({add, N, O}, OptsAcc) when N =:= Name ->
+ lists:foldl(fun({deps, Value}, OptsAcc1) ->
+ OldValue = rebar_utils:get(OptsAcc1, {deps,default}, []),
+ rebar_utils:set(OptsAcc1, {deps,default}, Value++OldValue);
+ ({Key, Value}, OptsAcc1) ->
+ OldValue = rebar_utils:get(OptsAcc1, Key, []),
+ rebar_utils:set(OptsAcc1, Key, Value++OldValue)
+ end, OptsAcc, O);
+ (_, OptsAcc) ->
+ OptsAcc
+ end, Opts2, Overrides).
+
+add_to_profile(Opts, Profile, KVs) when is_atom(Profile), is_list(KVs) ->
+ Profiles = rebar_utils:get(Opts, profiles, []),
+ ProfileOpts = dict:from_list(proplists:get_value(Profile, Profiles, [])),
+ NewOpts = rebar_utils:merge_opts(Profile, dict:from_list(KVs), ProfileOpts),
+ NewProfiles = [{Profile, dict:to_list(NewOpts)}|lists:keydelete(Profile, 1, Profiles)],
+ rebar_utils:set(Opts, profiles, NewProfiles).
+
+merge_opts(Profile, NewOpts, OldOpts) ->
+ Opts = merge_opts(NewOpts, OldOpts),
+
+ Opts2 = case dict:find(plugins, NewOpts) of
+ {ok, Value} ->
+ dict:store({plugins, Profile}, Value, Opts);
+ error ->
+ Opts
+ end,
+
+ case dict:find(deps, NewOpts) of
+ {ok, Value2} ->
+ dict:store({deps, Profile}, Value2, Opts2);
+ error ->
+ Opts2
+ end.
+
+merge_opts(NewOpts, OldOpts) ->
+ dict:merge(fun(deps, _NewValue, OldValue) ->
+ OldValue;
+ ({deps, _}, NewValue, _OldValue) ->
+ NewValue;
+ (plugins, NewValue, _OldValue) ->
+ NewValue;
+ ({plugins, _}, NewValue, _OldValue) ->
+ NewValue;
+ (profiles, NewValue, OldValue) ->
+ dict:to_list(merge_opts(dict:from_list(NewValue), dict:from_list(OldValue)));
+ (_Key, NewValue, OldValue) when is_list(NewValue) ->
+ case io_lib:printable_list(NewValue) of
+ true when NewValue =:= [] ->
+ case io_lib:printable_list(OldValue) of
+ true ->
+ NewValue;
+ false ->
+ OldValue
+ end;
+ true ->
+ NewValue;
+ false ->
+ rebar_utils:tup_umerge(rebar_utils:tup_sort(NewValue)
+ ,rebar_utils:tup_sort(OldValue))
+ end;
+ (_Key, NewValue, _OldValue) ->
+ NewValue
+ end, NewOpts, OldOpts).
%% ====================================================================
%% Internal functions