From 98752aab9390137d7cba0b70e0c1c08b9ca308d4 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Wed, 26 Aug 2015 22:13:04 -0500 Subject: wip: move state into app_info --- src/rebar_app_discover.erl | 3 +- src/rebar_app_info.erl | 240 ++++++++++++++++++++++++++++++++++++++++- src/rebar_app_utils.erl | 36 ++++--- src/rebar_dir.erl | 32 +++--- src/rebar_erlc_compiler.erl | 97 ++++++++--------- src/rebar_hooks.erl | 43 ++++---- src/rebar_otp_app.erl | 16 +-- src/rebar_plugins.erl | 21 ++-- src/rebar_prv_clean.erl | 8 +- src/rebar_prv_common_test.erl | 6 +- src/rebar_prv_compile.erl | 16 +-- src/rebar_prv_install_deps.erl | 33 +++--- src/rebar_utils.erl | 28 ++++- test/rebar_dir_SUITE.erl | 42 ++++---- test/rebar_src_dirs_SUITE.erl | 12 +-- 15 files changed, 447 insertions(+), 186 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 5a25a9e..bc66c1f 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -89,12 +89,13 @@ merge_deps(AppInfo, State) -> AppState2 = rebar_state:set(AppState1, artifacts, []), AppInfo1 = rebar_app_info:state(AppInfo, AppState2), + AppInfo2 = rebar_app_info:opts(AppInfo1, rebar_state:opts(AppState2)), State1 = lists:foldl(fun(Profile, StateAcc) -> handle_profile(Profile, Name, AppState1, StateAcc) end, State, lists:reverse(CurrentProfiles)), - {AppInfo1, State1}. + {AppInfo2, State1}. handle_profile(Profile, Name, AppState, State) -> TopParsedDeps = rebar_state:get(State, {parsed_deps, Profile}, {[], []}), diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index bb5104e..ef8f69d 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -5,6 +5,7 @@ new/3, new/4, new/5, + update_opts/3, discover/1, name/1, name/2, @@ -35,6 +36,13 @@ dir/2, out_dir/1, out_dir/2, + default/1, + default/2, + opts/1, + opts/2, + get/2, + get/3, + set/3, resource_type/1, resource_type/2, source/1, @@ -47,9 +55,20 @@ is_checkout/1, is_checkout/2, valid/1, - valid/2]). + valid/2, + + has_all_artifacts/1, + + apply_overrides/2, + add_to_profile/3, + apply_profiles/2, + deduplicate/1, + do_deduplicate/2, + merge_opts/3, + merge_opts/2]). -include("rebar.hrl"). +-include_lib("providers/include/providers.hrl"). -export_type([t/0]). @@ -64,6 +83,8 @@ applications=[] :: list(), deps=[] :: list(), profiles=[default] :: [atom()], + default=dict:new() :: rebar_dict(), + opts=dict:new() :: rebar_dict(), dep_level=0 :: integer(), dir :: file:name(), out_dir :: file:name(), @@ -125,6 +146,36 @@ new(Parent, AppName, Vsn, Dir, Deps) -> out_dir=ec_cnv:to_list(Dir), deps=Deps}}. +update_opts(AppInfo, Opts, Config) -> + LockDeps = case resource_type(AppInfo) of + pkg -> + Deps = deps(AppInfo), + [{{locks, default}, Deps}, {{deps, default}, Deps}]; + _ -> + deps_from_config(dir(AppInfo), Config) + end, + + Plugins = proplists:get_value(plugins, Config, []), + Terms = LockDeps++[{{plugins, default}, Plugins} | Config], + true = rebar_config:verify_config_format(Terms), + LocalOpts = dict:from_list(Terms), + + NewOpts = merge_opts(LocalOpts, Opts), + + AppInfo#app_info_t{opts=NewOpts + ,default=NewOpts}. + +deps_from_config(Dir, Config) -> + case rebar_config:consult_lock_file(filename:join(Dir, ?LOCK_FILE)) of + [D] -> + %% 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}]; + _ -> + [{{deps, default}, proplists:get_value(deps, Config, [])}] + end. + %% @doc discover a complete version of the app info with all fields set. -spec discover(file:filename_all()) -> {ok, t()} | not_found. discover(Dir) -> @@ -151,6 +202,34 @@ config(#app_info_t{config=Config}) -> config(AppInfo=#app_info_t{}, Config) -> AppInfo#app_info_t{config=Config}. +opts(#app_info_t{opts=Opts}) -> + Opts. + +opts(AppInfo, Opts) -> + AppInfo#app_info_t{opts=Opts}. + +default(#app_info_t{default=Default}) -> + Default. + +default(AppInfo, Default) -> + AppInfo#app_info_t{default=Default}. + +get(AppInfo, Key) -> + {ok, Value} = dict:find(Key, AppInfo#app_info_t.opts), + Value. + +get(AppInfo, Key, Default) -> + case dict:find(Key, AppInfo#app_info_t.opts) of + {ok, Value} -> + Value; + error -> + Default + end. + +-spec set(t(), any(), any()) -> t(). +set(AppInfo=#app_info_t{opts=Opts}, Key, Value) -> + AppInfo#app_info_t{opts = dict:store(Key, Value, Opts)}. + -spec app_file_src(t()) -> file:filename_all() | undefined. app_file_src(#app_info_t{app_file_src=undefined, dir=Dir, name=Name}) -> AppFileSrc = filename:join([ec_cnv:to_list(Dir), "src", ec_cnv:to_list(Name)++".app.src"]), @@ -338,9 +417,9 @@ is_checkout(#app_info_t{is_checkout=IsCheckout}) -> IsCheckout. -spec valid(t()) -> boolean(). -valid(AppInfo=#app_info_t{valid=undefined, state=State}) -> +valid(AppInfo=#app_info_t{valid=undefined}) -> case rebar_app_utils:validate_application_info(AppInfo) =:= true - andalso rebar_state:has_all_artifacts(State) =:= true of + andalso has_all_artifacts(AppInfo) =:= true of true -> true; _ -> @@ -352,3 +431,158 @@ valid(#app_info_t{valid=Valid}) -> -spec valid(t(), boolean()) -> t(). valid(AppInfo=#app_info_t{}, Valid) -> AppInfo#app_info_t{valid=Valid}. + +-spec has_all_artifacts(#app_info_t{}) -> true | {false, file:filename()}. +has_all_artifacts(AppInfo) -> + Artifacts = rebar_app_info:get(AppInfo, artifacts, []), + Dir = dir(AppInfo), + all(Dir, Artifacts). + +all(_, []) -> + true; +all(Dir, [File|Artifacts]) -> + case filelib:is_regular(filename:join(Dir, File)) of + false -> + ?DEBUG("Missing artifact ~s", [filename:join(Dir, File)]), + {false, File}; + true -> + all(Dir, Artifacts) + end. + +%%%%% + +apply_overrides(AppInfo, Name) -> + Overrides = rebar_app_info:get(AppInfo, overrides, []), + %Name = binary_to_atom(AppName, utf8), + + %% Inefficient. We want the order we get here though. + AppInfo1 = lists:foldl(fun({override, O}, AppInfoAcc) -> + lists:foldl(fun({deps, Value}, AppInfoAcc1) -> + rebar_app_info:set(AppInfoAcc1, {deps,default}, Value); + ({Key, Value}, AppInfoAcc1) -> + rebar_app_info:set(AppInfoAcc1, Key, Value) + end, AppInfoAcc, O); + (_, AppInfoAcc) -> + AppInfoAcc + end, AppInfo, Overrides), + + AppInfo2 = lists:foldl(fun({override, N, O}, AppInfoAcc) when N =:= Name -> + lists:foldl(fun({deps, Value}, AppInfoAcc1) -> + rebar_app_info:set(AppInfoAcc1, {deps,default}, Value); + ({Key, Value}, AppInfoAcc1) -> + rebar_app_info:set(AppInfoAcc1, Key, Value) + end, AppInfoAcc, O); + (_, AppInfoAcc) -> + AppInfoAcc + end, AppInfo1, Overrides), + + AppInfo3 = lists:foldl(fun({add, N, O}, AppInfoAcc) when N =:= Name -> + lists:foldl(fun({deps, Value}, AppInfoAcc1) -> + OldValue = rebar_app_info:get(AppInfoAcc1, {deps,default}, []), + rebar_app_info:set(AppInfoAcc1, {deps,default}, Value++OldValue); + ({Key, Value}, AppInfoAcc1) -> + OldValue = rebar_app_info:get(AppInfoAcc1, Key, []), + rebar_app_info:set(AppInfoAcc1, Key, Value++OldValue) + end, AppInfoAcc, O); + (_, AppInfoAcc) -> + AppInfoAcc + end, AppInfo2, Overrides), + + Opts = opts(AppInfo3), + AppInfo3#app_info_t{default=Opts}. + +add_to_profile(AppInfo, Profile, KVs) when is_atom(Profile), is_list(KVs) -> + Profiles = rebar_app_info:get(AppInfo, profiles, []), + ProfileOpts = dict:from_list(proplists:get_value(Profile, Profiles, [])), + NewOpts = merge_opts(Profile, dict:from_list(KVs), ProfileOpts), + NewProfiles = [{Profile, dict:to_list(NewOpts)}|lists:keydelete(Profile, 1, Profiles)], + rebar_app_info:set(AppInfo, profiles, NewProfiles). + +apply_profiles(AppInfo, Profile) when not is_list(Profile) -> + apply_profiles(AppInfo, [Profile]); +apply_profiles(AppInfo, [default]) -> + AppInfo; +apply_profiles(AppInfo=#app_info_t{default = Defaults, profiles=CurrentProfiles}, Profiles) -> + AppliedProfiles = case Profiles of + %% Head of list global profile is special, only for use by rebar3 + %% It does not clash if a user does `rebar3 as global...` but when + %% it is the head we must make sure not to prepend `default` + [global | _] -> + Profiles; + _ -> + deduplicate(CurrentProfiles ++ Profiles) + end, + + ConfigProfiles = rebar_app_info:get(AppInfo, profiles, []), + + NewOpts = + lists:foldl(fun(default, OptsAcc) -> + OptsAcc; + (Profile, OptsAcc) -> + case proplists:get_value(Profile, ConfigProfiles, []) of + OptsList when is_list(OptsList) -> + ProfileOpts = dict:from_list(OptsList), + merge_opts(Profile, ProfileOpts, OptsAcc); + Other -> + throw(?PRV_ERROR({profile_not_list, Profile, Other})) + end + end, Defaults, AppliedProfiles), + AppInfo#app_info_t{profiles = AppliedProfiles, opts=NewOpts}. + +deduplicate(Profiles) -> + do_deduplicate(lists:reverse(Profiles), []). + +do_deduplicate([], Acc) -> + Acc; +do_deduplicate([Head | Rest], Acc) -> + case lists:member(Head, Acc) of + true -> do_deduplicate(Rest, Acc); + false -> do_deduplicate(Rest, [Head | Acc]) + end. + +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). diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index a7c78f5..07c262a 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -158,25 +158,27 @@ pkg_to_app(Parent, DepsDir, AppName, PkgName, PkgVsn, IsLock, State) -> dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)), BaseDir = rebar_state:get(State, base_dir, []), - {ok, App1} = case rebar_app_info:discover(CheckoutsDir) of - {ok, App} -> - {ok, rebar_app_info:is_checkout(App, true)}; - not_found -> - Dir = ec_cnv:to_list(filename:join(DepsDir, Name)), - case rebar_app_info:discover(Dir) of - {ok, App} -> - {ok, rebar_app_info:parent(App, Parent)}; - not_found -> - rebar_app_info:new(Parent, Name, Vsn, Dir, []) - end - end, - C = rebar_config:consult(rebar_app_info:dir(App1)), - S = rebar_state:new(rebar_state:new(), C, App1), + {ok, AppInfo} = case rebar_app_info:discover(CheckoutsDir) of + {ok, App} -> + {ok, rebar_app_info:is_checkout(App, true)}; + not_found -> + Dir = ec_cnv:to_list(filename:join(DepsDir, Name)), + case rebar_app_info:discover(Dir) of + {ok, App} -> + {ok, rebar_app_info:parent(App, Parent)}; + not_found -> + rebar_app_info:new(Parent, Name, Vsn, Dir, []) + end + end, + C = rebar_config:consult(rebar_app_info:dir(AppInfo)), + AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), + AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), Overrides = rebar_state:get(State, overrides, []), ParentOverrides = rebar_state:overrides(State), - S1 = rebar_state:set(rebar_state:overrides(S, ParentOverrides++Overrides), base_dir, BaseDir), - App2 = rebar_app_info:state(App1, S1), - rebar_app_info:is_lock(rebar_app_info:source(App2, Source), IsLock). + S1 = rebar_state:set(rebar_state:overrides(State, ParentOverrides++Overrides), base_dir, BaseDir), + %AppInfo2 = rebar_app_info:state(AppInfo1, S1), + AppInfo3 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S1)), + rebar_app_info:is_lock(rebar_app_info:source(AppInfo3, Source), IsLock). format_error({missing_package, Package}) -> io_lib:format("Package not found in registry: ~s", [Package]); diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl index 7af94ea..af6696e 100644 --- a/src/rebar_dir.erl +++ b/src/rebar_dir.erl @@ -129,34 +129,34 @@ do_make_relative_path(Source, Target) -> Base = lists:duplicate(max(length(Target) - 1, 0), ".."), filename:join(Base ++ Source). --spec src_dirs(rebar_state:t()) -> list(file:filename_all()). +-spec src_dirs(rebar_app_info:t()) -> list(file:filename_all()). src_dirs(State) -> src_dirs(State, []). --spec src_dirs(rebar_state:t(), list(file:filename_all())) -> list(file:filename_all()). -src_dirs(State, Default) -> - ErlOpts = rebar_utils:erl_opts(State), +-spec src_dirs(rebar_app_info:t(), list(file:filename_all())) -> list(file:filename_all()). +src_dirs(AppInfo, Default) -> + ErlOpts = rebar_utils:erl_opts(AppInfo), Vs = proplists:get_all_values(src_dirs, ErlOpts), - case lists:append([rebar_state:get(State, src_dirs, []) | Vs]) of + case lists:append([rebar_utils:get(AppInfo, src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. --spec extra_src_dirs(rebar_state:t()) -> list(file:filename_all()). -extra_src_dirs(State) -> extra_src_dirs(State, []). +-spec extra_src_dirs(rebar_app_info:t()) -> list(file:filename_all()). +extra_src_dirs(AppInfo) -> extra_src_dirs(AppInfo, []). --spec extra_src_dirs(rebar_state:t(), list(file:filename_all())) -> list(file:filename_all()). -extra_src_dirs(State, Default) -> - ErlOpts = rebar_utils:erl_opts(State), +-spec extra_src_dirs(rebar_app_info:t(), list(file:filename_all())) -> list(file:filename_all()). +extra_src_dirs(AppInfo, Default) -> + ErlOpts = rebar_utils:erl_opts(AppInfo), Vs = proplists:get_all_values(extra_src_dirs, ErlOpts), - case lists:append([rebar_state:get(State, extra_src_dirs, []) | Vs]) of + case lists:append([rebar_utils:get(AppInfo, extra_src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. --spec all_src_dirs(rebar_state:t()) -> list(file:filename_all()). -all_src_dirs(State) -> all_src_dirs(State, [], []). +-spec all_src_dirs(rebar_app_info:t()) -> list(file:filename_all()). +all_src_dirs(AppInfo) -> all_src_dirs(AppInfo, [], []). --spec all_src_dirs(rebar_state:t(), list(file:filename_all()), list(file:filename_all())) -> +-spec all_src_dirs(rebar_app_info:t(), list(file:filename_all()), list(file:filename_all())) -> list(file:filename_all()). -all_src_dirs(State, SrcDefault, ExtraDefault) -> - src_dirs(State, SrcDefault) ++ extra_src_dirs(State, ExtraDefault). +all_src_dirs(AppInfo, SrcDefault, ExtraDefault) -> + src_dirs(AppInfo, SrcDefault) ++ extra_src_dirs(AppInfo, ExtraDefault). diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 90193da..69b5f29 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -26,7 +26,7 @@ %% ------------------------------------------------------------------- -module(rebar_erlc_compiler). --export([compile/2, +-export([compile/1, compile/3, clean/2]). @@ -80,31 +80,32 @@ %% 'old_inets'}]}. %% --spec compile(rebar_state:t(), file:name()) -> 'ok'. -compile(Config, Dir) -> - compile(Config, Dir, filename:join([Dir, "ebin"])). +-spec compile(rebar_app_info:t()) -> 'ok'. +compile(AppInfo) -> + Dir = ec_cnv:to_list(rebar_app_info:out_dir(AppInfo)), + compile(rebar_app_info:opts(AppInfo), Dir, filename:join([Dir, "ebin"])). --spec compile(rebar_state:t(), file:name(), file:name()) -> 'ok'. -compile(Config, Dir, OutDir) -> - rebar_base_compiler:run(Config, - check_files(rebar_state:get( - Config, xrl_first_files, [])), +-spec compile(rebar_app_info:t(), file:name(), file:name()) -> 'ok'. +compile(AppInfo, Dir, OutDir) -> + rebar_base_compiler:run(AppInfo, + check_files(rebar_utils:get( + AppInfo, xrl_first_files, [])), filename:join(Dir, "src"), ".xrl", filename:join(Dir, "src"), ".erl", fun compile_xrl/3), - rebar_base_compiler:run(Config, - check_files(rebar_state:get( - Config, yrl_first_files, [])), + rebar_base_compiler:run(AppInfo, + check_files(rebar_utils:get( + AppInfo, yrl_first_files, [])), filename:join(Dir, "src"), ".yrl", filename:join(Dir, "src"), ".erl", fun compile_yrl/3), - rebar_base_compiler:run(Config, - check_files(rebar_state:get( - Config, mib_first_files, [])), + rebar_base_compiler:run(AppInfo, + check_files(rebar_utils:get( + AppInfo, mib_first_files, [])), filename:join(Dir, "mibs"), ".mib", filename:join([Dir, "priv", "mibs"]), ".bin", fun compile_mib/3), - doterl_compile(Config, Dir, OutDir). + doterl_compile(AppInfo, Dir, OutDir). --spec clean(rebar_state:t(), file:filename()) -> 'ok'. -clean(_Config, AppDir) -> +-spec clean(rebar_app_info:t(), file:filename()) -> 'ok'. +clean(_AppInfo, AppDir) -> MibFiles = rebar_utils:find_files(filename:join(AppDir, "mibs"), ?RE_PREFIX".*\\.mib\$"), MIBs = [filename:rootname(filename:basename(MIB)) || MIB <- MibFiles], rebar_file_utils:delete_each( @@ -133,17 +134,17 @@ clean(_Config, AppDir) -> %% Internal functions %% =================================================================== --spec doterl_compile(rebar_state:t(), file:filename(), file:filename()) -> ok. +-spec doterl_compile(rebar_app_info:t(), file:filename(), file:filename()) -> ok. doterl_compile(State, Dir, ODir) -> ErlOpts = rebar_utils:erl_opts(State), doterl_compile(State, Dir, ODir, [], ErlOpts). -doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> +doterl_compile(AppInfo, Dir, OutDir, MoreSources, ErlOpts) -> ?DEBUG("erl_opts ~p", [ErlOpts]), %% Support the src_dirs option allowing multiple directories to %% contain erlang source. This might be used, for example, should %% eunit tests be separated from the core application source. - SrcDirs = [filename:join(Dir, X) || X <- rebar_dir:all_src_dirs(Config, ["src"], [])], + SrcDirs = [filename:join(Dir, X) || X <- rebar_dir:all_src_dirs(AppInfo, ["src"], [])], AllErlFiles = gather_src(SrcDirs, []) ++ MoreSources, %% Make sure that ebin/ exists and is on the path @@ -155,7 +156,7 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> G = init_erlcinfo(proplists:get_all_values(i, ErlOpts), AllErlFiles, Dir, OutDir), NeededErlFiles = needed_files(G, ErlOpts, Dir, OutDir1, AllErlFiles), - {ErlFirstFiles, ErlOptsFirst} = erl_first_files(Config, ErlOpts, Dir, NeededErlFiles), + {ErlFirstFiles, ErlOptsFirst} = erl_first_files(AppInfo, ErlOpts, Dir, NeededErlFiles), {DepErls, OtherErls} = lists:partition( fun(Source) -> digraph:in_degree(G, Source) > 0 end, [File || File <- NeededErlFiles, not lists:member(File, ErlFirstFiles)]), @@ -165,7 +166,7 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> ?DEBUG("Files to compile first: ~p", [FirstErls]), try rebar_base_compiler:run( - Config, FirstErls, OtherErls, + AppInfo, FirstErls, OtherErls, fun(S, C) -> ErlOpts1 = case lists:member(S, ErlFirstFiles) of true -> ErlOptsFirst; @@ -182,8 +183,8 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) -> %% Get files which need to be compiled first, i.e. those specified in erl_first_files %% and parse_transform options. Also produce specific erl_opts for these first %% files, so that yet to be compiled parse transformations are excluded from it. -erl_first_files(Config, ErlOpts, Dir, NeededErlFiles) -> - ErlFirstFilesConf = rebar_state:get(Config, erl_first_files, []), +erl_first_files(AppInfo, ErlOpts, Dir, NeededErlFiles) -> + ErlFirstFilesConf = rebar_utils:get(AppInfo, erl_first_files, []), NeededSrcDirs = lists:usort(lists:map(fun filename:dirname/1, NeededErlFiles)), %% NOTE: order of files here is important! ErlFirstFiles = @@ -402,9 +403,9 @@ expand_file_names(Files, Dirs) -> end, Files). --spec internal_erl_compile(rebar_state:t(), file:filename(), file:filename(), +-spec internal_erl_compile(rebar_app_info:t(), file:filename(), file:filename(), file:filename(), list()) -> ok | {ok, any()} | {error, any(), any()}. -internal_erl_compile(Config, Dir, Module, OutDir, ErlOpts) -> +internal_erl_compile(AppInfo, Dir, Module, OutDir, ErlOpts) -> Target = target_base(OutDir, Module) ++ ".beam", ok = filelib:ensure_dir(Target), Opts = [{outdir, filename:dirname(Target)}] ++ ErlOpts ++ @@ -413,23 +414,23 @@ internal_erl_compile(Config, Dir, Module, OutDir, ErlOpts) -> {ok, _Mod} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(Config, Module, Ws); + rebar_base_compiler:ok_tuple(AppInfo, Module, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(Config, Module, Es, Ws, Opts) + rebar_base_compiler:error_tuple(AppInfo, Module, Es, Ws, Opts) end. target_base(OutDir, Source) -> filename:join(OutDir, filename:basename(Source, ".erl")). -spec compile_mib(file:filename(), file:filename(), - rebar_state:t()) -> 'ok'. -compile_mib(Source, Target, Config) -> - Dir = rebar_state:dir(Config), + rebar_app_info:t()) -> 'ok'. +compile_mib(Source, Target, AppInfo) -> + Dir = filename:dirname(Target), ok = filelib:ensure_dir(Target), ok = filelib:ensure_dir(filename:join([Dir, "include", "dummy.hrl"])), - Opts = [{outdir, filename:join([Dir, "priv", "mibs"])} - ,{i, [filename:join([Dir, "priv", "mibs"])]}] ++ - rebar_state:get(Config, mib_opts, []), + Opts = [{outdir, Dir} + ,{i, [Dir]}] ++ + rebar_utils:get(AppInfo, mib_opts, []), case snmpc:compile(Source, Opts) of {ok, _} -> @@ -450,21 +451,21 @@ compile_mib(Source, Target, Config) -> end. -spec compile_xrl(file:filename(), file:filename(), - rebar_state:t()) -> 'ok'. -compile_xrl(Source, Target, Config) -> - Opts = [{scannerfile, Target} | rebar_state:get(Config, xrl_opts, [])], - compile_xrl_yrl(Config, Source, Target, Opts, leex). + rebar_app_info:t()) -> 'ok'. +compile_xrl(Source, Target, AppInfo) -> + Opts = [{scannerfile, Target} | rebar_utils:get(AppInfo, xrl_opts, [])], + compile_xrl_yrl(AppInfo, Source, Target, Opts, leex). -spec compile_yrl(file:filename(), file:filename(), - rebar_state:t()) -> 'ok'. -compile_yrl(Source, Target, Config) -> - Opts = [{parserfile, Target} | rebar_state:get(Config, yrl_opts, [])], - compile_xrl_yrl(Config, Source, Target, Opts, yecc). + rebar_app_info:t()) -> 'ok'. +compile_yrl(Source, Target, AppInfo) -> + Opts = [{parserfile, Target} | rebar_utils:get(AppInfo, yrl_opts, [])], + compile_xrl_yrl(AppInfo, Source, Target, Opts, yecc). --spec compile_xrl_yrl(rebar_state:t(), file:filename(), +-spec compile_xrl_yrl(rebar_app_info:t(), file:filename(), file:filename(), list(), module()) -> 'ok'. -compile_xrl_yrl(Config, Source, Target, Opts, Mod) -> - Dir = rebar_state:dir(Config), +compile_xrl_yrl(AppInfo, Source, Target, Opts, Mod) -> + Dir = filename:dirname(Target), Opts1 = [{includefile, filename:join(Dir, I)} || {includefile, I} <- Opts, filename:pathtype(I) =:= relative], case needs_compile(Source, Target) of @@ -473,9 +474,9 @@ compile_xrl_yrl(Config, Source, Target, Opts, Mod) -> {ok, _} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(Config, Source, Ws); + rebar_base_compiler:ok_tuple(AppInfo, Source, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(Config, Source, + rebar_base_compiler:error_tuple(AppInfo, Source, Es, Ws, Opts1) end; false -> diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index 857336c..c5f8b88 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -1,30 +1,34 @@ -module(rebar_hooks). -export([run_all_hooks/5 + ,run_all_hooks/6 ,format_error/1]). -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). +run_all_hooks(Dir, Type, Command, Providers, State) -> + run_all_hooks(Dir, Type, Command, Providers, element(2,rebar_app_info:new(noen)), State). + -spec run_all_hooks(file:filename_all(), pre | post, atom() | {atom(), atom()} | string(), - [providers:t()], rebar_state:t()) -> ok. -run_all_hooks(Dir, Type, Command, Providers, State) -> - run_provider_hooks(Dir, Type, Command, Providers, State), - run_hooks(Dir, Type, Command, State). + [providers:t()], rebar_app_info:t(), rebar_state:t()) -> ok. +run_all_hooks(Dir, Type, Command, Providers, AppInfo, State) -> + run_provider_hooks(Dir, Type, Command, Providers, AppInfo, State), + run_hooks(Dir, Type, Command, AppInfo, State). -run_provider_hooks(Dir, Type, Command, Providers, State) -> - case rebar_state:get(State, provider_hooks, []) of +run_provider_hooks(Dir, Type, Command, Providers, AppInfo, State) -> + case rebar_app_info:get(AppInfo, provider_hooks, [])++rebar_state:get(State, provider_hooks, []) of [] -> ok; AllHooks -> TypeHooks = proplists:get_value(Type, AllHooks, []), - run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, State) + run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, AppInfo, State) end. -run_provider_hooks(_Dir, _Type, _Command, _Providers, [], _State) -> +run_provider_hooks(_Dir, _Type, _Command, _Providers, [], _AppInfo, _State) -> ok; -run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, State) -> +run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, _AppInfo, State) -> PluginDepsPaths = rebar_state:code_paths(State, all_plugin_deps), code:add_pathsa(PluginDepsPaths), Providers1 = rebar_state:providers(State), @@ -67,16 +71,16 @@ format_error({bad_provider, Type, Command, Name}) -> %% ERL = ERLANG_ROOT_DIR/bin/erl %% ERLC = ERLANG_ROOT_DIR/bin/erl %% -run_hooks(Dir, pre, Command, State) -> - run_hooks(Dir, pre_hooks, Command, State); -run_hooks(Dir, post, Command, State) -> - run_hooks(Dir, post_hooks, Command, State); -run_hooks(Dir, Type, Command, State) -> - case rebar_state:get(State, Type, []) of +run_hooks(Dir, pre, Command, AppInfo, State) -> + run_hooks(Dir, pre_hooks, Command, AppInfo, State); +run_hooks(Dir, post, Command, AppInfo, State) -> + run_hooks(Dir, post_hooks, Command, AppInfo, State); +run_hooks(Dir, Type, Command, AppInfo, State) -> + case rebar_app_info:get(AppInfo, Type, []) of [] -> ok; Hooks -> - Env = create_env(State), + Env = create_env(State, AppInfo), lists:foreach(fun({_, C, _}=Hook) when C =:= Command -> apply_hook(Dir, Env, Hook); ({C, _}=Hook) when C =:= Command -> @@ -97,8 +101,9 @@ apply_hook(Dir, Env, {Command, Hook}) -> Msg = lists:flatten(io_lib:format("Hook for ~p failed!~n", [Command])), rebar_utils:sh(Hook, [use_stdout, {cd, Dir}, {env, Env}, {abort_on_error, Msg}]). -create_env(State) -> - BaseDir = rebar_state:dir(State), +create_env(State, AppInfo) -> + Opts = rebar_app_info:opts(AppInfo), + BaseDir = rebar_dir:base_dir(State), [ {"REBAR_DEPS_DIR", filename:absname(rebar_dir:deps_dir(State))}, {"REBAR_BUILD_DIR", filename:absname(rebar_dir:base_dir(State))}, @@ -109,7 +114,7 @@ create_env(State) -> {"REBAR_GLOBAL_CACHE_DIR", filename:absname(rebar_dir:global_cache_dir(State))}, {"REBAR_TEMPLATE_DIR", filename:absname(rebar_dir:template_dir(State))}, {"REBAR_APP_DIRS", join_dirs(BaseDir, rebar_dir:lib_dirs(State))}, - {"REBAR_SRC_DIRS", join_dirs(BaseDir, rebar_dir:all_src_dirs(State))}, + {"REBAR_SRC_DIRS", join_dirs(BaseDir, rebar_dir:all_src_dirs(Opts))}, {"ERLANG_ERTS_VER", erlang:system_info(version)}, {"ERLANG_ROOT_DIR", code:root_dir()}, {"ERLANG_LIB_DIR_erl_interface", code:lib_dir(erl_interface)}, diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index 507da70..c1d90bc 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -106,7 +106,7 @@ preprocess(State, AppInfo, AppSrcFile) -> %% substitute. Note that we include the list of modules available in %% ebin/ and update the app data accordingly. OutDir = rebar_app_info:out_dir(AppInfo), - AppVars = load_app_vars(State) ++ [{modules, ebin_modules(State, AppInfo, OutDir)}], + AppVars = load_app_vars(State) ++ [{modules, ebin_modules(AppInfo, OutDir)}], A1 = apply_app_vars(AppVars, AppData), %% AppSrcFile may contain instructions for generating a vsn number @@ -158,21 +158,21 @@ validate_name(AppName, File) -> ?PRV_ERROR({invalid_name, File, AppName}) end. -ebin_modules(State, App, Dir) -> +ebin_modules(AppInfo, Dir) -> Beams = lists:sort(rebar_utils:beams(filename:join(Dir, "ebin"))), - ExtraDirs = extra_dirs(State), - F = fun(Beam) -> not in_extra_dir(App, Beam, ExtraDirs) end, + ExtraDirs = extra_dirs(AppInfo), + F = fun(Beam) -> not in_extra_dir(AppInfo, Beam, ExtraDirs) end, Filtered = lists:filter(F, Beams), [rebar_utils:beam_to_mod(N) || N <- Filtered]. extra_dirs(State) -> - Extras = rebar_dir:extra_src_dirs(State), - SrcDirs = rebar_dir:src_dirs(State, ["src"]), + Extras = rebar_dir:extra_src_dirs(rebar_app_info:opts(State)), + SrcDirs = rebar_dir:src_dirs(rebar_app_info:opts(State), ["src"]), %% remove any dirs that are defined in `src_dirs` from `extra_src_dirs` Extras -- SrcDirs. -in_extra_dir(App, Beam, Dirs) -> - lists:any(fun(Dir) -> lists:prefix(filename:join([rebar_app_info:out_dir(App), Dir]), +in_extra_dir(AppInfo, Beam, Dirs) -> + lists:any(fun(Dir) -> lists:prefix(filename:join([rebar_app_info:out_dir(AppInfo), Dir]), beam_src(Beam)) end, Dirs). diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index 6c2daef..752514c 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -4,7 +4,7 @@ -module(rebar_plugins). -export([project_apps_install/1 - ,install/1 + ,install/2 ,handle_plugins/3 ,handle_plugins/4]). @@ -23,20 +23,19 @@ project_apps_install(State) -> Plugins = rebar_state:get(State, {plugins, Profile}, []), StateAcc1 = handle_plugins(Profile, Plugins, StateAcc), - lists:foldl(fun(App, StateAcc2) -> - AppDir = rebar_app_info:dir(App), - C = rebar_config:consult(AppDir), - S = rebar_state:new(rebar_state:new(), C, AppDir), - Plugins2 = rebar_state:get(S, {plugins, Profile}, []), + lists:foldl(fun(AppInfo, StateAcc2) -> + C = rebar_config:consult(rebar_app_info:dir(AppInfo)), + AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), + Plugins2 = rebar_state:get(AppInfo0, {plugins, Profile}, []), handle_plugins(Profile, Plugins2, StateAcc2) end, StateAcc1, ProjectApps) end, State, Profiles). --spec install(rebar_state:t()) -> rebar_state:t(). -install(State) -> +-spec install(rebar_state:t(), rebar_app_info:t()) -> rebar_state:t(). +install(State, AppInfo) -> Profiles = rebar_state:current_profiles(State), lists:foldl(fun(Profile, StateAcc) -> - Plugins = rebar_state:get(State, {plugins, Profile}, []), + Plugins = rebar_app_info:get(AppInfo, {plugins, Profile}, []), handle_plugins(Profile, Plugins, StateAcc) end, State, Profiles). @@ -92,10 +91,10 @@ handle_plugin(Profile, Plugin, State, Upgrade) -> build_plugin(AppInfo, Apps, State) -> Providers = rebar_state:providers(State), - Providers1 = rebar_state:providers(rebar_app_info:state(AppInfo)), + %Providers1 = rebar_state:providers(rebar_app_info:state(AppInfo)), S = rebar_state:all_deps(rebar_app_info:state_or_new(State, AppInfo), Apps), S1 = rebar_state:set(S, deps_dir, ?DEFAULT_PLUGINS_DIR), - rebar_prv_compile:compile(S1, Providers++Providers1, AppInfo). + rebar_prv_compile:compile(S1, Providers, AppInfo). plugin_providers({Plugin, _, _, _}) when is_atom(Plugin) -> validate_plugin(Plugin); diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index f10d12b..1d1d4c7 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -50,9 +50,9 @@ do(State) -> clean_apps(EmptyState, Providers, DepApps), Cwd = rebar_dir:get_cwd(), - rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), clean_apps(State, Providers, ProjectApps), - rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), {ok, State}. @@ -70,9 +70,9 @@ clean_apps(State, Providers, Apps) -> S = rebar_app_info:state_or_new(State, AppInfo), ?INFO("Cleaning out ~s...", [rebar_app_info:name(AppInfo)]), - rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, S), + rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, S), rebar_erlc_compiler:clean(State, rebar_app_info:out_dir(AppInfo)), - rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S) + rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, S) end, Apps). handle_args(State) -> diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index 25e9dad..aafc425 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -43,12 +43,12 @@ do(State) -> %% Run ct provider prehooks Providers = rebar_state:providers(State), Cwd = rebar_dir:get_cwd(), - rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), try run_test(State) of {ok, State1} = Result -> %% Run ct provider posthooks - rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1), + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State1), rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)), Result; ?PRV_ERROR(_) = Error -> @@ -307,7 +307,7 @@ copy(State, Dir) -> compile_dir(State, Dir) -> NewState = replace_src_dirs(State, [filename:absname(Dir)]), - ok = rebar_erlc_compiler:compile(NewState, rebar_dir:base_dir(State), Dir), + ok = rebar_erlc_compiler:compile(rebar_state:opts(NewState), rebar_dir:base_dir(State), Dir), ok = maybe_cover_compile(State, Dir), Dir. diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 74be7a6..072255d 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -52,7 +52,7 @@ do(State) -> {ok, ProjectApps1} = rebar_digraph:compile_order(ProjectApps), %% Run top level hooks *before* project apps compiled but *after* deps are - rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), ProjectApps2 = build_apps(State, Providers, ProjectApps1), State2 = rebar_state:project_apps(State, ProjectApps2), @@ -60,7 +60,7 @@ do(State) -> ProjAppsPaths = [filename:join(rebar_app_info:out_dir(X), "ebin") || X <- ProjectApps2], State3 = rebar_state:code_paths(State2, all_deps, DepsPaths ++ ProjAppsPaths), - rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State2), + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State2), has_all_artifacts(State3), rebar_utils:cleanup_code_path(rebar_state:code_paths(State3, default) @@ -80,7 +80,7 @@ build_apps(State, Providers, Apps) -> build_app(State, Providers, AppInfo) -> AppDir = rebar_app_info:dir(AppInfo), OutDir = rebar_app_info:out_dir(AppInfo), - copy_app_dirs(State, AppDir, OutDir), + copy_app_dirs(AppInfo, AppDir, OutDir), S = rebar_app_info:state_or_new(State, AppInfo), S1 = rebar_state:all_deps(S, rebar_state:all_deps(State)), @@ -89,12 +89,12 @@ build_app(State, Providers, AppInfo) -> compile(State, Providers, AppInfo) -> ?INFO("Compiling ~s", [rebar_app_info:name(AppInfo)]), AppDir = rebar_app_info:dir(AppInfo), - rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, State), - rebar_erlc_compiler:compile(State, ec_cnv:to_list(rebar_app_info:out_dir(AppInfo))), + rebar_erlc_compiler:compile(AppInfo), case rebar_otp_app:compile(State, AppInfo) of {ok, AppInfo1} -> - rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, State), + rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, State), has_all_artifacts(State), AppInfo1; Error -> @@ -113,7 +113,7 @@ has_all_artifacts(State) -> true end. -copy_app_dirs(State, OldAppDir, AppDir) -> +copy_app_dirs(AppInfo, OldAppDir, AppDir) -> case ec_cnv:to_binary(filename:absname(OldAppDir)) =/= ec_cnv:to_binary(filename:absname(AppDir)) of true -> @@ -142,7 +142,7 @@ copy_app_dirs(State, OldAppDir, AppDir) -> end, %% link to src_dirs to be adjacent to ebin is needed for R15 use of cover/xref - SrcDirs = rebar_dir:all_src_dirs(State, ["src"], []), + SrcDirs = rebar_dir:all_src_dirs(rebar_app_info:opts(AppInfo), ["src"], []), [symlink_or_copy(OldAppDir, AppDir, Dir) || Dir <- ["priv", "include"] ++ SrcDirs]; false -> ok diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index ca9344b..06033f6 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -254,28 +254,29 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> Profiles = rebar_state:current_profiles(State), Name = rebar_app_info:name(AppInfo), - %% Deps may be under a sub project app, find it and use its state if so - S = rebar_app_info:state(AppInfo), C = rebar_config:consult(rebar_app_info:dir(AppInfo)), - S1 = rebar_state:new(S, C, AppInfo), - S2 = rebar_state:apply_overrides(S1, Name), + AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), + AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), - S3 = rebar_state:apply_profiles(S2, Profiles), - Plugins = rebar_state:get(S3, plugins, []), - S4 = rebar_state:set(S3, {plugins, Profile}, Plugins), + AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, Profiles), + Plugins = rebar_app_info:get(AppInfo2, plugins, []), + AppInfo3 = rebar_app_info:set(AppInfo2, {plugins, Profile}, Plugins), - rebar_utils:check_min_otp_version(rebar_state:get(S4, minimum_otp_vsn, undefined)), - rebar_utils:check_blacklisted_otp_versions(rebar_state:get(S4, blacklisted_otp_vsns, [])), + rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo3, minimum_otp_vsn, undefined)), + rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo3, blacklisted_otp_vsns, [])), %% Dep may have plugins to install. Find and install here. - S5 = rebar_plugins:install(S4), - AppInfo1 = rebar_app_info:state(AppInfo, S5), + _S = rebar_plugins:install(State, AppInfo3), + %% TODO: Plugin Providers?? + + %AppInfo1 = rebar_app_info:state(AppInfo, S5), + %AppInfo2 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S5)), %% Upgrade lock level to be the level the dep will have in this dep tree - Deps = rebar_state:get(S5, {deps, default}, []), - AppInfo2 = rebar_app_info:deps(AppInfo1, rebar_state:deps_names(Deps)), - Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, S5, Locks, Level+1), - {AppInfo2, Deps1, State}. + Deps = rebar_app_info:get(AppInfo3, {deps, default}, []), + AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)), + Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, State, Locks, Level+1), + {AppInfo4, Deps1, State}. -spec maybe_fetch(rebar_app_info:t(), atom(), boolean(), sets:set(binary()), rebar_state:t()) -> {boolean(), rebar_app_info:t()}. @@ -420,4 +421,4 @@ warn_skip_deps(AppInfo, State) -> not_needs_compile(App) -> not(rebar_app_info:is_checkout(App)) andalso rebar_app_info:valid(App) - andalso rebar_state:has_all_artifacts(rebar_app_info:state(App)) =:= true. + andalso rebar_app_info:has_all_artifacts(App) =:= true. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 02a2262..cf6e8e8 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -26,7 +26,10 @@ %% ------------------------------------------------------------------- -module(rebar_utils). --export([sort_deps/1, +-export([get/2, + get/3, + set/3, + sort_deps/1, droplast/1, filtermap/2, is_arch/1, @@ -80,6 +83,21 @@ %% Public API %% ==================================================================== +get(Opts, Key) -> + {ok, Value} = dict:find(Key, Opts), + Value. + +get(Opts, Key, Default) -> + case dict:find(Key, Opts) of + {ok, Value} -> + Value; + error -> + Default + end. + +set(Opts, Key, Value) -> + dict:store(Key, Value, Opts). + sort_deps(Deps) -> %% We need a sort stable, based on the name. So that for multiple deps on %% the same level with the same name, we keep the order the parents had. @@ -219,11 +237,11 @@ deprecated(Old, New, When) -> [Old, Old, New, Old, When]). %% @doc Return list of erl_opts --spec erl_opts(rebar_state:t()) -> list(). -erl_opts(Config) -> - RawErlOpts = filter_defines(rebar_state:get(Config, erl_opts, []), []), +-spec erl_opts(rebar_app_info:t()) -> list(). +erl_opts(AppInfo) -> + RawErlOpts = filter_defines(rebar_utils:get(AppInfo, erl_opts, []), []), Defines = [{d, list_to_atom(D)} || - D <- rebar_state:get(Config, defines, [])], + D <- rebar_utils:get(AppInfo, defines, [])], Opts = Defines ++ RawErlOpts, case proplists:is_defined(no_debug_info, Opts) of true -> diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index a3c5052..6fbc081 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -28,39 +28,39 @@ end_per_testcase(_, _Config) -> ok. default_src_dirs(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return), - - [] = rebar_dir:src_dirs(State), - ["src"] = rebar_dir:src_dirs(State, ["src"]). + + [] = rebar_dir:src_dirs(rebar_state:opts(State)), + ["src"] = rebar_dir:src_dirs(rebar_state:opts(State), ["src"]). default_extra_src_dirs(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return), - - [] = rebar_dir:extra_src_dirs(State), - ["src"] = rebar_dir:extra_src_dirs(State, ["src"]). + + [] = rebar_dir:extra_src_dirs(rebar_state:opts(State)), + ["src"] = rebar_dir:extra_src_dirs(rebar_state:opts(State), ["src"]). default_all_src_dirs(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return), - - [] = rebar_dir:all_src_dirs(State), - ["src", "test"] = rebar_dir:all_src_dirs(State, ["src"], ["test"]). + + [] = rebar_dir:all_src_dirs(rebar_state:opts(State)), + ["src", "test"] = rebar_dir:all_src_dirs(rebar_state:opts(State), ["src"], ["test"]). src_dirs(Config) -> RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - - ["foo", "bar", "baz"] = rebar_dir:src_dirs(State). + + ["foo", "bar", "baz"] = rebar_dir:src_dirs(rebar_state:opts(State)). extra_src_dirs(Config) -> RebarConfig = [{erl_opts, [{extra_src_dirs, ["foo", "bar", "baz"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - - ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(State). + + ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(rebar_state:opts(State)). all_src_dirs(Config) -> RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}, {extra_src_dirs, ["baz", "qux"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - - ["foo", "bar", "baz", "qux"] = rebar_dir:all_src_dirs(State). + + ["foo", "bar", "baz", "qux"] = rebar_dir:all_src_dirs(rebar_state:opts(State)). profile_src_dirs(Config) -> RebarConfig = [ @@ -70,9 +70,9 @@ profile_src_dirs(Config) -> ]} ], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return), - + R = lists:sort(["foo", "bar", "baz", "qux"]), - R = lists:sort(rebar_dir:src_dirs(State)). + R = lists:sort(rebar_dir:src_dirs(rebar_state:opts(State))). profile_extra_src_dirs(Config) -> RebarConfig = [ @@ -82,9 +82,9 @@ profile_extra_src_dirs(Config) -> ]} ], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return), - + R = lists:sort(["foo", "bar", "baz", "qux"]), - R = lists:sort(rebar_dir:extra_src_dirs(State)). + R = lists:sort(rebar_dir:extra_src_dirs(rebar_state:opts(State))). profile_all_src_dirs(Config) -> RebarConfig = [ @@ -94,6 +94,6 @@ profile_all_src_dirs(Config) -> ]} ], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return), - + R = lists:sort(["foo", "bar", "baz", "qux"]), - R = lists:sort(rebar_dir:all_src_dirs(State)). + R = lists:sort(rebar_dir:all_src_dirs(rebar_state:opts(State))). diff --git a/test/rebar_src_dirs_SUITE.erl b/test/rebar_src_dirs_SUITE.erl index e322190..e29dcf0 100644 --- a/test/rebar_src_dirs_SUITE.erl +++ b/test/rebar_src_dirs_SUITE.erl @@ -49,7 +49,7 @@ src_dirs_at_root(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["foo", "bar", "baz"] = rebar_dir:src_dirs(State, []). + ["foo", "bar", "baz"] = rebar_dir:src_dirs(rebar_state:opts(State), []). extra_src_dirs_at_root(Config) -> AppDir = ?config(apps, Config), @@ -62,7 +62,7 @@ extra_src_dirs_at_root(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(State, []). + ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(rebar_state:opts(State), []). src_dirs_in_erl_opts(Config) -> AppDir = ?config(apps, Config), @@ -75,7 +75,7 @@ src_dirs_in_erl_opts(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["foo", "bar", "baz"] = rebar_dir:src_dirs(State, []). + ["foo", "bar", "baz"] = rebar_dir:src_dirs(rebar_state:opts(State), []). extra_src_dirs_in_erl_opts(Config) -> AppDir = ?config(apps, Config), @@ -88,7 +88,7 @@ extra_src_dirs_in_erl_opts(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(State, []). + ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(rebar_state:opts(State), []). src_dirs_at_root_and_in_erl_opts(Config) -> AppDir = ?config(apps, Config), @@ -101,7 +101,7 @@ src_dirs_at_root_and_in_erl_opts(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["baz", "qux", "foo", "bar"] = rebar_dir:src_dirs(State, []). + ["baz", "qux", "foo", "bar"] = rebar_dir:src_dirs(rebar_state:opts(State), []). extra_src_dirs_at_root_and_in_erl_opts(Config) -> AppDir = ?config(apps, Config), @@ -114,7 +114,7 @@ extra_src_dirs_at_root_and_in_erl_opts(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["baz", "qux", "foo", "bar"] = rebar_dir:extra_src_dirs(State, []). + ["baz", "qux", "foo", "bar"] = rebar_dir:extra_src_dirs(rebar_state:opts(State), []). build_basic_app(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From f209ccc2b8ea79279532f1fe1debe24aa0e6a488 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 29 Aug 2015 17:07:18 -0500 Subject: remove state record from app_info record --- src/rebar_app_discover.erl | 3 +-- src/rebar_app_info.erl | 31 ------------------------------- src/rebar_app_utils.erl | 1 - src/rebar_plugins.erl | 3 ++- src/rebar_prv_clean.erl | 6 +++--- src/rebar_prv_compile.erl | 4 ++-- src/rebar_prv_install_deps.erl | 6 +++--- test/rebar_profiles_SUITE.erl | 3 +-- 8 files changed, 12 insertions(+), 45 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index bc66c1f..e32a9f5 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -88,8 +88,7 @@ merge_deps(AppInfo, State) -> rebar_utils:check_blacklisted_otp_versions(rebar_state:get(AppState1, blacklisted_otp_vsns, [])), AppState2 = rebar_state:set(AppState1, artifacts, []), - AppInfo1 = rebar_app_info:state(AppInfo, AppState2), - AppInfo2 = rebar_app_info:opts(AppInfo1, rebar_state:opts(AppState2)), + AppInfo2 = rebar_app_info:opts(AppInfo, rebar_state:opts(AppState2)), State1 = lists:foldl(fun(Profile, StateAcc) -> handle_profile(Profile, Name, AppState1, StateAcc) diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index ef8f69d..21fbbea 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -9,8 +9,6 @@ discover/1, name/1, name/2, - config/1, - config/2, app_file_src/1, app_file_src/2, app_file_src_script/1, @@ -47,9 +45,6 @@ resource_type/2, source/1, source/2, - state/1, - state/2, - state_or_new/2, is_lock/1, is_lock/2, is_checkout/1, @@ -76,7 +71,6 @@ app_file_src :: file:filename_all() | undefined, app_file_src_script:: file:filename_all() | undefined, app_file :: file:filename_all() | undefined, - config :: rebar_state:t() | undefined, original_vsn :: binary() | string() | undefined, parent=root :: binary() | root, app_details=[] :: list(), @@ -90,7 +84,6 @@ out_dir :: file:name(), resource_type :: pkg | src, source :: string() | tuple() | undefined, - state :: rebar_state:t() | undefined, is_lock=false :: boolean(), is_checkout=false :: boolean(), valid :: boolean()}). @@ -194,14 +187,6 @@ name(#app_info_t{name=Name}) -> name(AppInfo=#app_info_t{}, AppName) -> AppInfo#app_info_t{name=ec_cnv:to_binary(AppName)}. --spec config(t()) -> rebar_state:t(). -config(#app_info_t{config=Config}) -> - Config. - --spec config(t(), rebar_state:t()) -> t(). -config(AppInfo=#app_info_t{}, Config) -> - AppInfo#app_info_t{config=Config}. - opts(#app_info_t{opts=Opts}) -> Opts. @@ -384,22 +369,6 @@ 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 state_or_new(rebar_state:t(), t()) -> rebar_state:t(). -state_or_new(State, AppInfo=#app_info_t{state=undefined}) -> - AppDir = dir(AppInfo), - C = rebar_config:consult(AppDir), - rebar_state:new(State, C, AppInfo); -state_or_new(_State, #app_info_t{state=State}) -> - State. - -spec is_lock(t(), boolean()) -> t(). is_lock(AppInfo=#app_info_t{}, IsLock) -> AppInfo#app_info_t{is_lock=IsLock}. diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 07c262a..3c27420 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -176,7 +176,6 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> Overrides = rebar_state:get(State, overrides, []), ParentOverrides = rebar_state:overrides(State), S1 = rebar_state:set(rebar_state:overrides(State, ParentOverrides++Overrides), base_dir, BaseDir), - %AppInfo2 = rebar_app_info:state(AppInfo1, S1), AppInfo3 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S1)), rebar_app_info:is_lock(rebar_app_info:source(AppInfo3, Source), IsLock). diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index 752514c..80f62f5 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -92,7 +92,8 @@ handle_plugin(Profile, Plugin, State, Upgrade) -> build_plugin(AppInfo, Apps, State) -> Providers = rebar_state:providers(State), %Providers1 = rebar_state:providers(rebar_app_info:state(AppInfo)), - S = rebar_state:all_deps(rebar_app_info:state_or_new(State, AppInfo), Apps), + %rebar_app_info:state_or_new(State, AppInfo) + S = rebar_state:all_deps(State, Apps), S1 = rebar_state:set(S, deps_dir, ?DEFAULT_PLUGINS_DIR), rebar_prv_compile:compile(S1, Providers, AppInfo). diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index 1d1d4c7..fa8bcf3 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -67,12 +67,12 @@ format_error(Reason) -> clean_apps(State, Providers, Apps) -> lists:foreach(fun(AppInfo) -> AppDir = rebar_app_info:dir(AppInfo), - S = rebar_app_info:state_or_new(State, AppInfo), + %S = rebar_app_info:state_or_new(State, AppInfo), ?INFO("Cleaning out ~s...", [rebar_app_info:name(AppInfo)]), - rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, S), + rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, State), rebar_erlc_compiler:clean(State, rebar_app_info:out_dir(AppInfo)), - rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, S) + rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, State) end, Apps). handle_args(State) -> diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 072255d..1675a41 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -82,8 +82,8 @@ build_app(State, Providers, AppInfo) -> OutDir = rebar_app_info:out_dir(AppInfo), copy_app_dirs(AppInfo, AppDir, OutDir), - S = rebar_app_info:state_or_new(State, AppInfo), - S1 = rebar_state:all_deps(S, rebar_state:all_deps(State)), + %S = rebar_app_info:state_or_new(State, AppInfo), + S1 = rebar_state:all_deps(State, rebar_state:all_deps(State)), compile(S1, Providers, AppInfo). compile(State, Providers, AppInfo) -> diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 06033f6..58557bf 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -294,9 +294,9 @@ maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) -> {true, rebar_app_info:valid(update_app_info(AppDir, AppInfo), false)}; {true, AppInfo1} -> %% Preserve the state we created with overrides - AppInfo2 = copy_app_info(AppInfo, AppInfo1), - AppState = rebar_app_info:state(AppInfo), - AppInfo3 = rebar_app_info:state(AppInfo2, AppState), + AppInfo3 = copy_app_info(AppInfo, AppInfo1), + %% AppState = rebar_app_info:state(AppInfo), + %% AppInfo3 = rebar_app_info:state(AppInfo2, AppState), case sets:is_element(rebar_app_info:name(AppInfo3), Seen) of true -> {false, AppInfo3}; diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 41bb535..d4c10c5 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -428,8 +428,7 @@ test_profile_applied_to_apps(Config) -> Apps = rebar_state:project_apps(State), lists:foreach(fun(App) -> - AppState = rebar_app_info:state(App), - Opts = rebar_state:opts(AppState), + Opts = rebar_app_info:opts(App), ErlOpts = dict:fetch(erl_opts, Opts), true = lists:member({d, 'TEST'}, ErlOpts) end, Apps). -- cgit v1.1 From 3aec31f0bcc6b8b0e240e25f9ec4baed27e51b5a Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 29 Aug 2015 17:28:05 -0500 Subject: fix erl_opts to not be inherited --- src/rebar_app_utils.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 3c27420..87d5d00 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -157,7 +157,7 @@ pkg_to_app(Parent, DepsDir, AppName, PkgName, PkgVsn, IsLock, State) -> dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)), - BaseDir = rebar_state:get(State, base_dir, []), + %BaseDir = rebar_state:get(State, base_dir, []), {ok, AppInfo} = case rebar_app_info:discover(CheckoutsDir) of {ok, App} -> {ok, rebar_app_info:is_checkout(App, true)}; @@ -173,11 +173,11 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> C = rebar_config:consult(rebar_app_info:dir(AppInfo)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), - Overrides = rebar_state:get(State, overrides, []), - ParentOverrides = rebar_state:overrides(State), - S1 = rebar_state:set(rebar_state:overrides(State, ParentOverrides++Overrides), base_dir, BaseDir), - AppInfo3 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S1)), - rebar_app_info:is_lock(rebar_app_info:source(AppInfo3, Source), IsLock). + %Overrides = rebar_state:get(State, overrides, []), + %ParentOverrides = rebar_state:overrides(State), + %% S1 = rebar_state:set(rebar_state:overrides(State, ParentOverrides++Overrides), base_dir, BaseDir), + %% AppInfo3 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S1)), + rebar_app_info:is_lock(rebar_app_info:source(AppInfo1, Source), IsLock). format_error({missing_package, Package}) -> io_lib:format("Package not found in registry: ~s", [Package]); -- cgit v1.1 From 32d07ec0767524c8bdf0321c70a741ab64dedd78 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 29 Aug 2015 21:41:58 -0500 Subject: build on already created AppInfo instead of having to do copy --- src/rebar_app_discover.erl | 58 ++++++++++++----------- src/rebar_app_info.erl | 7 ++- src/rebar_app_utils.erl | 5 -- src/rebar_dir.erl | 34 +++++++------- src/rebar_erlc_compiler.erl | 104 ++++++++++++++++++++--------------------- src/rebar_prv_install_deps.erl | 43 ++++------------- src/rebar_utils.erl | 16 +++---- 7 files changed, 125 insertions(+), 142 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index e32a9f5..08502a9 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -5,7 +5,8 @@ find_unbuilt_apps/1, find_apps/1, find_apps/2, - find_app/2]). + find_app/2, + find_app/3]). -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). @@ -183,41 +184,46 @@ find_apps(LibDirs, Validate) -> -spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false. find_app(AppDir, Validate) -> + find_app(rebar_app_info:new(), AppDir, Validate). + +find_app(AppInfo, AppDir, Validate) -> AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])), AppSrcFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])), AppSrcScriptFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src.script"])), - AppInfo = try_handle_app_file(AppFile, AppDir, AppSrcFile, AppSrcScriptFile, Validate), - AppInfo. + try_handle_app_file(AppInfo, AppFile, AppDir, AppSrcFile, AppSrcScriptFile, Validate). app_dir(AppFile) -> filename:join(rebar_utils:droplast(filename:split(filename:dirname(AppFile)))). --spec create_app_info(file:name(), file:name()) -> rebar_app_info:t(). -create_app_info(AppDir, AppFile) -> +-spec create_app_info(rebar_app_info:t(), file:name(), file:name()) -> rebar_app_info:t(). +create_app_info(AppInfo, AppDir, AppFile) -> [{application, AppName, AppDetails}] = rebar_config:consult_app_file(AppFile), AppVsn = proplists:get_value(vsn, AppDetails), Applications = proplists:get_value(applications, AppDetails, []), IncludedApplications = proplists:get_value(included_applications, AppDetails, []), - {ok, AppInfo} = rebar_app_info:new(AppName, AppVsn, AppDir), - AppInfo1 = rebar_app_info:applications( - rebar_app_info:app_details(AppInfo, AppDetails), + AppInfo1 = rebar_app_info:name( + rebar_app_info:original_vsn( + rebar_app_info:dir(AppInfo, AppDir), AppVsn), AppName), + AppInfo2 = rebar_app_info:applications( + rebar_app_info:app_details(AppInfo1, AppDetails), IncludedApplications++Applications), - Valid = case rebar_app_utils:validate_application_info(AppInfo1) of + Valid = case rebar_app_utils:validate_application_info(AppInfo2) =:= true + andalso rebar_app_info:has_all_artifacts(AppInfo2) =:= true of true -> true; _ -> false end, - rebar_app_info:dir(rebar_app_info:valid(AppInfo1, Valid), AppDir). + rebar_app_info:dir(rebar_app_info:valid(AppInfo2, Valid), AppDir). %% Read in and parse the .app file if it is availabe. Do the same for %% the .app.src file if it exists. -try_handle_app_file([], AppDir, [], AppSrcScriptFile, Validate) -> - try_handle_app_src_file([], AppDir, AppSrcScriptFile, Validate); -try_handle_app_file([], AppDir, AppSrcFile, _, Validate) -> - try_handle_app_src_file([], AppDir, AppSrcFile, Validate); -try_handle_app_file([File], AppDir, AppSrcFile, _, Validate) -> - try create_app_info(AppDir, File) of +try_handle_app_file(AppInfo, [], AppDir, [], AppSrcScriptFile, Validate) -> + try_handle_app_src_file(AppInfo, [], AppDir, AppSrcScriptFile, Validate); +try_handle_app_file(AppInfo, [], AppDir, AppSrcFile, _, Validate) -> + try_handle_app_src_file(AppInfo, [], AppDir, AppSrcFile, Validate); +try_handle_app_file(AppInfo0, [File], AppDir, AppSrcFile, _, Validate) -> + try create_app_info(AppInfo0, AppDir, File) of AppInfo -> AppInfo1 = rebar_app_info:app_file(AppInfo, File), AppInfo2 = case AppSrcFile of @@ -249,26 +255,26 @@ try_handle_app_file([File], AppDir, AppSrcFile, _, Validate) -> catch throw:{error, {Module, Reason}} -> ?DEBUG("Falling back to app.src file because .app failed: ~s", [Module:format_error(Reason)]), - try_handle_app_src_file(File, AppDir, AppSrcFile, Validate) + try_handle_app_src_file(AppInfo0, File, AppDir, AppSrcFile, Validate) end; -try_handle_app_file(Other, _AppDir, _AppSrcFile, _, _Validate) -> +try_handle_app_file(_AppInfo, Other, _AppDir, _AppSrcFile, _, _Validate) -> throw({error, {multiple_app_files, Other}}). %% Read in the .app.src file if we aren't looking for a valid (already built) app -try_handle_app_src_file(_, _AppDir, [], _Validate) -> +try_handle_app_src_file(_AppInfo, _, _AppDir, [], _Validate) -> false; -try_handle_app_src_file(_, _AppDir, _AppSrcFile, valid) -> +try_handle_app_src_file(_AppInfo, _, _AppDir, _AppSrcFile, valid) -> false; -try_handle_app_src_file(_, AppDir, [File], Validate) when Validate =:= invalid - ; Validate =:= all -> - AppInfo = create_app_info(AppDir, File), +try_handle_app_src_file(AppInfo, _, AppDir, [File], Validate) when Validate =:= invalid + ; Validate =:= all -> + AppInfo1 = create_app_info(AppInfo, AppDir, File), case filename:extension(File) of ".script" -> - {true, rebar_app_info:app_file_src_script(AppInfo, File)}; + {true, rebar_app_info:app_file_src_script(AppInfo1, File)}; _ -> - {true, rebar_app_info:app_file_src(AppInfo, File)} + {true, rebar_app_info:app_file_src(AppInfo1, File)} end; -try_handle_app_src_file(_, _AppDir, Other, _Validate) -> +try_handle_app_src_file(_AppInfo, _, _AppDir, Other, _Validate) -> throw({error, {multiple_app_files, Other}}). enable(State, AppInfo) -> diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 21fbbea..3ace5e4 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -1,6 +1,7 @@ -module(rebar_app_info). --export([new/1, +-export([new/0, + new/1, new/2, new/3, new/4, @@ -98,6 +99,10 @@ %% ============================================================================ %% @doc Build a new, empty, app info value. This is not of a lot of use and you %% probably wont be doing this much. +-spec new() -> t(). +new() -> + #app_info_t{}. + -spec new(atom() | binary() | string()) -> {ok, t()}. new(AppName) -> diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 87d5d00..2509c7d 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -157,7 +157,6 @@ pkg_to_app(Parent, DepsDir, AppName, PkgName, PkgVsn, IsLock, State) -> dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)), - %BaseDir = rebar_state:get(State, base_dir, []), {ok, AppInfo} = case rebar_app_info:discover(CheckoutsDir) of {ok, App} -> {ok, rebar_app_info:is_checkout(App, true)}; @@ -173,10 +172,6 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> C = rebar_config:consult(rebar_app_info:dir(AppInfo)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), - %Overrides = rebar_state:get(State, overrides, []), - %ParentOverrides = rebar_state:overrides(State), - %% S1 = rebar_state:set(rebar_state:overrides(State, ParentOverrides++Overrides), base_dir, BaseDir), - %% AppInfo3 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S1)), rebar_app_info:is_lock(rebar_app_info:source(AppInfo1, Source), IsLock). format_error({missing_package, Package}) -> diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl index af6696e..39fa723 100644 --- a/src/rebar_dir.erl +++ b/src/rebar_dir.erl @@ -129,34 +129,34 @@ do_make_relative_path(Source, Target) -> Base = lists:duplicate(max(length(Target) - 1, 0), ".."), filename:join(Base ++ Source). --spec src_dirs(rebar_app_info:t()) -> list(file:filename_all()). -src_dirs(State) -> src_dirs(State, []). +-spec src_dirs(rebar_dict()) -> list(file:filename_all()). +src_dirs(Opts) -> src_dirs(Opts, []). --spec src_dirs(rebar_app_info:t(), list(file:filename_all())) -> list(file:filename_all()). -src_dirs(AppInfo, Default) -> - ErlOpts = rebar_utils:erl_opts(AppInfo), +-spec src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()). +src_dirs(Opts, Default) -> + ErlOpts = rebar_utils:erl_opts(Opts), Vs = proplists:get_all_values(src_dirs, ErlOpts), - case lists:append([rebar_utils:get(AppInfo, src_dirs, []) | Vs]) of + case lists:append([rebar_utils:get(Opts, src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. --spec extra_src_dirs(rebar_app_info:t()) -> list(file:filename_all()). -extra_src_dirs(AppInfo) -> extra_src_dirs(AppInfo, []). +-spec extra_src_dirs(rebar_dict()) -> list(file:filename_all()). +extra_src_dirs(Opts) -> extra_src_dirs(Opts, []). --spec extra_src_dirs(rebar_app_info:t(), list(file:filename_all())) -> list(file:filename_all()). -extra_src_dirs(AppInfo, Default) -> - ErlOpts = rebar_utils:erl_opts(AppInfo), +-spec extra_src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()). +extra_src_dirs(Opts, Default) -> + ErlOpts = rebar_utils:erl_opts(Opts), Vs = proplists:get_all_values(extra_src_dirs, ErlOpts), - case lists:append([rebar_utils:get(AppInfo, extra_src_dirs, []) | Vs]) of + case lists:append([rebar_utils:get(Opts, extra_src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. --spec all_src_dirs(rebar_app_info:t()) -> list(file:filename_all()). -all_src_dirs(AppInfo) -> all_src_dirs(AppInfo, [], []). +-spec all_src_dirs(rebar_dict()) -> list(file:filename_all()). +all_src_dirs(Opts) -> all_src_dirs(Opts, [], []). --spec all_src_dirs(rebar_app_info:t(), list(file:filename_all()), list(file:filename_all())) -> +-spec all_src_dirs(rebar_dict(), list(file:filename_all()), list(file:filename_all())) -> list(file:filename_all()). -all_src_dirs(AppInfo, SrcDefault, ExtraDefault) -> - src_dirs(AppInfo, SrcDefault) ++ extra_src_dirs(AppInfo, ExtraDefault). +all_src_dirs(Opts, SrcDefault, ExtraDefault) -> + src_dirs(Opts, SrcDefault) ++ extra_src_dirs(Opts, ExtraDefault). diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 69b5f29..2b3942c 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -85,27 +85,27 @@ compile(AppInfo) -> Dir = ec_cnv:to_list(rebar_app_info:out_dir(AppInfo)), compile(rebar_app_info:opts(AppInfo), Dir, filename:join([Dir, "ebin"])). --spec compile(rebar_app_info:t(), file:name(), file:name()) -> 'ok'. -compile(AppInfo, Dir, OutDir) -> - rebar_base_compiler:run(AppInfo, +-spec compile(rebar_dict(), file:name(), file:name()) -> 'ok'. +compile(Opts, Dir, OutDir) -> + rebar_base_compiler:run(Opts, check_files(rebar_utils:get( - AppInfo, xrl_first_files, [])), + Opts, xrl_first_files, [])), filename:join(Dir, "src"), ".xrl", filename:join(Dir, "src"), ".erl", fun compile_xrl/3), - rebar_base_compiler:run(AppInfo, + rebar_base_compiler:run(Opts, check_files(rebar_utils:get( - AppInfo, yrl_first_files, [])), + Opts, yrl_first_files, [])), filename:join(Dir, "src"), ".yrl", filename:join(Dir, "src"), ".erl", fun compile_yrl/3), - rebar_base_compiler:run(AppInfo, + rebar_base_compiler:run(Opts, check_files(rebar_utils:get( - AppInfo, mib_first_files, [])), + Opts, mib_first_files, [])), filename:join(Dir, "mibs"), ".mib", filename:join([Dir, "priv", "mibs"]), ".bin", fun compile_mib/3), - doterl_compile(AppInfo, Dir, OutDir). + doterl_compile(Opts, Dir, OutDir). --spec clean(rebar_app_info:t(), file:filename()) -> 'ok'. -clean(_AppInfo, AppDir) -> +-spec clean(rebar_dict(), file:filename()) -> 'ok'. +clean(_Opts, AppDir) -> MibFiles = rebar_utils:find_files(filename:join(AppDir, "mibs"), ?RE_PREFIX".*\\.mib\$"), MIBs = [filename:rootname(filename:basename(MIB)) || MIB <- MibFiles], rebar_file_utils:delete_each( @@ -134,17 +134,17 @@ clean(_AppInfo, AppDir) -> %% Internal functions %% =================================================================== --spec doterl_compile(rebar_app_info:t(), file:filename(), file:filename()) -> ok. -doterl_compile(State, Dir, ODir) -> - ErlOpts = rebar_utils:erl_opts(State), - doterl_compile(State, Dir, ODir, [], ErlOpts). +-spec doterl_compile(rebar_dict(), file:filename(), file:filename()) -> ok. +doterl_compile(Opts, Dir, ODir) -> + ErlOpts = rebar_utils:erl_opts(Opts), + doterl_compile(Opts, Dir, ODir, [], ErlOpts). -doterl_compile(AppInfo, Dir, OutDir, MoreSources, ErlOpts) -> +doterl_compile(Opts, Dir, OutDir, MoreSources, ErlOpts) -> ?DEBUG("erl_opts ~p", [ErlOpts]), %% Support the src_dirs option allowing multiple directories to %% contain erlang source. This might be used, for example, should %% eunit tests be separated from the core application source. - SrcDirs = [filename:join(Dir, X) || X <- rebar_dir:all_src_dirs(AppInfo, ["src"], [])], + SrcDirs = [filename:join(Dir, X) || X <- rebar_dir:all_src_dirs(Opts, ["src"], [])], AllErlFiles = gather_src(SrcDirs, []) ++ MoreSources, %% Make sure that ebin/ exists and is on the path @@ -156,7 +156,7 @@ doterl_compile(AppInfo, Dir, OutDir, MoreSources, ErlOpts) -> G = init_erlcinfo(proplists:get_all_values(i, ErlOpts), AllErlFiles, Dir, OutDir), NeededErlFiles = needed_files(G, ErlOpts, Dir, OutDir1, AllErlFiles), - {ErlFirstFiles, ErlOptsFirst} = erl_first_files(AppInfo, ErlOpts, Dir, NeededErlFiles), + {ErlFirstFiles, ErlOptsFirst} = erl_first_files(Opts, ErlOpts, Dir, NeededErlFiles), {DepErls, OtherErls} = lists:partition( fun(Source) -> digraph:in_degree(G, Source) > 0 end, [File || File <- NeededErlFiles, not lists:member(File, ErlFirstFiles)]), @@ -166,7 +166,7 @@ doterl_compile(AppInfo, Dir, OutDir, MoreSources, ErlOpts) -> ?DEBUG("Files to compile first: ~p", [FirstErls]), try rebar_base_compiler:run( - AppInfo, FirstErls, OtherErls, + Opts, FirstErls, OtherErls, fun(S, C) -> ErlOpts1 = case lists:member(S, ErlFirstFiles) of true -> ErlOptsFirst; @@ -183,8 +183,8 @@ doterl_compile(AppInfo, Dir, OutDir, MoreSources, ErlOpts) -> %% Get files which need to be compiled first, i.e. those specified in erl_first_files %% and parse_transform options. Also produce specific erl_opts for these first %% files, so that yet to be compiled parse transformations are excluded from it. -erl_first_files(AppInfo, ErlOpts, Dir, NeededErlFiles) -> - ErlFirstFilesConf = rebar_utils:get(AppInfo, erl_first_files, []), +erl_first_files(Opts, ErlOpts, Dir, NeededErlFiles) -> + ErlFirstFilesConf = rebar_utils:get(Opts, erl_first_files, []), NeededSrcDirs = lists:usort(lists:map(fun filename:dirname/1, NeededErlFiles)), %% NOTE: order of files here is important! ErlFirstFiles = @@ -209,10 +209,10 @@ needed_files(G, ErlOpts, Dir, OutDir, SourceFiles) -> lists:filter(fun(Source) -> TargetBase = target_base(OutDir, Source), Target = TargetBase ++ ".beam", - Opts = [{outdir, filename:dirname(Target)} + AllOpts = [{outdir, filename:dirname(Target)} ,{i, filename:join(Dir, "include")}] ++ ErlOpts, digraph:vertex(G, Source) > {Source, filelib:last_modified(Target)} - orelse opts_changed(Opts, TargetBase) + orelse opts_changed(AllOpts, TargetBase) end, SourceFiles). maybe_rm_beam_and_edge(G, OutDir, Source) -> @@ -403,40 +403,40 @@ expand_file_names(Files, Dirs) -> end, Files). --spec internal_erl_compile(rebar_app_info:t(), file:filename(), file:filename(), +-spec internal_erl_compile(rebar_dict(), file:filename(), file:filename(), file:filename(), list()) -> ok | {ok, any()} | {error, any(), any()}. -internal_erl_compile(AppInfo, Dir, Module, OutDir, ErlOpts) -> +internal_erl_compile(Opts, Dir, Module, OutDir, ErlOpts) -> Target = target_base(OutDir, Module) ++ ".beam", ok = filelib:ensure_dir(Target), - Opts = [{outdir, filename:dirname(Target)}] ++ ErlOpts ++ + AllOpts = [{outdir, filename:dirname(Target)}] ++ ErlOpts ++ [{i, filename:join(Dir, "include")}, return], - case compile:file(Module, Opts) of + case compile:file(Module, AllOpts) of {ok, _Mod} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(AppInfo, Module, Ws); + rebar_base_compiler:ok_tuple(Opts, Module, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(AppInfo, Module, Es, Ws, Opts) + rebar_base_compiler:error_tuple(Opts, Module, Es, Ws, Opts) end. target_base(OutDir, Source) -> filename:join(OutDir, filename:basename(Source, ".erl")). -spec compile_mib(file:filename(), file:filename(), - rebar_app_info:t()) -> 'ok'. -compile_mib(Source, Target, AppInfo) -> + rebar_dict()) -> 'ok'. +compile_mib(Source, Target, Opts) -> Dir = filename:dirname(Target), ok = filelib:ensure_dir(Target), ok = filelib:ensure_dir(filename:join([Dir, "include", "dummy.hrl"])), - Opts = [{outdir, Dir} - ,{i, [Dir]}] ++ - rebar_utils:get(AppInfo, mib_opts, []), + AllOpts = [{outdir, Dir} + ,{i, [Dir]}] ++ + rebar_utils:get(Opts, mib_opts, []), - case snmpc:compile(Source, Opts) of + case snmpc:compile(Source, AllOpts) of {ok, _} -> Mib = filename:rootname(Target), MibToHrlOpts = - case proplists:get_value(verbosity, Opts, undefined) of + case proplists:get_value(verbosity, AllOpts, undefined) of undefined -> #options{specific = []}; Verbosity -> @@ -451,33 +451,33 @@ compile_mib(Source, Target, AppInfo) -> end. -spec compile_xrl(file:filename(), file:filename(), - rebar_app_info:t()) -> 'ok'. -compile_xrl(Source, Target, AppInfo) -> - Opts = [{scannerfile, Target} | rebar_utils:get(AppInfo, xrl_opts, [])], - compile_xrl_yrl(AppInfo, Source, Target, Opts, leex). + rebar_dict()) -> 'ok'. +compile_xrl(Source, Target, Opts) -> + AllOpts = [{scannerfile, Target} | rebar_utils:get(Opts, xrl_opts, [])], + compile_xrl_yrl(Opts, Source, Target, AllOpts, leex). -spec compile_yrl(file:filename(), file:filename(), - rebar_app_info:t()) -> 'ok'. -compile_yrl(Source, Target, AppInfo) -> - Opts = [{parserfile, Target} | rebar_utils:get(AppInfo, yrl_opts, [])], - compile_xrl_yrl(AppInfo, Source, Target, Opts, yecc). + rebar_dict()) -> 'ok'. +compile_yrl(Source, Target, Opts) -> + AllOpts = [{parserfile, Target} | rebar_utils:get(Opts, yrl_opts, [])], + compile_xrl_yrl(Opts, Source, Target, AllOpts, yecc). --spec compile_xrl_yrl(rebar_app_info:t(), file:filename(), +-spec compile_xrl_yrl(rebar_dict(), file:filename(), file:filename(), list(), module()) -> 'ok'. -compile_xrl_yrl(AppInfo, Source, Target, Opts, Mod) -> +compile_xrl_yrl(Opts, Source, Target, AllOpts, Mod) -> Dir = filename:dirname(Target), - Opts1 = [{includefile, filename:join(Dir, I)} || {includefile, I} <- Opts, - filename:pathtype(I) =:= relative], + AllOpts1 = [{includefile, filename:join(Dir, I)} || {includefile, I} <- AllOpts, + filename:pathtype(I) =:= relative], case needs_compile(Source, Target) of true -> - case Mod:file(Source, Opts1 ++ [{return, true}]) of + case Mod:file(Source, AllOpts1 ++ [{return, true}]) of {ok, _} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(AppInfo, Source, Ws); + rebar_base_compiler:ok_tuple(Opts, Source, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(AppInfo, Source, - Es, Ws, Opts1) + rebar_base_compiler:error_tuple(Opts, Source, + Es, Ws, AllOpts1) end; false -> skipped diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 58557bf..6ae22d6 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -287,24 +287,20 @@ maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) -> true -> {false, AppInfo}; false -> - case rebar_app_discover:find_app(AppDir, all) of + case rebar_app_discover:find_app(AppInfo, AppDir, all) of false -> true = fetch_app(AppInfo, AppDir, State), maybe_symlink_default(State, Profile, AppDir, AppInfo), {true, rebar_app_info:valid(update_app_info(AppDir, AppInfo), false)}; {true, AppInfo1} -> - %% Preserve the state we created with overrides - AppInfo3 = copy_app_info(AppInfo, AppInfo1), - %% AppState = rebar_app_info:state(AppInfo), - %% AppInfo3 = rebar_app_info:state(AppInfo2, AppState), - case sets:is_element(rebar_app_info:name(AppInfo3), Seen) of + case sets:is_element(rebar_app_info:name(AppInfo1), Seen) of true -> - {false, AppInfo3}; + {false, AppInfo1}; false -> - maybe_symlink_default(State, Profile, AppDir, AppInfo3), + maybe_symlink_default(State, Profile, AppDir, AppInfo1), MaybeUpgrade = maybe_upgrade(AppInfo, AppDir, Upgrade, State), - AppInfo4 = update_app_info(AppDir, AppInfo3), - {MaybeUpgrade, AppInfo4} + AppInfo2 = update_app_info(AppDir, AppInfo1), + {MaybeUpgrade, AppInfo2} end end end. @@ -361,32 +357,13 @@ fetch_app(AppInfo, AppDir, State) -> %% So this is the first time for newly downloaded apps that its .app/.app.src data can %% be read in an parsed. update_app_info(AppDir, AppInfo) -> - case rebar_app_info:discover(AppDir) of - {ok, Found} -> - AppDetails = rebar_app_info:app_details(Found), - Vsn = rebar_app_info:original_vsn(Found), - Applications = proplists:get_value(applications, AppDetails, []), - IncludedApplications = proplists:get_value(included_applications, AppDetails, []), - AppInfo1 = rebar_app_info:original_vsn(rebar_app_info:applications( - rebar_app_info:app_details(AppInfo, AppDetails), - IncludedApplications++Applications), Vsn), - AppInfo2 = copy_app_info(AppInfo, AppInfo1), - rebar_app_info:valid(AppInfo2, undefined); - not_found -> + case rebar_app_discover:find_app(AppInfo, AppDir, all) of + {true, AppInfo1} -> + AppInfo1; + false -> throw(?PRV_ERROR({dep_app_not_found, AppDir, rebar_app_info:name(AppInfo)})) end. -copy_app_info(OldAppInfo, NewAppInfo) -> - Deps = rebar_app_info:deps(OldAppInfo), - ResourceType = rebar_app_info:resource_type(OldAppInfo), - Parent = rebar_app_info:parent(OldAppInfo), - Source = rebar_app_info:source(OldAppInfo), - - rebar_app_info:deps( - rebar_app_info:resource_type( - rebar_app_info:source( - rebar_app_info:parent(NewAppInfo, Parent), Source), ResourceType), Deps). - maybe_upgrade(AppInfo, AppDir, Upgrade, State) -> Source = rebar_app_info:source(AppInfo), case Upgrade orelse rebar_app_info:is_lock(AppInfo) of diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index cf6e8e8..7363d0a 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -237,17 +237,17 @@ deprecated(Old, New, When) -> [Old, Old, New, Old, When]). %% @doc Return list of erl_opts --spec erl_opts(rebar_app_info:t()) -> list(). -erl_opts(AppInfo) -> - RawErlOpts = filter_defines(rebar_utils:get(AppInfo, erl_opts, []), []), +-spec erl_opts(rebar_dict()) -> list(). +erl_opts(Opts) -> + RawErlOpts = filter_defines(rebar_utils:get(Opts, erl_opts, []), []), Defines = [{d, list_to_atom(D)} || - D <- rebar_utils:get(AppInfo, defines, [])], - Opts = Defines ++ RawErlOpts, - case proplists:is_defined(no_debug_info, Opts) of + D <- rebar_utils:get(Opts, defines, [])], + AllOpts = Defines ++ RawErlOpts, + case proplists:is_defined(no_debug_info, AllOpts) of true -> - [O || O <- Opts, O =/= no_debug_info]; + [O || O <- AllOpts, O =/= no_debug_info]; false -> - [debug_info|Opts] + [debug_info|AllOpts] end. %% for use by `do` task -- cgit v1.1 From 8e25a45cbbc3ba796e3cb4331c15a2914fa0e644 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 30 Aug 2015 13:39:38 -0500 Subject: update use of hooks and plugins with state in app_info --- src/rebar_app_info.erl | 105 ++++------------------------------------- src/rebar_app_utils.erl | 2 +- src/rebar_base_compiler.erl | 8 ++-- src/rebar_erlc_compiler.erl | 17 +++---- src/rebar_hooks.erl | 38 +++++++-------- src/rebar_prv_clean.erl | 4 +- src/rebar_prv_compile.erl | 30 +++++++----- src/rebar_prv_install_deps.erl | 6 +-- src/rebar_state.erl | 96 +++---------------------------------- src/rebar_utils.erl | 93 +++++++++++++++++++++++++++++++++++- 10 files changed, 162 insertions(+), 237 deletions(-) diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 3ace5e4..1e5710f 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -59,9 +59,7 @@ add_to_profile/3, apply_profiles/2, deduplicate/1, - do_deduplicate/2, - merge_opts/3, - merge_opts/2]). + do_deduplicate/2]). -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). @@ -158,7 +156,7 @@ update_opts(AppInfo, Opts, Config) -> true = rebar_config:verify_config_format(Terms), LocalOpts = dict:from_list(Terms), - NewOpts = merge_opts(LocalOpts, Opts), + NewOpts = rebar_utils:merge_opts(LocalOpts, Opts), AppInfo#app_info_t{opts=NewOpts ,default=NewOpts}. @@ -425,52 +423,14 @@ all(Dir, [File|Artifacts]) -> %%%%% -apply_overrides(AppInfo, Name) -> - Overrides = rebar_app_info:get(AppInfo, overrides, []), - %Name = binary_to_atom(AppName, utf8), - - %% Inefficient. We want the order we get here though. - AppInfo1 = lists:foldl(fun({override, O}, AppInfoAcc) -> - lists:foldl(fun({deps, Value}, AppInfoAcc1) -> - rebar_app_info:set(AppInfoAcc1, {deps,default}, Value); - ({Key, Value}, AppInfoAcc1) -> - rebar_app_info:set(AppInfoAcc1, Key, Value) - end, AppInfoAcc, O); - (_, AppInfoAcc) -> - AppInfoAcc - end, AppInfo, Overrides), - - AppInfo2 = lists:foldl(fun({override, N, O}, AppInfoAcc) when N =:= Name -> - lists:foldl(fun({deps, Value}, AppInfoAcc1) -> - rebar_app_info:set(AppInfoAcc1, {deps,default}, Value); - ({Key, Value}, AppInfoAcc1) -> - rebar_app_info:set(AppInfoAcc1, Key, Value) - end, AppInfoAcc, O); - (_, AppInfoAcc) -> - AppInfoAcc - end, AppInfo1, Overrides), - - AppInfo3 = lists:foldl(fun({add, N, O}, AppInfoAcc) when N =:= Name -> - lists:foldl(fun({deps, Value}, AppInfoAcc1) -> - OldValue = rebar_app_info:get(AppInfoAcc1, {deps,default}, []), - rebar_app_info:set(AppInfoAcc1, {deps,default}, Value++OldValue); - ({Key, Value}, AppInfoAcc1) -> - OldValue = rebar_app_info:get(AppInfoAcc1, Key, []), - rebar_app_info:set(AppInfoAcc1, Key, Value++OldValue) - end, AppInfoAcc, O); - (_, AppInfoAcc) -> - AppInfoAcc - end, AppInfo2, Overrides), - - Opts = opts(AppInfo3), - AppInfo3#app_info_t{default=Opts}. +apply_overrides(Overrides, AppInfo) -> + Name = binary_to_atom(rebar_app_info:name(AppInfo), utf8), + Opts = rebar_utils:apply_overrides(opts(AppInfo), Name, Overrides), + AppInfo#app_info_t{default=Opts, opts=Opts}. add_to_profile(AppInfo, Profile, KVs) when is_atom(Profile), is_list(KVs) -> - Profiles = rebar_app_info:get(AppInfo, profiles, []), - ProfileOpts = dict:from_list(proplists:get_value(Profile, Profiles, [])), - NewOpts = merge_opts(Profile, dict:from_list(KVs), ProfileOpts), - NewProfiles = [{Profile, dict:to_list(NewOpts)}|lists:keydelete(Profile, 1, Profiles)], - rebar_app_info:set(AppInfo, profiles, NewProfiles). + Opts = rebar_utils:add_to_profile(opts(AppInfo), Profile, KVs), + AppInfo#app_info_t{opts=Opts}. apply_profiles(AppInfo, Profile) when not is_list(Profile) -> apply_profiles(AppInfo, [Profile]); @@ -496,7 +456,7 @@ apply_profiles(AppInfo=#app_info_t{default = Defaults, profiles=CurrentProfiles} case proplists:get_value(Profile, ConfigProfiles, []) of OptsList when is_list(OptsList) -> ProfileOpts = dict:from_list(OptsList), - merge_opts(Profile, ProfileOpts, OptsAcc); + rebar_utils:merge_opts(Profile, ProfileOpts, OptsAcc); Other -> throw(?PRV_ERROR({profile_not_list, Profile, Other})) end @@ -513,50 +473,3 @@ do_deduplicate([Head | Rest], Acc) -> true -> do_deduplicate(Rest, Acc); false -> do_deduplicate(Rest, [Head | Acc]) end. - -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). diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 2509c7d..545ce95 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -171,7 +171,7 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> end, C = rebar_config:consult(rebar_app_info:dir(AppInfo)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), - AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), + AppInfo1 = rebar_app_info:apply_overrides(rebar_state:get(State, overrides, []), AppInfo0), rebar_app_info:is_lock(rebar_app_info:source(AppInfo1, Source), IsLock). format_error({missing_package, Package}) -> diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 7193003..31292af 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -31,8 +31,8 @@ -export([run/4, run/7, run/8, - ok_tuple/3, - error_tuple/5]). + ok_tuple/2, + error_tuple/4]). %% =================================================================== %% Public API @@ -69,10 +69,10 @@ run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, simple_compile_wrapper(S, Target, Compile3Fn, C, CheckLastMod) end). -ok_tuple(_Config, Source, Ws) -> +ok_tuple(Source, Ws) -> {ok, format_warnings(Source, Ws)}. -error_tuple(_Config, Source, Es, Ws, Opts) -> +error_tuple(Source, Es, Ws, Opts) -> {error, format_errors(Source, Es), format_warnings(Source, Ws, Opts)}. diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 2b3942c..869ade3 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -210,7 +210,7 @@ needed_files(G, ErlOpts, Dir, OutDir, SourceFiles) -> TargetBase = target_base(OutDir, Source), Target = TargetBase ++ ".beam", AllOpts = [{outdir, filename:dirname(Target)} - ,{i, filename:join(Dir, "include")}] ++ ErlOpts, + ,{i, filename:join(Dir, "include")}] ++ ErlOpts, digraph:vertex(G, Source) > {Source, filelib:last_modified(Target)} orelse opts_changed(AllOpts, TargetBase) end, SourceFiles). @@ -405,7 +405,7 @@ expand_file_names(Files, Dirs) -> -spec internal_erl_compile(rebar_dict(), file:filename(), file:filename(), file:filename(), list()) -> ok | {ok, any()} | {error, any(), any()}. -internal_erl_compile(Opts, Dir, Module, OutDir, ErlOpts) -> +internal_erl_compile(_Opts, Dir, Module, OutDir, ErlOpts) -> Target = target_base(OutDir, Module) ++ ".beam", ok = filelib:ensure_dir(Target), AllOpts = [{outdir, filename:dirname(Target)}] ++ ErlOpts ++ @@ -414,9 +414,9 @@ internal_erl_compile(Opts, Dir, Module, OutDir, ErlOpts) -> {ok, _Mod} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(Opts, Module, Ws); + rebar_base_compiler:ok_tuple(Module, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(Opts, Module, Es, Ws, Opts) + rebar_base_compiler:error_tuple(Module, Es, Ws, AllOpts) end. target_base(OutDir, Source) -> @@ -464,8 +464,9 @@ compile_yrl(Source, Target, Opts) -> -spec compile_xrl_yrl(rebar_dict(), file:filename(), file:filename(), list(), module()) -> 'ok'. -compile_xrl_yrl(Opts, Source, Target, AllOpts, Mod) -> - Dir = filename:dirname(Target), +compile_xrl_yrl(_Opts, Source, Target, AllOpts, Mod) -> + %% FIX ME: should be the outdir or something + Dir = filename:dirname(filename:dirname(Target)), AllOpts1 = [{includefile, filename:join(Dir, I)} || {includefile, I} <- AllOpts, filename:pathtype(I) =:= relative], case needs_compile(Source, Target) of @@ -474,9 +475,9 @@ compile_xrl_yrl(Opts, Source, Target, AllOpts, Mod) -> {ok, _} -> ok; {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(Opts, Source, Ws); + rebar_base_compiler:ok_tuple(Source, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(Opts, Source, + rebar_base_compiler:error_tuple(Source, Es, Ws, AllOpts1) end; false -> diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index c5f8b88..4e5130e 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -7,28 +7,29 @@ -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). -run_all_hooks(Dir, Type, Command, Providers, State) -> - run_all_hooks(Dir, Type, Command, Providers, element(2,rebar_app_info:new(noen)), State). - -spec run_all_hooks(file:filename_all(), pre | post, atom() | {atom(), atom()} | string(), [providers:t()], rebar_app_info:t(), rebar_state:t()) -> ok. run_all_hooks(Dir, Type, Command, Providers, AppInfo, State) -> - run_provider_hooks(Dir, Type, Command, Providers, AppInfo, State), - run_hooks(Dir, Type, Command, AppInfo, State). + run_provider_hooks(Dir, Type, Command, Providers, rebar_app_info:opts(AppInfo), State), + run_hooks(Dir, Type, Command, rebar_app_info:opts(AppInfo), State). + +run_all_hooks(Dir, Type, Command, Providers, State) -> + run_provider_hooks(Dir, Type, Command, Providers, rebar_state:opts(State), State), + run_hooks(Dir, Type, Command, rebar_state:opts(State), State). -run_provider_hooks(Dir, Type, Command, Providers, AppInfo, State) -> - case rebar_app_info:get(AppInfo, provider_hooks, [])++rebar_state:get(State, provider_hooks, []) of +run_provider_hooks(Dir, Type, Command, Providers, Opts, State) -> + case rebar_utils:get(Opts, provider_hooks, []) of [] -> ok; AllHooks -> TypeHooks = proplists:get_value(Type, AllHooks, []), - run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, AppInfo, State) + run_provider_hooks_(Dir, Type, Command, Providers, TypeHooks, rebar_state:opts(State, Opts)) end. -run_provider_hooks(_Dir, _Type, _Command, _Providers, [], _AppInfo, _State) -> +run_provider_hooks_(_Dir, _Type, _Command, _Providers, [], _State) -> ok; -run_provider_hooks(Dir, Type, Command, Providers, TypeHooks, _AppInfo, State) -> +run_provider_hooks_(Dir, Type, Command, Providers, TypeHooks, State) -> PluginDepsPaths = rebar_state:code_paths(State, all_plugin_deps), code:add_pathsa(PluginDepsPaths), Providers1 = rebar_state:providers(State), @@ -71,16 +72,16 @@ format_error({bad_provider, Type, Command, Name}) -> %% ERL = ERLANG_ROOT_DIR/bin/erl %% ERLC = ERLANG_ROOT_DIR/bin/erl %% -run_hooks(Dir, pre, Command, AppInfo, State) -> - run_hooks(Dir, pre_hooks, Command, AppInfo, State); -run_hooks(Dir, post, Command, AppInfo, State) -> - run_hooks(Dir, post_hooks, Command, AppInfo, State); -run_hooks(Dir, Type, Command, AppInfo, State) -> - case rebar_app_info:get(AppInfo, Type, []) of +run_hooks(Dir, pre, Command, Opts, State) -> + run_hooks(Dir, pre_hooks, Command, Opts, State); +run_hooks(Dir, post, Command, Opts, State) -> + run_hooks(Dir, post_hooks, Command, Opts, State); +run_hooks(Dir, Type, Command, Opts, State) -> + case rebar_utils:get(Opts, Type, []) of [] -> ok; Hooks -> - Env = create_env(State, AppInfo), + Env = create_env(State, Opts), lists:foreach(fun({_, C, _}=Hook) when C =:= Command -> apply_hook(Dir, Env, Hook); ({C, _}=Hook) when C =:= Command -> @@ -101,8 +102,7 @@ apply_hook(Dir, Env, {Command, Hook}) -> Msg = lists:flatten(io_lib:format("Hook for ~p failed!~n", [Command])), rebar_utils:sh(Hook, [use_stdout, {cd, Dir}, {env, Env}, {abort_on_error, Msg}]). -create_env(State, AppInfo) -> - Opts = rebar_app_info:opts(AppInfo), +create_env(State, Opts) -> BaseDir = rebar_dir:base_dir(State), [ {"REBAR_DEPS_DIR", filename:absname(rebar_dir:deps_dir(State))}, diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index fa8bcf3..60b61e3 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -50,9 +50,9 @@ do(State) -> clean_apps(EmptyState, Providers, DepApps), Cwd = rebar_dir:get_cwd(), - rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), + rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), clean_apps(State, Providers, ProjectApps), - rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State), {ok, State}. diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 1675a41..547f5d3 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -45,14 +45,14 @@ do(State) -> %% Need to allow global config vars used on deps. %% Right now no way to differeniate and just give deps a new state. %% But need an account of "all deps" for some hooks to use. - EmptyState = rebar_state:new(), - build_apps(rebar_state:all_deps(EmptyState, - rebar_state:all_deps(State)), Providers, Deps), - + %% EmptyState = rebar_state:new(), + %% build_apps(rebar_state:all_deps(EmptyState, + %% rebar_state:all_deps(State)), Providers, Deps), + build_apps(State, Providers, Deps), {ok, ProjectApps1} = rebar_digraph:compile_order(ProjectApps), %% Run top level hooks *before* project apps compiled but *after* deps are - rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State), + rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), ProjectApps2 = build_apps(State, Providers, ProjectApps1), State2 = rebar_state:project_apps(State, ProjectApps2), @@ -60,9 +60,13 @@ do(State) -> ProjAppsPaths = [filename:join(rebar_app_info:out_dir(X), "ebin") || X <- ProjectApps2], State3 = rebar_state:code_paths(State2, all_deps, DepsPaths ++ ProjAppsPaths), - rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, element(2,rebar_app_info:new(noen)), State2), - has_all_artifacts(State3), - + rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State2), + case rebar_state:has_all_artifacts(State3) of + {false, File} -> + throw(?PRV_ERROR({missing_artifact, File})); + true -> + true + end, rebar_utils:cleanup_code_path(rebar_state:code_paths(State3, default) ++ rebar_state:code_paths(State, all_plugin_deps)), @@ -83,8 +87,8 @@ build_app(State, Providers, AppInfo) -> copy_app_dirs(AppInfo, AppDir, OutDir), %S = rebar_app_info:state_or_new(State, AppInfo), - S1 = rebar_state:all_deps(State, rebar_state:all_deps(State)), - compile(S1, Providers, AppInfo). + %S1 = rebar_state:all_deps(State, rebar_state:all_deps(State)), + compile(State, Providers, AppInfo). compile(State, Providers, AppInfo) -> ?INFO("Compiling ~s", [rebar_app_info:name(AppInfo)]), @@ -95,7 +99,7 @@ compile(State, Providers, AppInfo) -> case rebar_otp_app:compile(State, AppInfo) of {ok, AppInfo1} -> rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, State), - has_all_artifacts(State), + has_all_artifacts(AppInfo1), AppInfo1; Error -> throw(Error) @@ -105,8 +109,8 @@ compile(State, Providers, AppInfo) -> %% Internal functions %% =================================================================== -has_all_artifacts(State) -> - case rebar_state:has_all_artifacts(State) of +has_all_artifacts(AppInfo1) -> + case rebar_app_info:has_all_artifacts(AppInfo1) of {false, File} -> throw(?PRV_ERROR({missing_artifact, File})); true -> diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 6ae22d6..aeda252 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -256,7 +256,7 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> C = rebar_config:consult(rebar_app_info:dir(AppInfo)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), - AppInfo1 = rebar_app_info:apply_overrides(AppInfo0, Name), + AppInfo1 = rebar_app_info:apply_overrides(rebar_state:overrides(State), AppInfo0), AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, Profiles), Plugins = rebar_app_info:get(AppInfo2, plugins, []), @@ -266,7 +266,7 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo3, blacklisted_otp_vsns, [])), %% Dep may have plugins to install. Find and install here. - _S = rebar_plugins:install(State, AppInfo3), + State1 = rebar_plugins:install(State, AppInfo3), %% TODO: Plugin Providers?? %AppInfo1 = rebar_app_info:state(AppInfo, S5), @@ -276,7 +276,7 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> Deps = rebar_app_info:get(AppInfo3, {deps, default}, []), AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)), Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, State, Locks, Level+1), - {AppInfo4, Deps1, State}. + {AppInfo4, Deps1, State1}. -spec maybe_fetch(rebar_app_info:t(), atom(), boolean(), sets:set(binary()), rebar_state:t()) -> {boolean(), rebar_app_info:t()}. diff --git a/src/rebar_state.erl b/src/rebar_state.erl index e31b01b..47fd853 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -118,7 +118,7 @@ new(ParentState, Config, Deps, Dir) -> true = rebar_config:verify_config_format(Terms), LocalOpts = dict:from_list(Terms), - NewOpts = merge_opts(LocalOpts, Opts), + NewOpts = rebar_utils:merge_opts(LocalOpts, Opts), ParentState#state_t{dir=Dir ,opts=NewOpts @@ -255,49 +255,12 @@ command_parsed_args(State, 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({deps, Value}, StateAcc1) -> - rebar_state:set(StateAcc1, {deps,default}, Value); - ({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({deps, Value}, StateAcc1) -> - rebar_state:set(StateAcc1, {deps,default}, Value); - ({Key, Value}, StateAcc1) -> - rebar_state:set(StateAcc1, Key, Value) - end, StateAcc, O); - (_, StateAcc) -> - StateAcc - end, State1, Overrides), - - State3 = lists:foldl(fun({add, N, O}, StateAcc) when N =:= Name -> - lists:foldl(fun({deps, Value}, StateAcc1) -> - OldValue = rebar_state:get(StateAcc1, {deps,default}, []), - rebar_state:set(StateAcc1, {deps,default}, Value++OldValue); - ({Key, Value}, StateAcc1) -> - OldValue = rebar_state:get(StateAcc1, Key, []), - rebar_state:set(StateAcc1, Key, Value++OldValue) - end, StateAcc, O); - (_, StateAcc) -> - StateAcc - end, State2, Overrides), - - Opts = opts(State3), - State3#state_t{default=Opts}. + Opts = rebar_utils:apply_overrides(opts(State), Name, Overrides), + State#state_t{default=Opts, opts=Opts}. add_to_profile(State, Profile, KVs) when is_atom(Profile), is_list(KVs) -> - Profiles = rebar_state:get(State, profiles, []), - ProfileOpts = dict:from_list(proplists:get_value(Profile, Profiles, [])), - NewOpts = merge_opts(Profile, dict:from_list(KVs), ProfileOpts), - NewProfiles = [{Profile, dict:to_list(NewOpts)}|lists:keydelete(Profile, 1, Profiles)], - rebar_state:set(State, profiles, NewProfiles). + Opts = rebar_utils:add_to_profile(opts(State), Profile, KVs), + State#state_t{opts=Opts}. apply_profiles(State, Profile) when not is_list(Profile) -> apply_profiles(State, [Profile]); @@ -323,7 +286,7 @@ apply_profiles(State=#state_t{default = Defaults, current_profiles=CurrentProfil case proplists:get_value(Profile, ConfigProfiles, []) of OptsList when is_list(OptsList) -> ProfileOpts = dict:from_list(OptsList), - merge_opts(Profile, ProfileOpts, OptsAcc); + rebar_utils:merge_opts(Profile, ProfileOpts, OptsAcc); Other -> throw(?PRV_ERROR({profile_not_list, Profile, Other})) end @@ -341,53 +304,6 @@ do_deduplicate([Head | Rest], Acc) -> false -> do_deduplicate(Rest, [Head | Acc]) end. -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). - dir(#state_t{dir=Dir}) -> Dir. 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 -- cgit v1.1 From a6ca5d5e25dbeb851e0f4c9fd91aa74e15f25ce8 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 30 Aug 2015 17:02:42 -0500 Subject: fixes for overrides of deps --- src/rebar_app_discover.erl | 1 - src/rebar_app_utils.erl | 6 ++++-- src/rebar_prv_install_deps.erl | 7 +++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 08502a9..b819313 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -77,7 +77,6 @@ merge_deps(AppInfo, State) -> CurrentProfiles = rebar_state:current_profiles(State), Name = rebar_app_info:name(AppInfo), C = project_app_config(AppInfo, State), - %% We reset the opts here to default so no profiles are applied multiple times AppState = rebar_state:apply_overrides( rebar_state:apply_profiles( diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 545ce95..be2b289 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -171,8 +171,10 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) -> end, C = rebar_config:consult(rebar_app_info:dir(AppInfo)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), - AppInfo1 = rebar_app_info:apply_overrides(rebar_state:get(State, overrides, []), AppInfo0), - rebar_app_info:is_lock(rebar_app_info:source(AppInfo1, Source), IsLock). + Overrides = rebar_state:get(State, overrides, []), + AppInfo1 = rebar_app_info:set(AppInfo0, overrides, rebar_app_info:get(AppInfo, overrides, [])++Overrides), + AppInfo2 = rebar_app_info:apply_overrides(rebar_app_info:get(AppInfo1, overrides, []), AppInfo1), + rebar_app_info:is_lock(rebar_app_info:source(AppInfo2, Source), IsLock). format_error({missing_package, Package}) -> io_lib:format("Package not found in registry: ~s", [Package]); diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index aeda252..789ad2f 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -253,11 +253,9 @@ update_unseen_dep(AppInfo, Profile, Level, Deps, Apps, State, Upgrade, Seen, Loc handle_dep(State, Profile, 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)), AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), - AppInfo1 = rebar_app_info:apply_overrides(rebar_state:overrides(State), AppInfo0), - + AppInfo1 = rebar_app_info:apply_overrides(rebar_app_info:get(AppInfo, overrides, []), AppInfo0), AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, Profiles), Plugins = rebar_app_info:get(AppInfo2, plugins, []), AppInfo3 = rebar_app_info:set(AppInfo2, {plugins, Profile}, Plugins), @@ -275,7 +273,8 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> %% Upgrade lock level to be the level the dep will have in this dep tree Deps = rebar_app_info:get(AppInfo3, {deps, default}, []), AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)), - Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, State, Locks, Level+1), + Overrides = rebar_state:overrides(State) ++ rebar_app_info:get(AppInfo0, overrides, []), + Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, rebar_state:overrides(State, Overrides), Locks, Level+1), {AppInfo4, Deps1, State1}. -spec maybe_fetch(rebar_app_info:t(), atom(), boolean(), -- cgit v1.1 From c7a7b309fd839b28daa736999a20da598ff699e1 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 30 Aug 2015 21:36:51 -0500 Subject: more cleanup of old state usage --- src/rebar_app_discover.erl | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index b819313..03bb96a 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -31,7 +31,7 @@ do(State, LibDirs) -> ParsedDeps = parse_profile_deps(Profile ,TopLevelApp ,ProfileDeps2 - ,StateAcc1 + ,rebar_state:opts(StateAcc1) ,StateAcc1), rebar_state:set(StateAcc1, {parsed_deps, Profile}, ParsedDeps) end, State, lists:reverse(CurrentProfiles)), @@ -74,32 +74,29 @@ format_error({missing_module, Module}) -> merge_deps(AppInfo, State) -> Default = rebar_state:default(State), - CurrentProfiles = rebar_state:current_profiles(State), - Name = rebar_app_info:name(AppInfo), C = project_app_config(AppInfo, State), - %% We reset the opts here to default so no profiles are applied multiple times - AppState = rebar_state:apply_overrides( - rebar_state:apply_profiles( - rebar_state:new(reset_hooks(rebar_state:opts(State, Default)), C, - rebar_app_info:dir(AppInfo)), CurrentProfiles), Name), - AppState1 = rebar_state:overrides(AppState, rebar_state:get(AppState, overrides, [])), + AppInfo0 = rebar_app_info:update_opts(AppInfo, Default, C), - rebar_utils:check_min_otp_version(rebar_state:get(AppState1, minimum_otp_vsn, undefined)), - rebar_utils:check_blacklisted_otp_versions(rebar_state:get(AppState1, blacklisted_otp_vsns, [])), + CurrentProfiles = rebar_state:current_profiles(State), + Name = rebar_app_info:name(AppInfo0), + + %% We reset the opts here to default so no profiles are applied multiple times + AppInfo1 = rebar_app_info:apply_overrides(rebar_state:overrides(State), AppInfo0), + AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, CurrentProfiles), - AppState2 = rebar_state:set(AppState1, artifacts, []), - AppInfo2 = rebar_app_info:opts(AppInfo, rebar_state:opts(AppState2)), + rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo2, minimum_otp_vsn, undefined)), + rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo2, blacklisted_otp_vsns, [])), State1 = lists:foldl(fun(Profile, StateAcc) -> - handle_profile(Profile, Name, AppState1, StateAcc) + handle_profile(Profile, Name, AppInfo2, StateAcc) end, State, lists:reverse(CurrentProfiles)), {AppInfo2, State1}. -handle_profile(Profile, Name, AppState, State) -> +handle_profile(Profile, Name, AppInfo, State) -> TopParsedDeps = rebar_state:get(State, {parsed_deps, Profile}, {[], []}), TopLevelProfileDeps = rebar_state:get(State, {deps, Profile}, []), - AppProfileDeps = rebar_state:get(AppState, {deps, Profile}, []), + AppProfileDeps = rebar_app_info:get(AppInfo, {deps, Profile}, []), AppProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_sort(AppProfileDeps)), ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge( rebar_utils:tup_sort(TopLevelProfileDeps) @@ -109,17 +106,17 @@ handle_profile(Profile, Name, AppState, State) -> %% Only deps not also specified in the top level config need %% to be included in the parsed deps NewDeps = ProfileDeps2 -- TopLevelProfileDeps, - ParsedDeps = parse_profile_deps(Profile, Name, NewDeps, AppState, State1), + ParsedDeps = parse_profile_deps(Profile, Name, NewDeps, rebar_app_info:opts(AppInfo), State1), State2 = rebar_state:set(State1, {deps, Profile}, ProfileDeps2), rebar_state:set(State2, {parsed_deps, Profile}, TopParsedDeps++ParsedDeps). -parse_profile_deps(Profile, Name, Deps, AppState, State) -> +parse_profile_deps(Profile, Name, Deps, Opts, State) -> DepsDir = rebar_prv_install_deps:profile_dep_dir(State, Profile), Locks = rebar_state:get(State, {locks, Profile}, []), rebar_app_utils:parse_deps(Name ,DepsDir ,Deps - ,AppState + ,rebar_state:opts(State, Opts) ,Locks ,1). @@ -139,10 +136,10 @@ maybe_reset_hooks(C, Dir, State) -> C end. -reset_hooks(State) -> - lists:foldl(fun(Key, StateAcc) -> - rebar_state:set(StateAcc, Key, []) - end, State, [post_hooks, pre_hooks, provider_hooks]). +%% reset_hooks(Opts) -> +%% lists:foldl(fun(Key, OptsAcc) -> +%% rebar_utils:set(OptsAcc, Key, []) +%% end, Opts, [post_hooks, pre_hooks, provider_hooks]). -spec all_app_dirs(list(file:name())) -> list(file:name()). all_app_dirs(LibDirs) -> -- cgit v1.1 From e6f6ccc7570ad57f6d1416b3f8c59551b7aaa5c6 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 31 Aug 2015 21:40:33 -0500 Subject: more cleanup --- src/rebar_app_discover.erl | 22 +++++++++++----------- src/rebar_hooks.erl | 1 - src/rebar_prv_clean.erl | 9 ++------- src/rebar_prv_compile.erl | 9 --------- src/rebar_prv_install_deps.erl | 11 ++++++----- src/rebar_prv_plugins_upgrade.erl | 5 +++-- src/rebar_state.erl | 16 +++------------- src/rebar_utils.erl | 34 ++++++++++++++++++++-------------- 8 files changed, 45 insertions(+), 62 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 03bb96a..a0b6d8c 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -26,7 +26,7 @@ do(State, LibDirs) -> %% Handle top level deps State1 = lists:foldl(fun(Profile, StateAcc) -> ProfileDeps = rebar_state:get(StateAcc, {deps, Profile}, []), - ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_sort(ProfileDeps)), + ProfileDeps2 = rebar_utils:tup_dedup(ProfileDeps), StateAcc1 = rebar_state:set(StateAcc, {deps, Profile}, ProfileDeps2), ParsedDeps = parse_profile_deps(Profile ,TopLevelApp @@ -73,7 +73,7 @@ format_error({missing_module, Module}) -> io_lib:format("Module defined in app file missing: ~p~n", [Module]). merge_deps(AppInfo, State) -> - Default = rebar_state:default(State), + Default = reset_hooks(rebar_state:default(State)), C = project_app_config(AppInfo, State), AppInfo0 = rebar_app_info:update_opts(AppInfo, Default, C), @@ -97,10 +97,9 @@ handle_profile(Profile, Name, AppInfo, State) -> TopParsedDeps = rebar_state:get(State, {parsed_deps, Profile}, {[], []}), TopLevelProfileDeps = rebar_state:get(State, {deps, Profile}, []), AppProfileDeps = rebar_app_info:get(AppInfo, {deps, Profile}, []), - AppProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_sort(AppProfileDeps)), - ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge( - rebar_utils:tup_sort(TopLevelProfileDeps) - ,rebar_utils:tup_sort(AppProfileDeps2))), + AppProfileDeps2 = rebar_utils:tup_dedup(AppProfileDeps), + ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge(TopLevelProfileDeps + ,AppProfileDeps2)), State1 = rebar_state:set(State, {deps, Profile}, ProfileDeps2), %% Only deps not also specified in the top level config need @@ -131,15 +130,16 @@ maybe_reset_hooks(C, Dir, State) -> case ec_file:real_dir_path(rebar_dir:root_dir(State)) of Dir -> C1 = proplists:delete(provider_hooks, C), - proplists:delete(post_hooks, proplists:delete(pre_hooks, C1)); + C2 = proplists:delete(artifacts, C1), + proplists:delete(post_hooks, proplists:delete(pre_hooks, C2)); _ -> C end. -%% reset_hooks(Opts) -> -%% lists:foldl(fun(Key, OptsAcc) -> -%% rebar_utils:set(OptsAcc, Key, []) -%% end, Opts, [post_hooks, pre_hooks, provider_hooks]). +reset_hooks(Opts) -> + lists:foldl(fun(Key, OptsAcc) -> + rebar_utils:set(OptsAcc, Key, []) + end, Opts, [post_hooks, pre_hooks, provider_hooks, artifacts]). -spec all_app_dirs(list(file:name())) -> list(file:name()). all_app_dirs(LibDirs) -> diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index 4e5130e..cb44b81 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -35,7 +35,6 @@ run_provider_hooks_(Dir, Type, Command, Providers, TypeHooks, State) -> Providers1 = rebar_state:providers(State), State1 = rebar_state:providers(rebar_state:dir(State, Dir), Providers++Providers1), HookProviders = proplists:get_all_values(Command, TypeHooks), - case rebar_core:do(HookProviders, State1) of {error, ProviderName} -> ?DEBUG(format_error({bad_provider, Type, Command, ProviderName}), []), diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index 60b61e3..503291d 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -44,10 +44,7 @@ do(State) -> DepApps = [] end, - %% Need to allow global config vars used on deps - %% Right now no way to differeniate and just give deps a new state - EmptyState = rebar_state:new(), - clean_apps(EmptyState, Providers, DepApps), + clean_apps(State, Providers, DepApps), Cwd = rebar_dir:get_cwd(), rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), @@ -66,10 +63,8 @@ format_error(Reason) -> clean_apps(State, Providers, Apps) -> lists:foreach(fun(AppInfo) -> - AppDir = rebar_app_info:dir(AppInfo), - %S = rebar_app_info:state_or_new(State, AppInfo), - ?INFO("Cleaning out ~s...", [rebar_app_info:name(AppInfo)]), + AppDir = rebar_app_info:dir(AppInfo), rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, AppInfo, State), rebar_erlc_compiler:clean(State, rebar_app_info:out_dir(AppInfo)), rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, AppInfo, State) diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 547f5d3..56e5e84 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -42,12 +42,6 @@ do(State) -> Deps = rebar_state:deps_to_build(State), Cwd = rebar_state:dir(State), - %% Need to allow global config vars used on deps. - %% Right now no way to differeniate and just give deps a new state. - %% But need an account of "all deps" for some hooks to use. - %% EmptyState = rebar_state:new(), - %% build_apps(rebar_state:all_deps(EmptyState, - %% rebar_state:all_deps(State)), Providers, Deps), build_apps(State, Providers, Deps), {ok, ProjectApps1} = rebar_digraph:compile_order(ProjectApps), @@ -85,9 +79,6 @@ build_app(State, Providers, AppInfo) -> AppDir = rebar_app_info:dir(AppInfo), OutDir = rebar_app_info:out_dir(AppInfo), copy_app_dirs(AppInfo, AppDir, OutDir), - - %S = rebar_app_info:state_or_new(State, AppInfo), - %S1 = rebar_state:all_deps(State, rebar_state:all_deps(State)), compile(State, Providers, AppInfo). compile(State, Providers, AppInfo) -> diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 789ad2f..cd5f068 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -254,9 +254,11 @@ handle_dep(State, Profile, 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)), + AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), AppInfo1 = rebar_app_info:apply_overrides(rebar_app_info:get(AppInfo, overrides, []), AppInfo0), AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, Profiles), + Plugins = rebar_app_info:get(AppInfo2, plugins, []), AppInfo3 = rebar_app_info:set(AppInfo2, {plugins, Profile}, Plugins), @@ -265,16 +267,15 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> %% Dep may have plugins to install. Find and install here. State1 = rebar_plugins:install(State, AppInfo3), - %% TODO: Plugin Providers?? - - %AppInfo1 = rebar_app_info:state(AppInfo, S5), - %AppInfo2 = rebar_app_info:opts(AppInfo1, rebar_state:opts(S5)), %% Upgrade lock level to be the level the dep will have in this dep tree Deps = rebar_app_info:get(AppInfo3, {deps, default}, []), AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)), + + %% Keep all overrides from the global config and this dep when parsing its deps Overrides = rebar_state:overrides(State) ++ rebar_app_info:get(AppInfo0, overrides, []), - Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, rebar_state:overrides(State, Overrides), Locks, Level+1), + Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, rebar_state:overrides(State, Overrides) + ,Locks, Level+1), {AppInfo4, Deps1, State1}. -spec maybe_fetch(rebar_app_info:t(), atom(), boolean(), diff --git a/src/rebar_prv_plugins_upgrade.erl b/src/rebar_prv_plugins_upgrade.erl index fabfa5b..f946f40 100644 --- a/src/rebar_prv_plugins_upgrade.erl +++ b/src/rebar_prv_plugins_upgrade.erl @@ -91,5 +91,6 @@ build_plugin(AppInfo, Apps, State) -> Providers = rebar_state:providers(State), AppDir = rebar_app_info:dir(AppInfo), C = rebar_config:consult(AppDir), - S = rebar_state:new(rebar_state:all_deps(rebar_state:new(), Apps), C, AppInfo), - rebar_prv_compile:compile(S, Providers, AppInfo). + S = rebar_state:new(rebar_state:all_deps(rebar_state:new(), Apps), C, AppDir), + AppInfo1 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C), + rebar_prv_compile:compile(S, Providers, AppInfo1). diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 47fd853..494624f 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -97,19 +97,9 @@ new(ParentState=#state_t{}, Config) -> Dir = rebar_dir:get_cwd(), new(ParentState, Config, Dir). --spec new(t(), list(), rebar_app_info:t() | file:filename_all()) -> t(). -new(ParentState, Config, Dir) when is_list(Dir) -> - new(ParentState, Config, deps_from_config(Dir, Config), Dir); -new(ParentState, Config, AppInfo) -> - Dir = rebar_app_info:dir(AppInfo), - DepLocks = case rebar_app_info:resource_type(AppInfo) of - pkg -> - Deps = rebar_app_info:deps(AppInfo), - [{{locks, default}, Deps}, {{deps, default}, Deps}]; - _ -> - deps_from_config(Dir, Config) - end, - new(ParentState, Config, DepLocks, Dir). +-spec new(t(), list(), file:filename_all()) -> t(). +new(ParentState, Config, Dir) -> + new(ParentState, Config, deps_from_config(Dir, Config), Dir). new(ParentState, Config, Deps, Dir) -> Opts = ParentState#state_t.opts, diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 9f66181..7260f6d 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -269,20 +269,23 @@ deps_to_binary([{Name, Source} | T]) -> deps_to_binary([Name | T]) -> [ec_cnv:to_binary(Name) | deps_to_binary(T)]. -tup_dedup([]) -> +tup_dedup(List) -> + tup_dedup_(tup_sort(List)). + +tup_dedup_([]) -> []; -tup_dedup([A]) -> +tup_dedup_([A]) -> [A]; -tup_dedup([A,B|T]) when element(1, A) =:= element(1, B) -> - tup_dedup([A | T]); -tup_dedup([A,B|T]) when element(1, A) =:= B -> - tup_dedup([A | T]); -tup_dedup([A,B|T]) when A =:= element(1, B) -> - tup_dedup([A | T]); -tup_dedup([A,A|T]) -> - [A|tup_dedup(T)]; -tup_dedup([A|T]) -> - [A|tup_dedup(T)]. +tup_dedup_([A,B|T]) when element(1, A) =:= element(1, B) -> + tup_dedup_([A | T]); +tup_dedup_([A,B|T]) when element(1, A) =:= B -> + tup_dedup_([A | T]); +tup_dedup_([A,B|T]) when A =:= element(1, B) -> + tup_dedup_([A | T]); +tup_dedup_([A,A|T]) -> + [A|tup_dedup_(T)]; +tup_dedup_([A|T]) -> + [A|tup_dedup_(T)]. %% Sort the list in proplist-order, meaning that `{a,b}' and `{a,c}' %% both compare as usual, and `a' and `b' do the same, but `a' and `{a,b}' will @@ -311,9 +314,12 @@ tup_sort(List) -> %% %% This lets us apply proper overrides to list of elements according to profile %% priority. This function depends on a stable proplist sort. -tup_umerge([], Olds) -> +tup_umerge(NewList, OldList) -> + tup_umerge_(tup_sort(NewList), tup_sort(OldList)). + +tup_umerge_([], Olds) -> Olds; -tup_umerge([New|News], Olds) -> +tup_umerge_([New|News], Olds) -> lists:reverse(umerge(News, Olds, [], New)). tup_find(_Elem, []) -> -- cgit v1.1 From b2c051452e336f9727b0f93ddb2f1abe970ed325 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 1 Sep 2015 17:25:22 -0500 Subject: remove overrides element from state record --- src/rebar_app_discover.erl | 2 +- src/rebar_prv_install_deps.erl | 4 ++-- src/rebar_state.erl | 14 -------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index a0b6d8c..1052774 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -81,7 +81,7 @@ merge_deps(AppInfo, State) -> Name = rebar_app_info:name(AppInfo0), %% We reset the opts here to default so no profiles are applied multiple times - AppInfo1 = rebar_app_info:apply_overrides(rebar_state:overrides(State), AppInfo0), + AppInfo1 = rebar_app_info:apply_overrides(rebar_state:get(State, overrides, []), AppInfo0), AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, CurrentProfiles), rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo2, minimum_otp_vsn, undefined)), diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index cd5f068..cb1bf00 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -273,8 +273,8 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)), %% Keep all overrides from the global config and this dep when parsing its deps - Overrides = rebar_state:overrides(State) ++ rebar_app_info:get(AppInfo0, overrides, []), - Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, rebar_state:overrides(State, Overrides) + Overrides = rebar_app_info:get(AppInfo0, overrides, []), + Deps1 = rebar_app_utils:parse_deps(Name, DepsDir, Deps, rebar_state:set(State, overrides, Overrides) ,Locks, Level+1), {AppInfo4, Deps1, State1}. diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 494624f..4a95a9a 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -35,8 +35,6 @@ deps_names/1, - overrides/1, overrides/2, - apply_overrides/2, resources/1, resources/2, add_resource/2, providers/1, providers/2, add_provider/2]). @@ -62,7 +60,6 @@ all_plugin_deps = [] :: [rebar_app_info:t()], all_deps = [] :: [rebar_app_info:t()], - overrides = [], resources = [], providers = []}). @@ -243,11 +240,6 @@ 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), - Opts = rebar_utils:apply_overrides(opts(State), Name, Overrides), - State#state_t{default=Opts, opts=Opts}. - add_to_profile(State, Profile, KVs) when is_atom(Profile), is_list(KVs) -> Opts = rebar_utils:add_to_profile(opts(State), Profile, KVs), State#state_t{opts=Opts}. @@ -310,12 +302,6 @@ 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 From d034f40c38753860c2da894f1966af5399f3efce Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 1 Sep 2015 17:48:04 -0500 Subject: move opts functions to new module rebar_opts --- src/rebar_app_discover.erl | 2 +- src/rebar_app_info.erl | 8 +-- src/rebar_dir.erl | 8 +-- src/rebar_erlc_compiler.erl | 16 ++--- src/rebar_hooks.erl | 4 +- src/rebar_opts.erl | 155 ++++++++++++++++++++++++++++++++++++++++++++ src/rebar_state.erl | 6 +- src/rebar_utils.erl | 152 +------------------------------------------ 8 files changed, 179 insertions(+), 172 deletions(-) create mode 100644 src/rebar_opts.erl diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 1052774..e702786 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -138,7 +138,7 @@ maybe_reset_hooks(C, Dir, State) -> reset_hooks(Opts) -> lists:foldl(fun(Key, OptsAcc) -> - rebar_utils:set(OptsAcc, Key, []) + rebar_opts:set(OptsAcc, Key, []) end, Opts, [post_hooks, pre_hooks, provider_hooks, artifacts]). -spec all_app_dirs(list(file:name())) -> list(file:name()). diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 1e5710f..268b09d 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -156,7 +156,7 @@ update_opts(AppInfo, Opts, Config) -> true = rebar_config:verify_config_format(Terms), LocalOpts = dict:from_list(Terms), - NewOpts = rebar_utils:merge_opts(LocalOpts, Opts), + NewOpts = rebar_opts:merge_opts(LocalOpts, Opts), AppInfo#app_info_t{opts=NewOpts ,default=NewOpts}. @@ -425,11 +425,11 @@ all(Dir, [File|Artifacts]) -> apply_overrides(Overrides, AppInfo) -> Name = binary_to_atom(rebar_app_info:name(AppInfo), utf8), - Opts = rebar_utils:apply_overrides(opts(AppInfo), Name, Overrides), + Opts = rebar_opts:apply_overrides(opts(AppInfo), Name, Overrides), AppInfo#app_info_t{default=Opts, opts=Opts}. add_to_profile(AppInfo, Profile, KVs) when is_atom(Profile), is_list(KVs) -> - Opts = rebar_utils:add_to_profile(opts(AppInfo), Profile, KVs), + Opts = rebar_opts:add_to_profile(opts(AppInfo), Profile, KVs), AppInfo#app_info_t{opts=Opts}. apply_profiles(AppInfo, Profile) when not is_list(Profile) -> @@ -456,7 +456,7 @@ apply_profiles(AppInfo=#app_info_t{default = Defaults, profiles=CurrentProfiles} case proplists:get_value(Profile, ConfigProfiles, []) of OptsList when is_list(OptsList) -> ProfileOpts = dict:from_list(OptsList), - rebar_utils:merge_opts(Profile, ProfileOpts, OptsAcc); + rebar_opts:merge_opts(Profile, ProfileOpts, OptsAcc); Other -> throw(?PRV_ERROR({profile_not_list, Profile, Other})) end diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl index 39fa723..7aeb11e 100644 --- a/src/rebar_dir.erl +++ b/src/rebar_dir.erl @@ -134,9 +134,9 @@ src_dirs(Opts) -> src_dirs(Opts, []). -spec src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()). src_dirs(Opts, Default) -> - ErlOpts = rebar_utils:erl_opts(Opts), + ErlOpts = rebar_opts:erl_opts(Opts), Vs = proplists:get_all_values(src_dirs, ErlOpts), - case lists:append([rebar_utils:get(Opts, src_dirs, []) | Vs]) of + case lists:append([rebar_opts:get(Opts, src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. @@ -146,9 +146,9 @@ extra_src_dirs(Opts) -> extra_src_dirs(Opts, []). -spec extra_src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()). extra_src_dirs(Opts, Default) -> - ErlOpts = rebar_utils:erl_opts(Opts), + ErlOpts = rebar_opts:erl_opts(Opts), Vs = proplists:get_all_values(extra_src_dirs, ErlOpts), - case lists:append([rebar_utils:get(Opts, extra_src_dirs, []) | Vs]) of + case lists:append([rebar_opts:get(Opts, extra_src_dirs, []) | Vs]) of [] -> Default; Dirs -> Dirs end. diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 869ade3..0fc5455 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -88,17 +88,17 @@ compile(AppInfo) -> -spec compile(rebar_dict(), file:name(), file:name()) -> 'ok'. compile(Opts, Dir, OutDir) -> rebar_base_compiler:run(Opts, - check_files(rebar_utils:get( + check_files(rebar_opts:get( Opts, xrl_first_files, [])), filename:join(Dir, "src"), ".xrl", filename:join(Dir, "src"), ".erl", fun compile_xrl/3), rebar_base_compiler:run(Opts, - check_files(rebar_utils:get( + check_files(rebar_opts:get( Opts, yrl_first_files, [])), filename:join(Dir, "src"), ".yrl", filename:join(Dir, "src"), ".erl", fun compile_yrl/3), rebar_base_compiler:run(Opts, - check_files(rebar_utils:get( + check_files(rebar_opts:get( Opts, mib_first_files, [])), filename:join(Dir, "mibs"), ".mib", filename:join([Dir, "priv", "mibs"]), ".bin", fun compile_mib/3), @@ -136,7 +136,7 @@ clean(_Opts, AppDir) -> -spec doterl_compile(rebar_dict(), file:filename(), file:filename()) -> ok. doterl_compile(Opts, Dir, ODir) -> - ErlOpts = rebar_utils:erl_opts(Opts), + ErlOpts = rebar_opts:erl_opts(Opts), doterl_compile(Opts, Dir, ODir, [], ErlOpts). doterl_compile(Opts, Dir, OutDir, MoreSources, ErlOpts) -> @@ -184,7 +184,7 @@ doterl_compile(Opts, Dir, OutDir, MoreSources, ErlOpts) -> %% and parse_transform options. Also produce specific erl_opts for these first %% files, so that yet to be compiled parse transformations are excluded from it. erl_first_files(Opts, ErlOpts, Dir, NeededErlFiles) -> - ErlFirstFilesConf = rebar_utils:get(Opts, erl_first_files, []), + ErlFirstFilesConf = rebar_opts:get(Opts, erl_first_files, []), NeededSrcDirs = lists:usort(lists:map(fun filename:dirname/1, NeededErlFiles)), %% NOTE: order of files here is important! ErlFirstFiles = @@ -430,7 +430,7 @@ compile_mib(Source, Target, Opts) -> ok = filelib:ensure_dir(filename:join([Dir, "include", "dummy.hrl"])), AllOpts = [{outdir, Dir} ,{i, [Dir]}] ++ - rebar_utils:get(Opts, mib_opts, []), + rebar_opts:get(Opts, mib_opts, []), case snmpc:compile(Source, AllOpts) of {ok, _} -> @@ -453,13 +453,13 @@ compile_mib(Source, Target, Opts) -> -spec compile_xrl(file:filename(), file:filename(), rebar_dict()) -> 'ok'. compile_xrl(Source, Target, Opts) -> - AllOpts = [{scannerfile, Target} | rebar_utils:get(Opts, xrl_opts, [])], + AllOpts = [{scannerfile, Target} | rebar_opts:get(Opts, xrl_opts, [])], compile_xrl_yrl(Opts, Source, Target, AllOpts, leex). -spec compile_yrl(file:filename(), file:filename(), rebar_dict()) -> 'ok'. compile_yrl(Source, Target, Opts) -> - AllOpts = [{parserfile, Target} | rebar_utils:get(Opts, yrl_opts, [])], + AllOpts = [{parserfile, Target} | rebar_opts:get(Opts, yrl_opts, [])], compile_xrl_yrl(Opts, Source, Target, AllOpts, yecc). -spec compile_xrl_yrl(rebar_dict(), file:filename(), diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index cb44b81..6db3c77 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -19,7 +19,7 @@ run_all_hooks(Dir, Type, Command, Providers, State) -> run_hooks(Dir, Type, Command, rebar_state:opts(State), State). run_provider_hooks(Dir, Type, Command, Providers, Opts, State) -> - case rebar_utils:get(Opts, provider_hooks, []) of + case rebar_opts:get(Opts, provider_hooks, []) of [] -> ok; AllHooks -> @@ -76,7 +76,7 @@ run_hooks(Dir, pre, Command, Opts, State) -> run_hooks(Dir, post, Command, Opts, State) -> run_hooks(Dir, post_hooks, Command, Opts, State); run_hooks(Dir, Type, Command, Opts, State) -> - case rebar_utils:get(Opts, Type, []) of + case rebar_opts:get(Opts, Type, []) of [] -> ok; Hooks -> diff --git a/src/rebar_opts.erl b/src/rebar_opts.erl new file mode 100644 index 0000000..47451c5 --- /dev/null +++ b/src/rebar_opts.erl @@ -0,0 +1,155 @@ +-module(rebar_opts). + +-export([get/2, + get/3, + set/3, + + erl_opts/1, + + apply_overrides/3, + add_to_profile/3, + merge_opts/2, + merge_opts/3]). + +-include("rebar.hrl"). + +get(Opts, Key) -> + {ok, Value} = dict:find(Key, Opts), + Value. + +get(Opts, Key, Default) -> + case dict:find(Key, Opts) of + {ok, Value} -> + Value; + error -> + Default + end. + +set(Opts, Key, Value) -> + dict:store(Key, Value, Opts). + +%% @doc Return list of erl_opts +-spec erl_opts(rebar_dict()) -> list(). +erl_opts(Opts) -> + RawErlOpts = filter_defines(?MODULE:get(Opts, erl_opts, []), []), + Defines = [{d, list_to_atom(D)} || + D <- ?MODULE:get(Opts, defines, [])], + AllOpts = Defines ++ RawErlOpts, + case proplists:is_defined(no_debug_info, AllOpts) of + true -> + [O || O <- AllOpts, O =/= no_debug_info]; + false -> + [debug_info|AllOpts] + 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) -> + set(OptsAcc1, {deps,default}, Value); + ({Key, Value}, OptsAcc1) -> + 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) -> + set(OptsAcc1, {deps,default}, Value); + ({Key, Value}, OptsAcc1) -> + 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 = ?MODULE:get(OptsAcc1, {deps,default}, []), + set(OptsAcc1, {deps,default}, Value++OldValue); + ({Key, Value}, OptsAcc1) -> + OldValue = ?MODULE:get(OptsAcc1, Key, []), + 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 = ?MODULE:get(Opts, profiles, []), + ProfileOpts = dict:from_list(proplists:get_value(Profile, Profiles, [])), + NewOpts = merge_opts(Profile, dict:from_list(KVs), ProfileOpts), + NewProfiles = [{Profile, dict:to_list(NewOpts)}|lists:keydelete(Profile, 1, Profiles)], + 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(NewValue, OldValue) + end; + (_Key, NewValue, _OldValue) -> + NewValue + end, NewOpts, OldOpts). + +%% Internal functions + +%% +%% Filter a list of erl_opts platform_define options such that only +%% those which match the provided architecture regex are returned. +%% +filter_defines([], Acc) -> + lists:reverse(Acc); +filter_defines([{platform_define, ArchRegex, Key} | Rest], Acc) -> + case rebar_utils:is_arch(ArchRegex) of + true -> + filter_defines(Rest, [{d, Key} | Acc]); + false -> + filter_defines(Rest, Acc) + end; +filter_defines([{platform_define, ArchRegex, Key, Value} | Rest], Acc) -> + case rebar_utils:is_arch(ArchRegex) of + true -> + filter_defines(Rest, [{d, Key, Value} | Acc]); + false -> + filter_defines(Rest, Acc) + end; +filter_defines([Opt | Rest], Acc) -> + filter_defines(Rest, [Opt | Acc]). diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 4a95a9a..2a5aa01 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -105,7 +105,7 @@ new(ParentState, Config, Deps, Dir) -> true = rebar_config:verify_config_format(Terms), LocalOpts = dict:from_list(Terms), - NewOpts = rebar_utils:merge_opts(LocalOpts, Opts), + NewOpts = rebar_opts:merge_opts(LocalOpts, Opts), ParentState#state_t{dir=Dir ,opts=NewOpts @@ -241,7 +241,7 @@ command_parsed_args(State, CmdArgs) -> State#state_t{command_parsed_args=CmdArgs}. add_to_profile(State, Profile, KVs) when is_atom(Profile), is_list(KVs) -> - Opts = rebar_utils:add_to_profile(opts(State), Profile, KVs), + Opts = rebar_opts:add_to_profile(opts(State), Profile, KVs), State#state_t{opts=Opts}. apply_profiles(State, Profile) when not is_list(Profile) -> @@ -268,7 +268,7 @@ apply_profiles(State=#state_t{default = Defaults, current_profiles=CurrentProfil case proplists:get_value(Profile, ConfigProfiles, []) of OptsList when is_list(OptsList) -> ProfileOpts = dict:from_list(OptsList), - rebar_utils:merge_opts(Profile, ProfileOpts, OptsAcc); + rebar_opts:merge_opts(Profile, ProfileOpts, OptsAcc); Other -> throw(?PRV_ERROR({profile_not_list, Profile, Other})) end diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 7260f6d..564b384 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -26,10 +26,7 @@ %% ------------------------------------------------------------------- -module(rebar_utils). --export([get/2, - get/3, - set/3, - sort_deps/1, +-export([sort_deps/1, droplast/1, filtermap/2, is_arch/1, @@ -48,7 +45,6 @@ vcs_vsn/3, deprecated/3, deprecated/4, - erl_opts/1, indent/1, update_code/1, remove_from_code_path/1, @@ -69,11 +65,7 @@ escape_double_quotes_weak/1, check_min_otp_version/1, check_blacklisted_otp_versions/1, - info_useless/2, - apply_overrides/3, - add_to_profile/3, - merge_opts/2, - merge_opts/3]). + info_useless/2]). %% for internal use only -export([otp_release/0]). @@ -87,21 +79,6 @@ %% Public API %% ==================================================================== -get(Opts, Key) -> - {ok, Value} = dict:find(Key, Opts), - Value. - -get(Opts, Key, Default) -> - case dict:find(Key, Opts) of - {ok, Value} -> - Value; - error -> - Default - end. - -set(Opts, Key, Value) -> - dict:store(Key, Value, Opts). - sort_deps(Deps) -> %% We need a sort stable, based on the name. So that for multiple deps on %% the same level with the same name, we keep the order the parents had. @@ -240,20 +217,6 @@ deprecated(Old, New, When) -> "'~p' will be removed ~s.~n">>, [Old, Old, New, Old, When]). -%% @doc Return list of erl_opts --spec erl_opts(rebar_dict()) -> list(). -erl_opts(Opts) -> - RawErlOpts = filter_defines(rebar_utils:get(Opts, erl_opts, []), []), - Defines = [{d, list_to_atom(D)} || - D <- rebar_utils:get(Opts, defines, [])], - AllOpts = Defines ++ RawErlOpts, - case proplists:is_defined(no_debug_info, AllOpts) of - true -> - [O || O <- AllOpts, O =/= no_debug_info]; - false -> - [debug_info|AllOpts] - end. - %% for use by `do` task %% note: this does not handle the case where you have an argument that @@ -407,94 +370,6 @@ 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 %% ==================================================================== @@ -759,29 +634,6 @@ find_resource_module(Type, Resources) -> {ok, Module} end. -%% -%% Filter a list of erl_opts platform_define options such that only -%% those which match the provided architecture regex are returned. -%% -filter_defines([], Acc) -> - lists:reverse(Acc); -filter_defines([{platform_define, ArchRegex, Key} | Rest], Acc) -> - case rebar_utils:is_arch(ArchRegex) of - true -> - filter_defines(Rest, [{d, Key} | Acc]); - false -> - filter_defines(Rest, Acc) - end; -filter_defines([{platform_define, ArchRegex, Key, Value} | Rest], Acc) -> - case rebar_utils:is_arch(ArchRegex) of - true -> - filter_defines(Rest, [{d, Key, Value} | Acc]); - false -> - filter_defines(Rest, Acc) - end; -filter_defines([Opt | Rest], Acc) -> - filter_defines(Rest, [Opt | Acc]). - %% @doc ident to the level specified -spec indent(non_neg_integer()) -> iolist(). indent(Amount) when erlang:is_integer(Amount) -> -- cgit v1.1 From a81444ae1c32fb1ff73bd571327fd6adeec9901f Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 1 Sep 2015 19:42:01 -0500 Subject: move otp version verification to a single app_info function --- src/rebar_app_discover.erl | 4 ++-- src/rebar_app_info.erl | 5 +++++ src/rebar_prv_install_deps.erl | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index e702786..9d7c62a 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -84,8 +84,8 @@ merge_deps(AppInfo, State) -> AppInfo1 = rebar_app_info:apply_overrides(rebar_state:get(State, overrides, []), AppInfo0), AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, CurrentProfiles), - rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo2, minimum_otp_vsn, undefined)), - rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo2, blacklisted_otp_vsns, [])), + %% Will throw an exception if checks fail + rebar_app_info:verify_otp_vsn(AppInfo2), State1 = lists:foldl(fun(Profile, StateAcc) -> handle_profile(Profile, Name, AppInfo2, StateAcc) diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 268b09d..92706f3 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -53,6 +53,7 @@ valid/1, valid/2, + verify_otp_vsn/1, has_all_artifacts/1, apply_overrides/2, @@ -404,6 +405,10 @@ valid(#app_info_t{valid=Valid}) -> valid(AppInfo=#app_info_t{}, Valid) -> AppInfo#app_info_t{valid=Valid}. +verify_otp_vsn(AppInfo) -> + rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo, minimum_otp_vsn, undefined)), + rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo, blacklisted_otp_vsns, [])). + -spec has_all_artifacts(#app_info_t{}) -> true | {false, file:filename()}. has_all_artifacts(AppInfo) -> Artifacts = rebar_app_info:get(AppInfo, artifacts, []), diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index cb1bf00..fd1aa49 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -262,8 +262,8 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) -> Plugins = rebar_app_info:get(AppInfo2, plugins, []), AppInfo3 = rebar_app_info:set(AppInfo2, {plugins, Profile}, Plugins), - rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo3, minimum_otp_vsn, undefined)), - rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo3, blacklisted_otp_vsns, [])), + %% Will throw an exception if checks fail + rebar_app_info:verify_otp_vsn(AppInfo3), %% Dep may have plugins to install. Find and install here. State1 = rebar_plugins:install(State, AppInfo3), -- cgit v1.1