summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar_app_discover.erl12
-rw-r--r--src/rebar_prv_compile.erl (renamed from src/rebar_prv_app_builder.erl)8
-rw-r--r--src/rebar_prv_install_deps.erl143
-rw-r--r--src/rebar_state.erl42
4 files changed, 117 insertions, 88 deletions
diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl
index aaaeb03..12193b5 100644
--- a/src/rebar_app_discover.erl
+++ b/src/rebar_app_discover.erl
@@ -7,8 +7,9 @@
do(State, LibDirs) ->
Apps = find_apps(LibDirs, all),
+ ProjectDeps = rebar_state:deps_names(State),
lists:foldl(fun(AppInfo, StateAcc) ->
- rebar_state:apps_to_build(StateAcc, AppInfo)
+ rebar_state:project_apps(StateAcc, rebar_app_info:deps(AppInfo, ProjectDeps))
end, State, Apps).
-spec all_app_dirs(list(file:name())) -> list(file:name()).
@@ -35,15 +36,10 @@ app_dirs(LibDir) ->
"*.app"]),
lists:usort(lists:foldl(fun(Path, Acc) ->
- Files = filelib:wildcard(to_list(Path)),
+ Files = filelib:wildcard(ec_cnv:to_list(Path)),
[app_dir(File) || File <- Files] ++ Acc
end, [], [Path1, Path2, Path3, Path4])).
-to_list(S) when is_list(S) ->
- S;
-to_list(S) when is_binary(S) ->
- binary_to_list(S).
-
find_unbuilt_apps(LibDirs) ->
find_apps(LibDirs, invalid).
@@ -149,7 +145,7 @@ get_modules_list(AppFile, AppDetail) ->
ok | {error, Reason::term()}.
has_all_beams(EbinDir, [Module | ModuleList]) ->
BeamFile = filename:join([EbinDir,
- list_to_binary(atom_to_list(Module) ++ ".beam")]),
+ ec_cnv:to_list(Module) ++ ".beam"]),
case filelib:is_file(BeamFile) of
true ->
has_all_beams(EbinDir, ModuleList);
diff --git a/src/rebar_prv_app_builder.erl b/src/rebar_prv_compile.erl
index 4c2d978..6eb2339 100644
--- a/src/rebar_prv_app_builder.erl
+++ b/src/rebar_prv_compile.erl
@@ -1,4 +1,4 @@
--module(rebar_prv_app_builder).
+-module(rebar_prv_compile).
-behaviour(rebar_provider).
@@ -29,10 +29,12 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error().
do(State) ->
- Apps = rebar_state:apps_to_build(State),
+ Apps = rebar_state:project_apps(State),
lists:foreach(fun(AppInfo) ->
- _AppInfo1 = build(State, AppInfo)
+ C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
+ S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(AppInfo)),
+ _AppInfo1 = build(S, AppInfo)
end, Apps),
rebar_lock:create(State),
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 3e13fc2..ebb877b 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -42,6 +42,11 @@
-define(PROVIDER, install_deps).
-define(DEPS, [app_discovery]).
+-type src_dep() :: {atom(), string(), {atom(), string(), string()}}.
+-type binary_dep() :: {atom(), binary()} | atom().
+
+-type dep() :: src_dep() | binary_dep().
+
%% ===================================================================
%% Public API
%% ===================================================================
@@ -60,53 +65,9 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()}.
do(State) ->
- %% Read in package index and dep graph
- {Packages, Graph} = rebar_packages:get_packages(State),
case rebar_state:get(State, locks, []) of
[] ->
- case rebar_state:get(State, deps, []) of
- [] ->
- {ok, State};
- Deps ->
- %% Split source deps form binary deps, needed to keep backwards compatibility
- DepsDir = get_deps_dir(State),
- {SrcDeps, Goals} = parse_deps(DepsDir, Deps),
- State1 = rebar_state:src_deps(rebar_state:goals(State, Goals), lists:ukeysort(2, SrcDeps)),
- State2 = update_src_deps(State1),
- case rebar_state:goals(State2) of
- [] ->
- ProjectApps = lists:map(fun(X) ->
- rebar_app_info:deps(X, [rebar_app_info:name(Y) || Y <- SrcDeps])
- end, rebar_state:apps_to_build(State2)),
- FinalDeps = ProjectApps ++ rebar_state:src_deps(State2),
- {ok, Sort} = rebar_topo:sort_apps(FinalDeps),
- State3 = rebar_state:apps_to_build(State2, Sort),
- {ok, State3};
- Goals1 ->
- {ok, Solved} = rlx_depsolver:solve(Graph, Goals1),
- Final = lists:map(fun({Name, Vsn}) ->
- FmtVsn = ec_cnv:to_binary(rlx_depsolver:format_version(Vsn)),
- {ok, P} = dict:find({Name, FmtVsn}, Packages),
- PkgDeps = proplists:get_value(<<"deps">>, P),
- Link = proplists:get_value(<<"link">>, P),
- Source = {Name, FmtVsn, Link},
- {ok, AppInfo} = rebar_app_info:new(Name, FmtVsn),
- AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
- AppInfo2 =
- rebar_app_info:dir(AppInfo1, get_deps_dir(DepsDir, <<Name/binary, "-", FmtVsn/binary>>)),
- AppInfo3 = rebar_app_info:source(AppInfo2, Source),
- ok = maybe_fetch(AppInfo3),
- AppInfo3
- end, Solved),
- ProjectApps = lists:map(fun(X) ->
- rebar_app_info:deps(X, [rebar_app_info:name(Y) || Y <- SrcDeps] ++ [element(1, G) || G <- Goals1])
- end, rebar_state:apps_to_build(State2)),
- FinalDeps = ProjectApps ++ rebar_state:src_deps(State2) ++ Final,
- {ok, Sort} = rebar_topo:sort_apps(FinalDeps),
- State3 = rebar_state:apps_to_build(State2, Sort),
- {ok, State3}
- end
- end;
+ handle_deps(State, rebar_state:get(State, deps, []));
_Locks ->
{ok, State}
end.
@@ -130,10 +91,12 @@ setup_env(State) ->
[{"REBAR_DEPS_DIR", DepsDir}, ERL_LIBS].
+-spec get_deps_dir(rebar_state:t()) -> file:filename_all().
get_deps_dir(State) ->
BaseDir = rebar_state:get(State, base_dir, ""),
get_deps_dir(BaseDir, "deps").
+-spec get_deps_dir(file:filename_all(), rebar_state:t()) -> file:filename_all().
get_deps_dir(DepsDir, App) ->
filename:join(DepsDir, App).
@@ -141,28 +104,84 @@ get_deps_dir(DepsDir, App) ->
%% Internal functions
%% ===================================================================
+handle_deps(State, []) ->
+ {ok, State};
+handle_deps(State, Deps) ->
+ %% Read in package index and dep graph
+ {Packages, Graph} = rebar_packages:get_packages(State),
+ ProjectApps = rebar_state:project_apps(State),
+
+ %% Split source deps form binary deps, needed to keep backwards compatibility
+ DepsDir = get_deps_dir(State),
+ {SrcDeps, BinaryDeps} = parse_deps(DepsDir, Deps),
+ State1 = rebar_state:src_deps(rebar_state:binary_deps(State, BinaryDeps),
+ lists:ukeysort(2, SrcDeps)),
+
+ %% Fetch transitive src deps
+ State2 = update_src_deps(State1),
+ Solved = case rebar_state:binary_deps(State2) of
+ [] -> %% No binary deps
+ [];
+ BinaryDeps1 ->
+ %% Find binary deps needed
+ {ok, S} = rlx_depsolver:solve(Graph, BinaryDeps1),
+
+ %% Create app_info record for each binary dep
+ lists:map(fun({Name, Vsn}) ->
+ AppInfo = package_to_app(DepsDir
+ ,Packages
+ ,Name
+ ,Vsn),
+ ok = maybe_fetch(AppInfo),
+ AppInfo
+ end, S)
+ end,
+
+ FinalDeps = ProjectApps ++ rebar_state:src_deps(State2) ++ Solved,
+ %% Sort all apps to build order
+ {ok, Sort} = rebar_topo:sort_apps(FinalDeps),
+ {ok, rebar_state:project_apps(State2, Sort)}.
+
+-spec package_to_app(file:name(), dict:dict(), binary(), binary()) -> rebar_app_info:t().
+package_to_app(DepsDir, Packages, Name, Vsn) ->
+ FmtVsn = ec_cnv:to_binary(rlx_depsolver:format_version(Vsn)),
+
+ {ok, P} = dict:find({Name, FmtVsn}, Packages),
+ PkgDeps = proplists:get_value(<<"deps">>, P),
+ Link = proplists:get_value(<<"link">>, P),
+
+ {ok, AppInfo} = rebar_app_info:new(Name, FmtVsn),
+ AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
+ AppInfo2 =
+ rebar_app_info:dir(AppInfo1, get_deps_dir(DepsDir, <<Name/binary, "-", FmtVsn/binary>>)),
+ rebar_app_info:source(AppInfo2, {Name, FmtVsn, Link}).
+
+-spec update_src_deps(rebar_state:t()) -> rebat_state:t().
update_src_deps(State) ->
SrcDeps = rebar_state:src_deps(State),
DepsDir = get_deps_dir(State),
- case lists:foldl(fun(AppInfo, {SrcDepsAcc, GoalsAcc}) ->
+ case lists:foldl(fun(AppInfo, {SrcDepsAcc, BinaryDepsAcc}) ->
ok = maybe_fetch(AppInfo),
- {NewSrcDeps, NewGoals} = handle_dep(DepsDir, AppInfo),
- {lists:ukeymerge(2, SrcDepsAcc, lists:ukeysort(2, NewSrcDeps)), NewGoals++GoalsAcc}
- end, {SrcDeps, rebar_state:goals(State)}, SrcDeps) of
- {SrcDeps, NewGoals} ->
- rebar_state:goals(State, NewGoals);
- {NewSrcDeps, NewGoals} ->
- io:format("NEWSRC ~p~n", [NewSrcDeps]),
- State1 = rebar_state:src_deps(rebar_state:goals(State, NewGoals), NewSrcDeps),
+ {AppInfo1, NewSrcDeps, NewBinaryDeps} = handle_dep(DepsDir, AppInfo),
+ {lists:ukeymerge(2, lists:ukeysort(2, [AppInfo1 | SrcDepsAcc]), lists:ukeysort(2, NewSrcDeps)), NewBinaryDeps++BinaryDepsAcc}
+ end, {[], rebar_state:binary_deps(State)}, SrcDeps) of
+ {NewSrcDeps, NewBinaryDeps} when length(SrcDeps) =:= length(NewSrcDeps) ->
+ rebar_state:src_deps(rebar_state:binary_deps(State, NewBinaryDeps), NewSrcDeps);
+ {NewSrcDeps, NewBinaryDeps} ->
+ State1 = rebar_state:src_deps(rebar_state:binary_deps(State, NewBinaryDeps), NewSrcDeps),
update_src_deps(State1)
end.
+-spec handle_dep(binary(), rebar_state:t()) -> {[rebar_app_info:t()], [binary_dep()]}.
handle_dep(DepsDir, AppInfo) ->
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(AppInfo)),
Deps = rebar_state:get(S, deps, []),
- parse_deps(DepsDir, Deps).
+ AppInfo1 = rebar_app_info:deps(AppInfo, rebar_state:deps_names(S)),
+ {SrcDeps, BinaryDeps} = parse_deps(DepsDir, Deps),
+ {AppInfo1, SrcDeps, BinaryDeps}.
+-spec maybe_fetch(rebar_app_info:t()) -> ok.
maybe_fetch(AppInfo) ->
AppDir = rebar_app_info:dir(AppInfo),
case filelib:is_dir(AppDir) of
@@ -174,19 +193,21 @@ maybe_fetch(AppInfo) ->
ok
end.
+-spec parse_deps(binary(), [dep()]) -> {[rebar_app_info:t()], [binary_dep()]}.
parse_deps(DepsDir, Deps) ->
- lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, GoalsAcc}) ->
+ lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, BinaryDepsAcc}) ->
{SrcDepsAcc, [parse_goal(ec_cnv:to_binary(Name)
- ,ec_cnv:to_binary(Vsn)) | GoalsAcc]};
- (Name, {SrcDepsAcc, GoalsAcc}) when is_atom(Name) ->
- {SrcDepsAcc, [ec_cnv:to_binary(Name) | GoalsAcc]};
- ({Name, _, Source}, {SrcDepsAcc, GoalsAcc}) ->
+ ,ec_cnv:to_binary(Vsn)) | BinaryDepsAcc]};
+ (Name, {SrcDepsAcc, BinaryDepsAcc}) when is_atom(Name) ->
+ {SrcDepsAcc, [ec_cnv:to_binary(Name) | BinaryDepsAcc]};
+ ({Name, _, Source}, {SrcDepsAcc, BinaryDepsAcc}) ->
{ok, Dep} = rebar_app_info:new(Name),
Dep1 = rebar_app_info:source(
rebar_app_info:dir(Dep, get_deps_dir(DepsDir, Name)), Source),
- {[Dep1 | SrcDepsAcc], GoalsAcc}
+ {[Dep1 | SrcDepsAcc], BinaryDepsAcc}
end, {[], []}, Deps).
+-spec parse_goal(binary(), binary()) -> binary_dep().
parse_goal(Name, Constraint) ->
case re:run(Constraint, "([^\\d]*)(\\d.*)", [{capture, [1,2], binary}]) of
{match, [<<>>, Vsn]} ->
diff --git a/src/rebar_state.erl b/src/rebar_state.erl
index fc5d750..da0c9d8 100644
--- a/src/rebar_state.erl
+++ b/src/rebar_state.erl
@@ -7,9 +7,10 @@
set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1,
create_logic_providers/2,
- apps_to_build/1, apps_to_build/2,
+ project_apps/1, project_apps/2,
- goals/1, goals/2,
+ deps_names/1,
+ binary_deps/1, binary_deps/2,
src_deps/1, src_deps/2,
providers/1, providers/2, add_provider/2]).
@@ -33,10 +34,10 @@
command_args = [] :: list(),
src_deps = [] :: [rebar_app_info:t()],
- apps = dict:new() :: rebar_dict(),
- goals = [],
+ binary_deps = [],
+ project_apps = [],
+
providers = [],
- apps_to_build = [],
skip_dirs = new_skip_dirs() :: rebar_dict() }).
-export_type([t/0]).
@@ -105,13 +106,22 @@ command_args(#state_t{command_args=CmdArgs}) ->
command_args(State, CmdArgs) ->
State#state_t{command_args=CmdArgs}.
-goals(#state_t{goals=Goals}) ->
- Goals.
-goals(State=#state_t{goals=Goals}, NewGoals) when is_list(Goals) ->
- State#state_t{goals=NewGoals};
-goals(State=#state_t{goals=Goals}, Goal) ->
- State#state_t{goals=[Goal | Goals]}.
+deps_names(State) ->
+ Deps = rebar_state:get(State, deps, []),
+ lists:map(fun(Dep) when is_tuple(Dep) ->
+ ec_cnv:to_binary(element(1, Dep));
+ (Dep) when is_atom(Dep) ->
+ ec_cnv:to_binary(Dep)
+ end, Deps).
+
+binary_deps(#state_t{binary_deps=BinaryDeps}) ->
+ BinaryDeps.
+
+binary_deps(State=#state_t{binary_deps=BinaryDeps}, NewBinaryDeps) when is_list(BinaryDeps) ->
+ State#state_t{binary_deps=NewBinaryDeps};
+binary_deps(State=#state_t{binary_deps=BinaryDeps}, BinaryDep) ->
+ State#state_t{binary_deps=[BinaryDep | BinaryDeps]}.
src_deps(#state_t{src_deps=SrcDeps}) ->
SrcDeps.
@@ -121,13 +131,13 @@ src_deps(State=#state_t{src_deps=SrcDeps}, NewSrcDeps) when is_list(SrcDeps) ->
src_deps(State=#state_t{src_deps=SrcDeps}, SrcDep) ->
State#state_t{src_deps=[SrcDep | SrcDeps]}.
-apps_to_build(#state_t{apps_to_build=Apps}) ->
+project_apps(#state_t{project_apps=Apps}) ->
Apps.
-apps_to_build(State=#state_t{apps_to_build=Apps}, NewApps) when is_list(NewApps) ->
- State#state_t{apps_to_build=NewApps};
-apps_to_build(State=#state_t{apps_to_build=Apps}, App) ->
- State#state_t{apps_to_build=[App | Apps]}.
+project_apps(State=#state_t{}, NewApps) when is_list(NewApps) ->
+ State#state_t{project_apps=NewApps};
+project_apps(State=#state_t{project_apps=Apps}, App) ->
+ State#state_t{project_apps=[App | Apps]}.
providers(#state_t{providers=Providers}) ->
Providers.