summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTristan Sloughter <tristan.sloughter@gmail.com>2015-01-04 20:09:07 -0600
committerTristan Sloughter <tristan.sloughter@gmail.com>2015-01-04 20:09:07 -0600
commit1d38dcf4feacfb60ae3f9fc54568c23dd28a16a4 (patch)
tree44bc967caa387f8f7a96b9de5c39880dccf89521 /src
parent038fb668e1a7bfb9177f175baa9bcb9c32e95cef (diff)
parent37a20259062056f684f3fa7e9333ca7de9f97a4d (diff)
Merge pull request #83 from tsloughter/master
overrides working except for transitive dep inheritance with lock file
Diffstat (limited to 'src')
-rw-r--r--src/rebar3.erl5
-rw-r--r--src/rebar_app_info.erl11
-rw-r--r--src/rebar_prv_compile.erl9
-rw-r--r--src/rebar_prv_install_deps.erl188
-rw-r--r--src/rebar_state.erl42
5 files changed, 182 insertions, 73 deletions
diff --git a/src/rebar3.erl b/src/rebar3.erl
index f69d27f..c062aa4 100644
--- a/src/rebar3.erl
+++ b/src/rebar3.erl
@@ -142,7 +142,10 @@ init_config() ->
Config1 = case rebar_config:consult_file(?LOCK_FILE) of
[D] ->
- [{locks, D}, {{deps, default}, D} | Config];
+ %% We want the top level deps only from the lock file.
+ %% This ensures deterministic overrides for configs.
+ Deps = [X || X <- D, element(3, X) =:= 0],
+ [{{locks, default}, D}, {{deps, default}, Deps} | Config];
_ ->
Config
end,
diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl
index 3854ea7..4fdb14c 100644
--- a/src/rebar_app_info.erl
+++ b/src/rebar_app_info.erl
@@ -30,6 +30,8 @@
dir/2,
source/1,
source/2,
+ state/1,
+ state/2,
valid/1,
valid/2]).
@@ -47,6 +49,7 @@
dep_level=0 :: integer(),
dir :: file:name(),
source :: string() | tuple() | undefined,
+ state :: rebar_state:t() | undefined,
valid :: boolean()}).
%%============================================================================
@@ -211,6 +214,14 @@ source(AppInfo=#app_info_t{}, Source) ->
source(#app_info_t{source=Source}) ->
Source.
+-spec state(t(), rebar_state:t() | undefined) -> t().
+state(AppInfo=#app_info_t{}, State) ->
+ AppInfo#app_info_t{state=State}.
+
+-spec state(t()) -> rebar_state:t() | undefined.
+state(#app_info_t{state=State}) ->
+ State.
+
-spec valid(t()) -> boolean().
valid(AppInfo=#app_info_t{valid=undefined}) ->
rebar_app_discover:validate_application_info(AppInfo);
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl
index 221876b..b247603 100644
--- a/src/rebar_prv_compile.erl
+++ b/src/rebar_prv_compile.erl
@@ -67,8 +67,13 @@ format_error(Reason) ->
build_apps(State, Apps) ->
lists:foreach(fun(AppInfo) ->
AppDir = rebar_app_info:dir(AppInfo),
- C = rebar_config:consult(AppDir),
- S = rebar_state:new(State, C, AppDir),
+ S = case rebar_app_info:state(AppInfo) of
+ undefined ->
+ C = rebar_config:consult(AppDir),
+ rebar_state:new(State, C, AppDir);
+ AppState ->
+ AppState
+ end,
%% Legacy hook support
rebar_hooks:run_compile_hooks(AppDir, pre_hooks, compile, S),
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 9561d8e..5b06ccf 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -36,7 +36,8 @@
-include_lib("providers/include/providers.hrl").
-export([handle_deps/3,
- handle_deps/4]).
+ handle_deps/4,
+ handle_deps/5]).
-export_type([dep/0]).
@@ -74,10 +75,12 @@ do(State) ->
{SrcApps, State1} =
lists:foldl(fun(Profile, {SrcAppsAcc, StateAcc}) ->
+ Locks = rebar_state:get(StateAcc, {locks, Profile}, []),
{ok, NewSrcApps, NewState} =
handle_deps(Profile
,StateAcc
- ,rebar_state:get(StateAcc, {deps, Profile}, [])),
+ ,rebar_state:get(StateAcc, {deps, Profile}, [])
+ ,Locks),
{NewSrcApps++SrcAppsAcc, NewState}
end, {[], State}, lists:reverse(Profiles)),
@@ -123,22 +126,29 @@ format_error(Reason) ->
-spec handle_deps(atom(), rebar_state:t(), list()) ->
{ok, [rebar_app_info:t()], rebar_state:t()} | {error, string()}.
handle_deps(Profile, State, Deps) ->
- handle_deps(Profile, State, Deps, false).
+ handle_deps(Profile, State, Deps, false, []).
--spec handle_deps(atom(), rebar_state:t(), list(), boolean() | {true, binary(), integer()})
+-spec handle_deps(atom(), rebar_state:t(), list(), list() | boolean()) ->
+ {ok, [rebar_app_info:t()], rebar_state:t()} | {error, string()}.
+handle_deps(Profile, State, Deps, Update) when is_boolean(Update) ->
+ handle_deps(Profile, State, Deps, Update, []);
+handle_deps(Profile, State, Deps, Locks) when is_list(Locks) ->
+ handle_deps(Profile, State, Deps, false, Locks).
+
+-spec handle_deps(atom(), rebar_state:t(), list(), boolean() | {true, binary(), integer()}, list())
-> {ok, [rebar_app_info:t()], rebar_state:t()} | {error, string()}.
-handle_deps(_Profile, State, [], _) ->
+handle_deps(_Profile, State, [], _, _) ->
{ok, [], State};
-handle_deps(Profile, State, Deps, Update) ->
+handle_deps(Profile, State, Deps, Update, Locks) ->
%% Read in package index and dep graph
{Packages, Graph} = rebar_packages:get_packages(State),
%% Split source deps from pkg deps, needed to keep backwards compatibility
DepsDir = rebar_dir:deps_dir(State),
- {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps),
+ {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, State, Locks, 0),
%% Fetch transitive src deps
{State1, SrcApps, PkgDeps1, Seen} =
- update_src_deps(Profile, 0, SrcDeps, PkgDeps, [], State, Update, sets:new()),
+ update_src_deps(Profile, 0, SrcDeps, PkgDeps, [], State, Update, sets:new(), Locks),
{Solved, State2} = case PkgDeps1 of
[] -> %% No pkg deps
@@ -156,6 +166,7 @@ handle_deps(Profile, State, Deps, Update) ->
end,
update_pkg_deps(Profile, S, Packages, Update, Seen, State1)
end,
+
AllDeps = lists:ukeymerge(2
,lists:ukeysort(2, SrcApps)
,lists:ukeysort(2, Solved)),
@@ -176,7 +187,7 @@ update_pkg_deps(Profile, Pkgs, Packages, Update, Seen, State) ->
AppInfo = package_to_app(DepsDir
,Packages
,Pkg),
- {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc),
+ {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc, 0),
case maybe_fetch(AppInfo, Update, SeenAcc1) of
true ->
{[AppInfo | Acc], SeenAcc1, StateAcc1};
@@ -186,14 +197,14 @@ update_pkg_deps(Profile, Pkgs, Packages, Update, Seen, State) ->
end, {[], Seen, State}, Pkgs),
{Solved, State1}.
-maybe_lock(Profile, AppInfo, Seen, State) ->
+maybe_lock(Profile, AppInfo, Seen, State, Level) ->
Name = rebar_app_info:name(AppInfo),
case Profile of
default ->
case sets:is_element(Name, Seen) of
false ->
{sets:add_element(Name, Seen),
- rebar_state:lock(State, AppInfo)};
+ rebar_state:lock(State, rebar_app_info:dep_level(AppInfo, Level))};
true ->
{Seen, State}
end;
@@ -215,17 +226,17 @@ package_to_app(DepsDir, Packages, {Name, Vsn}) ->
rebar_app_info:source(AppInfo2, {pkg, Name, Vsn, Link})
end.
--spec update_src_deps(atom(), non_neg_integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary())) -> {rebar_state:t(), list(), list(), sets:set(binary())}.
-update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen) ->
- case lists:foldl(fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc}) ->
+-spec update_src_deps(atom(), non_neg_integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary()), list()) -> {rebar_state:t(), list(), list(), sets:set(binary())}.
+update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen, Locks) ->
+ case lists:foldl(fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc}) ->
%% If not seen, add to list of locks to write out
case sets:is_element(rebar_app_info:name(AppInfo), SeenAcc) of
true ->
warn_skip_deps(AppInfo),
- {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc};
+ {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc};
false ->
- {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc),
- {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2} =
+ {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc, Level),
+ {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, LocksAcc1} =
case Update of
{true, UpdateName, UpdateLevel} ->
handle_update(AppInfo
@@ -235,7 +246,8 @@ update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen)
,PkgDepsAcc
,SrcAppsAcc
,Level
- ,StateAcc1);
+ ,StateAcc1
+ ,LocksAcc);
_ ->
maybe_fetch(AppInfo, false, SeenAcc1),
handle_dep(AppInfo
@@ -243,22 +255,22 @@ update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen)
,PkgDepsAcc
,SrcAppsAcc
,Level
- ,StateAcc1)
+ ,StateAcc1
+ ,LocksAcc)
end,
- {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, SeenAcc1}
+ {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, SeenAcc1, LocksAcc1}
end
end,
- {[], PkgDeps, SrcApps, State, Seen},
+ {[], PkgDeps, SrcApps, State, Seen, Locks},
lists:sort(SrcDeps)) of
- {[], NewPkgDeps, NewSrcApps, State1, Seen1} ->
+ {[], NewPkgDeps, NewSrcApps, State1, Seen1, _NewLocks} ->
{State1, NewSrcApps, NewPkgDeps, Seen1};
- {NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Seen1} ->
- update_src_deps(Profile, Level+1, NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Update, Seen1)
+ {NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Seen1, NewLocks} ->
+ update_src_deps(Profile, Level+1, NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Update, Seen1, NewLocks)
end.
-handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, SrcApps, Level, State) ->
+handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->
Name = rebar_app_info:name(AppInfo),
- Locks = rebar_state:get(State, locks, []),
{_, _, _, DepLevel} = lists:keyfind(Name, 1, Locks),
case UpdateLevel < DepLevel
orelse Name =:= UpdateName of
@@ -270,39 +282,52 @@ handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, SrcApps, Level
,PkgDeps
,SrcApps
,Level
- ,State);
+ ,State
+ ,Locks);
false ->
- {SrcDeps, PkgDeps, SrcApps, State}
+ {SrcDeps, PkgDeps, SrcApps, State, Locks}
end;
false ->
- {SrcDeps, PkgDeps, SrcApps, State}
+ {SrcDeps, PkgDeps, SrcApps, State, Locks}
end.
-handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State) ->
+handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->
DepsDir = rebar_dir:deps_dir(State),
- {AppInfo1, NewSrcDeps, NewPkgDeps} =
- handle_dep(State, DepsDir, AppInfo),
+ {AppInfo1, NewSrcDeps, NewPkgDeps, NewLocks} =
+ handle_dep(State, DepsDir, AppInfo, Locks, Level),
AppInfo2 = rebar_app_info:dep_level(AppInfo1, Level),
{NewSrcDeps ++ SrcDeps
,NewPkgDeps++PkgDeps
,[AppInfo2 | SrcApps]
- ,State}.
+ ,State
+ ,NewLocks}.
--spec handle_dep(rebar_state:t(), file:filename_all(), rebar_app_info:t()) ->
+-spec handle_dep(rebar_state:t(), file:filename_all(), rebar_app_info:t(), list(), integer()) ->
{rebar_app_info:t(), [rebar_app_info:t()], [pkg_dep()]}.
-handle_dep(State, DepsDir, AppInfo) ->
+handle_dep(State, DepsDir, AppInfo, Locks, Level) ->
Profiles = rebar_state:current_profiles(State),
+ Name = rebar_app_info:name(AppInfo),
+
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
- S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(AppInfo)),
- S1 = rebar_state:apply_profiles(S, Profiles),
- Deps = rebar_state:get(S1, deps, []),
- AppInfo1 = rebar_app_info:deps(AppInfo, rebar_state:deps_names(Deps)),
- {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps),
- {AppInfo1, SrcDeps, PkgDeps}.
+
+ S = rebar_app_info:state(AppInfo),
+ S1 = rebar_state:new(S, C, rebar_app_info:dir(AppInfo)),
+ S2 = rebar_state:apply_profiles(S1, Profiles),
+ S3 = rebar_state:apply_overrides(S2, Name),
+ AppInfo1 = rebar_app_info:state(AppInfo, S3),
+
+ Deps = rebar_state:get(S3, deps, []),
+
+ %% Update lock level to be the level the dep will have in this dep tree
+ NewLocks = [{DepName, Source, LockLevel+Level} ||
+ {DepName, Source, LockLevel} <- rebar_state:get(S3, {locks, default}, [])],
+ AppInfo2 = rebar_app_info:deps(AppInfo1, rebar_state:deps_names(Deps)),
+ {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, S3, Locks, Level),
+ {AppInfo2, SrcDeps, PkgDeps, Locks++NewLocks}.
-spec maybe_fetch(rebar_app_info:t(), boolean() | {true, binary(), integer()},
- sets:set(binary())) -> boolean().
+ sets:set(binary())) -> boolean().
maybe_fetch(AppInfo, Update, Seen) ->
AppDir = ec_cnv:to_list(rebar_app_info:dir(AppInfo)),
Apps = rebar_app_discover:find_apps(["_checkouts"], all),
@@ -355,39 +380,64 @@ maybe_fetch(AppInfo, Update, Seen) ->
end
end.
--spec parse_deps(binary(), list()) -> {[rebar_app_info:t()], [pkg_dep()]}.
-parse_deps(DepsDir, Deps) ->
- lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, PkgDepsAcc}) when is_list(Vsn) ->
- {SrcDepsAcc, [parse_goal(ec_cnv:to_binary(Name)
- ,ec_cnv:to_binary(Vsn)) | PkgDepsAcc]};
- (Name, {SrcDepsAcc, PkgDepsAcc}) when is_atom(Name) ->
- {SrcDepsAcc, [ec_cnv:to_binary(Name) | PkgDepsAcc]};
- ({Name, Source}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) ->
- Dep = new_dep(DepsDir, Name, [], Source),
- {[Dep | SrcDepsAcc], PkgDepsAcc};
- ({Name, Source}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) ->
- Dep = new_dep(DepsDir, Name, [], Source),
- {[Dep | SrcDepsAcc], PkgDepsAcc};
- ({Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) ->
- Dep = new_dep(DepsDir, Name, [], Source),
- {[Dep | SrcDepsAcc], PkgDepsAcc};
- ({Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source)
- , is_integer(Level) ->
- Dep = new_dep(DepsDir, Name, [], Source),
- {[Dep | SrcDepsAcc], PkgDepsAcc}
+-spec parse_deps(binary(), list(), list(), list(), integer()) -> {[rebar_app_info:t()], [pkg_dep()]}.
+parse_deps(DepsDir, Deps, State, Locks, Level) ->
+ lists:foldl(fun(Dep, Acc) ->
+ Name = case Dep of
+ Dep when is_tuple(Dep) ->
+ element(1, Dep);
+ Dep ->
+ Dep
+ end,
+ case lists:keyfind(ec_cnv:to_binary(Name), 1, Locks) of
+ false ->
+ parse_dep(Dep, Acc, DepsDir, State);
+ LockedDep ->
+ LockedLevel = element(3, LockedDep),
+ case LockedLevel > Level of
+ true ->
+ parse_dep(Dep, Acc, DepsDir, State);
+ false ->
+ parse_dep(LockedDep, Acc, DepsDir, State)
+ end
+ end
end, {[], []}, Deps).
-new_dep(DepsDir, Name, Vsn, Source) ->
- Dirs = [ec_cnv:to_list(filename:join(DepsDir, Name))],
- {ok, Dep} = case ec_lists:search(fun(Dir) ->
- rebar_app_info:discover(Dir)
- end, Dirs) of
- {ok, App, _} ->
+parse_dep({Name, Vsn}, {SrcDepsAcc, PkgDepsAcc}, _DepsDir, _State) when is_list(Vsn) ->
+ {SrcDepsAcc, [parse_goal(ec_cnv:to_binary(Name)
+ ,ec_cnv:to_binary(Vsn)) | PkgDepsAcc]};
+parse_dep(Name, {SrcDepsAcc, PkgDepsAcc}, _DepsDir, _State) when is_atom(Name) ->
+ {SrcDepsAcc, [ec_cnv:to_binary(Name) | PkgDepsAcc]};
+parse_dep({Name, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source) ->
+ Dep = new_dep(DepsDir, Name, [], Source, State),
+ {[Dep | SrcDepsAcc], PkgDepsAcc};
+parse_dep({Name, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source) ->
+ Dep = new_dep(DepsDir, Name, [], Source, State),
+ {[Dep | SrcDepsAcc], PkgDepsAcc};
+parse_dep({Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source) ->
+ Dep = new_dep(DepsDir, Name, [], Source, State),
+ {[Dep | SrcDepsAcc], PkgDepsAcc};
+parse_dep({Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, State) when is_tuple(Source)
+ , is_integer(Level) ->
+ Dep = new_dep(DepsDir, Name, [], Source, State),
+ {[Dep | SrcDepsAcc], PkgDepsAcc}.
+
+new_dep(DepsDir, Name, Vsn, Source, State) ->
+ Dir = ec_cnv:to_list(filename:join(DepsDir, Name)),
+ {ok, Dep} = case rebar_app_info:discover(Dir) of
+ {ok, App} ->
{ok, App};
not_found ->
rebar_app_info:new(Name, Vsn, ec_cnv:to_list(filename:join(DepsDir, Name)))
end,
- rebar_app_info:source(Dep, Source).
+ C = rebar_config:consult(rebar_app_info:dir(Dep)),
+ S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(Dep)),
+
+ Overrides = rebar_state:get(State, overrides, []),
+ ParentOverrides = rebar_state:overrides(State),
+ Dep1 = rebar_app_info:state(Dep,
+ rebar_state:overrides(S, ParentOverrides++Overrides)),
+ rebar_app_info:source(Dep1, Source).
-spec parse_goal(binary(), binary()) -> pkg_dep().
parse_goal(Name, Constraint) ->
diff --git a/src/rebar_state.erl b/src/rebar_state.erl
index 657c7d2..50bcfdb 100644
--- a/src/rebar_state.erl
+++ b/src/rebar_state.erl
@@ -27,6 +27,9 @@
deps_names/1,
+ overrides/1, overrides/2,
+ apply_overrides/2,
+
prepend_hook/3, append_hook/3, hooks/2,
providers/1, providers/2, add_provider/2]).
@@ -49,6 +52,7 @@
deps_to_build = [] :: [rebar_app_into:t()],
all_deps = [] :: [rebar_app_into:t()],
+ overrides = [],
providers = []}).
-export_type([t/0]).
@@ -86,7 +90,8 @@ new(ParentState, Config, Dir) ->
Opts = ParentState#state_t.opts,
LocalOpts = case rebar_config:consult_file(filename:join(Dir, ?LOCK_FILE)) of
[D] ->
- dict:from_list([{locks, D}, {{deps, default}, D} | Config]);
+ LockedDeps = [X || X <- D, element(3, X) =:= 0],
+ dict:from_list([{{locks, default}, LockedDeps}, {{deps, default}, D} | Config]);
_ ->
D = proplists:get_value(deps, Config, []),
dict:from_list([{{deps, default}, D} | Config])
@@ -150,6 +155,35 @@ command_parsed_args(#state_t{command_parsed_args=CmdArgs}) ->
command_parsed_args(State, CmdArgs) ->
State#state_t{command_parsed_args=CmdArgs}.
+apply_overrides(State=#state_t{overrides=Overrides}, AppName) ->
+ Name = binary_to_atom(AppName, utf8),
+
+ %% Inefficient. We want the order we get here though.
+ State1 = lists:foldl(fun({override, O}, StateAcc) ->
+ lists:foldl(fun({Key, Value}, StateAcc1) ->
+ rebar_state:set(StateAcc1, Key, Value)
+ end, StateAcc, O);
+ (_, StateAcc) ->
+ StateAcc
+ end, State, Overrides),
+
+ State2 = lists:foldl(fun({override, N, O}, StateAcc) when N =:= Name ->
+ lists:foldl(fun({Key, Value}, StateAcc1) ->
+ rebar_state:set(StateAcc1, Key, Value)
+ end, StateAcc, O);
+ (_, StateAcc) ->
+ StateAcc
+ end, State1, Overrides),
+
+ lists:foldl(fun({add, N, O}, StateAcc) when N =:= Name ->
+ lists:foldl(fun({Key, Value}, StateAcc1) ->
+ OldValue = rebar_state:get(StateAcc1, Key, []),
+ rebar_state:set(StateAcc1, Key, Value++OldValue)
+ end, StateAcc, O);
+ (_, StateAcc) ->
+ StateAcc
+ end, State2, Overrides).
+
apply_profiles(State, Profile) when not is_list(Profile) ->
apply_profiles(State, [Profile]);
apply_profiles(State, [default]) ->
@@ -200,6 +234,12 @@ deps_names(State) ->
Deps = rebar_state:get(State, deps, []),
deps_names(Deps).
+overrides(#state_t{overrides=Overrides}) ->
+ Overrides.
+
+overrides(State=#state_t{}, Overrides) ->
+ State#state_t{overrides=Overrides}.
+
project_apps(#state_t{project_apps=Apps}) ->
Apps.