From 5ccb0572cb7d6c6d10ab5c09d7a4b0981215d933 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 29 Sep 2018 15:50:56 -0600 Subject: [PATCH] use project_type to find module for building projects --- src/rebar_app_discover.erl | 2 +- src/rebar_app_info.erl | 18 +++++++++--------- src/rebar_app_utils.erl | 5 ++--- src/rebar_prv_compile.erl | 31 ++++++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 655094ae..74681c73 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -427,7 +427,7 @@ try_handle_app_src_file(AppInfo, _, _AppDir, [], _Validate) -> %% a .app after this step case filelib:is_file(filename:join(rebar_app_info:dir(AppInfo), "mix.exs")) of true -> - {true, rebar_app_info:compile_type(AppInfo, mix)}; + {true, rebar_app_info:project_type(AppInfo, mix)}; false -> false end; diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index a49a4eb6..62f9143f 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -48,8 +48,8 @@ set/3, source/1, source/2, - compile_type/1, - compile_type/2, + project_type/1, + project_type/2, is_lock/1, is_lock/2, is_checkout/1, @@ -93,7 +93,7 @@ is_lock=false :: boolean(), is_checkout=false :: boolean(), valid :: boolean() | undefined, - compile_type :: rebar3 | mix | undefined, + project_type :: rebar3 | mix | undefined, is_available=false :: boolean()}). %%============================================================================ @@ -518,14 +518,14 @@ is_available(AppInfo=#app_info_t{}, IsAvailable) -> AppInfo#app_info_t{is_available=IsAvailable}. %% @doc --spec compile_type(t()) -> atom(). -compile_type(#app_info_t{compile_type=CompileType}) -> - CompileType. +-spec project_type(t()) -> atom(). +project_type(#app_info_t{project_type=ProjectType}) -> + ProjectType. %% @doc --spec compile_type(t(), atom()) -> t(). -compile_type(AppInfo=#app_info_t{}, CompileType) -> - AppInfo#app_info_t{compile_type=CompileType}. +-spec project_type(t(), atom()) -> t(). +project_type(AppInfo=#app_info_t{}, ProjectType) -> + AppInfo#app_info_t{project_type=ProjectType}. %% @doc returns whether the app is valid (built) or not diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index fb08ea94..605944ee 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -273,9 +273,8 @@ update_source(AppInfo, Source, _State) -> -spec format_error(any()) -> iolist(). format_error({missing_package, Name, undefined}) -> io_lib:format("Package not found in any repo: ~ts", [rebar_utils:to_binary(Name)]); -format_error({missing_package, Name, Vsn}) -> - io_lib:format("Package not found in any repo: ~ts ~ts", [rebar_utils:to_binary(Name), - rebar_utils:to_binary(Vsn)]); +format_error({missing_package, Name, Constraint}) -> + io_lib:format("Package not found in any repo: ~ts ~ts", [Name, Constraint]); format_error({parse_dep, Dep}) -> io_lib:format("Failed parsing dep ~p", [Dep]); format_error({invalid_vsn, Dep, InvalidVsn}) -> diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 98dacbfd..4c1a4eb2 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -92,6 +92,12 @@ handle_project_apps(DepsPaths, Providers, State) -> -spec format_error(any()) -> iolist(). format_error({missing_artifact, File}) -> io_lib:format("Missing artifact ~ts", [File]); +format_error({bad_project_builder, Name, Type, Module}) -> + io_lib:format("Error building application ~s:~n Required project builder ~s function " + "~s:build/1 not found", [Name, Type, Module]); +format_error({unknown_project_type, Name, Type}) -> + io_lib:format("Error building application ~s:~n " + "No project builder is configured for type ~s", [Name, Type]); format_error(Reason) -> io_lib:format("~p", [Reason]). @@ -135,7 +141,7 @@ build_extra_dir(State, Dir) -> true -> BaseDir = filename:join([rebar_dir:base_dir(State), "extras"]), OutDir = filename:join([BaseDir, Dir]), - filelib:ensure_dir(filename:join([OutDir, "dummy.beam"])), + rebar_file_utils:ensure_dir(OutDir), copy(rebar_state:dir(State), BaseDir, Dir), Compilers = rebar_state:compilers(State), @@ -160,8 +166,7 @@ compile(State, Providers, AppInfo) -> AppInfo2 = rebar_hooks:run_all_hooks(AppDir, pre, ?ERLC_HOOK, Providers, AppInfo1, State), - Compilers = rebar_state:compilers(State), - rebar_compiler:compile_all(Compilers, AppInfo2), + build_app(AppInfo2, State), AppInfo3 = rebar_hooks:run_all_hooks(AppDir, post, ?ERLC_HOOK, Providers, AppInfo2, State), @@ -191,6 +196,26 @@ compile(State, Providers, AppInfo) -> %% Internal functions %% =================================================================== +build_app(AppInfo, State) -> + case rebar_app_info:project_type(AppInfo) of + T when T =:= rebar3 ; T =:= undefined -> + Compilers = rebar_state:compilers(State), + rebar_compiler:compile_all(Compilers, AppInfo); + T -> + ProjectBuilders = rebar_state:get(State, project_builders, []), + case lists:keyfind(T, 1, ProjectBuilders) of + {_, Module} -> + _ = code:ensure_loaded(Module), + case erlang:function_exported(Module, build, 1) of + true -> + Module:build(AppInfo); + false -> + throw(?PRV_ERROR({bad_project_builder, rebar_app_info:name(AppInfo), T, Module})) + end; + _ -> + throw(?PRV_ERROR({unknown_project_type, rebar_app_info:name(AppInfo), T})) + end + end. update_code_paths(State, ProjectApps, DepsPaths) -> ProjAppsPaths = paths_for_apps(ProjectApps), ExtrasPaths = paths_for_extras(State, ProjectApps),