summaryrefslogtreecommitdiff
path: root/src/rebar_prv_app_builder.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_prv_app_builder.erl')
-rw-r--r--src/rebar_prv_app_builder.erl95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/rebar_prv_app_builder.erl b/src/rebar_prv_app_builder.erl
new file mode 100644
index 0000000..6d1498d
--- /dev/null
+++ b/src/rebar_prv_app_builder.erl
@@ -0,0 +1,95 @@
+-module(rebar_prv_app_builder).
+
+-behaviour(rebar_provider).
+
+-export([init/1,
+ do/1]).
+
+-include("rebar.hrl").
+
+-define(PROVIDER, app_builder).
+-define(DEPS, [deps]).
+
+%% ===================================================================
+%% Public API
+%% ===================================================================
+
+-spec init(rebar_config:config()) -> {ok, rebar_config:config()}.
+init(State) ->
+ State1 = rebar_config:add_provider(State, #provider{name = ?PROVIDER,
+ provider_impl = ?MODULE,
+ provides = build,
+ bare = false,
+ deps = ?DEPS,
+ example = "rebar build",
+ short_desc = "",
+ desc = "",
+ opts = []}),
+ {ok, State1}.
+
+-spec do(rebar_config:config()) -> {ok, rebar_config:config()} | relx:error().
+do(Config) ->
+ Deps = rebar_config:deps_to_build(Config),
+ Apps = rebar_config:apps_to_build(Config),
+ Config1 =
+ lists:foldl(fun(AppInfo, ConfigAcc) ->
+ ?CONSOLE("Building ~p version ~p~n", [rebar_app_info:name(AppInfo)
+ ,rebar_app_info:original_vsn(AppInfo)]),
+ {_AppInfo1, ConfigAcc1} = build(ConfigAcc, AppInfo),
+ ConfigAcc
+ end, Config, Deps++Apps),
+ Graph = construct_graph(Config),
+ Goals = rebar_config:goals(Config1),
+ {ok, Solve} = rlx_depsolver:solve(Graph, Goals),
+
+ DepsDir = get_deps_dir(Config1),
+ LockDeps = lists:map(fun({Name, _, Source}) ->
+ Dir = get_deps_dir(DepsDir, Name),
+ {Name, Vsn} = lists:keyfind(Name, 1, Solve),
+ rebar_fetch:new(Dir, Name, format_vsn(Vsn), Source)
+ end, rebar_config:deps(Config)),
+ ok = file:write_file("./rebar.lock", io_lib:format("~p.~n", [LockDeps])),
+ {ok, Config1}.
+
+build(Config, AppInfo) ->
+ {ok, AppInfo1} = rebar_otp_app:compile(Config, AppInfo),
+ Config1 = rebar_config:replace_app(Config, rebar_app_info:name(AppInfo1), AppInfo1),
+ rebar_erlc_compiler:compile(Config, rebar_app_info:dir(AppInfo1)),
+ {AppInfo1, Config1}.
+
+%% ===================================================================
+%% Internal functions
+%% ===================================================================
+
+construct_graph(Config) ->
+ LibDirs = rebar_config:get_local(Config, lib_dirs, ["apps", "libs", "."]),
+ DepsDir = rebar_deps:get_deps_dir(Config),
+ Graph = rlx_depsolver:new_graph(),
+ Apps = rebar_app_discover:find_apps([DepsDir | LibDirs]),
+ lists:foldl(fun(AppInfo, GraphAcc) ->
+ Name = rebar_app_info:name(AppInfo),
+ Vsn = rebar_app_info:original_vsn(AppInfo),
+ C = rebar_config:new2(rebar_config:new(), rebar_app_info:dir(AppInfo)),
+ LocalDeps = rebar_config:get_local(C, deps, []),
+ PkgDeps = lists:map(fun({A, "", _}) ->
+ A;
+ ({A, ".*", _}) ->
+ A;
+ ({A, V, _}) ->
+ {A, V}
+ end, LocalDeps),
+ rlx_depsolver:add_package_version(GraphAcc
+ ,Name
+ ,Vsn
+ ,PkgDeps)
+ end, Graph, Apps).
+
+get_deps_dir(Config) ->
+ BaseDir = rebar_utils:base_dir(Config),
+ get_deps_dir(BaseDir, deps).
+
+get_deps_dir(DepsDir, App) ->
+ filename:join(DepsDir, atom_to_list(App)).
+
+format_vsn(Vsn) ->
+ binary_to_list(iolist_to_binary(ec_semver:format(Vsn))).