From d1692efdf5cad04bc25d959a80ac56ff6faecd8b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 30 Dec 2014 16:38:50 -0600 Subject: overrides working except for transitive dep inheritance with lock file --- src/rebar_app_info.erl | 11 +++++++++ src/rebar_prv_compile.erl | 9 +++++-- src/rebar_prv_install_deps.erl | 56 +++++++++++++++++++++++++----------------- src/rebar_state.erl | 39 +++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 24 deletions(-) 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..b1c38b4 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -134,7 +134,7 @@ handle_deps(Profile, State, Deps, Update) -> {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), %% Fetch transitive src deps {State1, SrcApps, PkgDeps1, Seen} = @@ -293,16 +293,23 @@ handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State) -> {rebar_app_info:t(), [rebar_app_info:t()], [pkg_dep()]}. handle_dep(State, DepsDir, AppInfo) -> 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, []), + AppInfo2 = rebar_app_info:deps(AppInfo1, rebar_state:deps_names(Deps)), + {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, S3), + {AppInfo2, SrcDeps, PkgDeps}. -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 +362,44 @@ maybe_fetch(AppInfo, Update, Seen) -> end end. --spec parse_deps(binary(), list()) -> {[rebar_app_info:t()], [pkg_dep()]}. -parse_deps(DepsDir, Deps) -> +-spec parse_deps(binary(), list(), list()) -> {[rebar_app_info:t()], [pkg_dep()]}. +parse_deps(DepsDir, Deps, State) -> 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 = new_dep(DepsDir, Name, [], Source, State), {[Dep | SrcDepsAcc], PkgDepsAcc}; ({Name, Source}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) -> - Dep = new_dep(DepsDir, Name, [], Source), + Dep = new_dep(DepsDir, Name, [], Source, State), {[Dep | SrcDepsAcc], PkgDepsAcc}; ({Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) -> - Dep = new_dep(DepsDir, Name, [], Source), + Dep = new_dep(DepsDir, Name, [], Source, State), {[Dep | SrcDepsAcc], PkgDepsAcc}; ({Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}) when is_tuple (Source) - , is_integer(Level) -> - Dep = new_dep(DepsDir, Name, [], Source), + , is_integer(Level) -> + Dep = new_dep(DepsDir, Name, [], Source, State), {[Dep | SrcDepsAcc], PkgDepsAcc} 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, _} -> +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..d5d19f3 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]). @@ -150,6 +154,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 +233,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. -- cgit v1.1