summaryrefslogtreecommitdiff
path: root/src/rebar_prv_install_deps.erl
diff options
context:
space:
mode:
authorTristan Sloughter <t@crashfast.com>2014-08-29 22:36:46 -0500
committerTristan Sloughter <t@crashfast.com>2014-08-29 22:37:28 -0500
commitac0d726bb8c21eca3b883f7c47e42cdea02b5a3f (patch)
tree0870210a2656a493454ab8918d3ade43c2b05dc7 /src/rebar_prv_install_deps.erl
parent901cea4671864cebc6d7da40e14a004ad2ad8687 (diff)
wip: reworking deps fetching/sorting
Diffstat (limited to 'src/rebar_prv_install_deps.erl')
-rw-r--r--src/rebar_prv_install_deps.erl159
1 files changed, 48 insertions, 111 deletions
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index ccfb3b0..40df88c 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -42,10 +42,6 @@
-define(PROVIDER, install_deps).
-define(DEPS, [app_discovery]).
--record(dep, {name :: binary(),
- vsn :: binary(),
- source :: binary()}).
-
%% ===================================================================
%% Public API
%% ===================================================================
@@ -74,30 +70,30 @@ do(State) ->
Deps ->
%% Split source deps form binary deps, needed to keep backwards compatibility
{SrcDeps, Goals} = parse_deps(Deps),
- case update_src_deps(State, SrcDeps, Goals, [], []) of
- {State1, SrcDeps1, [], Locked} ->
- {ok, rebar_state:set(State1, locks, Locked)};
- {State1, SrcDeps1, Goals1, Locked} ->
- {ok, Solved} = rlx_depsolver:solve(Graph, Goals1),
- M = lists:map(fun({Name, Vsn}) ->
- FmtVsn = ec_cnv:to_binary(rlx_depsolver:format_version(Vsn)),
- {ok, P} = dict:find({Name, FmtVsn}, Packages),
- Link = proplists:get_value(<<"link">>, P),
- #dep{name=Name,
- vsn=FmtVsn,
- source={Name
- ,FmtVsn
- ,Link}}
- end, Solved),
- {State2, Deps1, _, Locked2} = update_deps(State1, M),
- State3 = rebar_state:set(State2, locks, Locked++Locked2),
- {ok, rebar_state:set(State3, goals, Goals1)}
- end
+ State1 = rebar_state:src_deps(rebar_state:goals(State, Goals), SrcDeps),
+ State2 = update_src_deps(State1),
+ Goals1 = rebar_state:goals(State2),
+ {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),
+ rebar_app_info:source(AppInfo1, Source)
+ end, Solved),
+ ProjectApps = lists:map(fun(X) ->
+ rebar_app_info:deps(X, [rebar_app_info:name(Y) || Y <- SrcDeps] ++ [element(1, G) || G <- Goals])
+ end, rebar_state:apps_to_build(State2)),
+ FinalDeps = ProjectApps ++ rebar_state:src_deps(State2) ++ Final,
+ {ok, Sort} = rebar_topo:sort_apps(FinalDeps),
+ [io:format("Build ~p~n", [rebar_app_info:name(A)]) || A <- Sort],
+ {ok, State2}
end;
- Locks ->
- Locks1 = [new(Lock) || Lock <- Locks],
- {State2, _, _, _} = update_deps(State, Locks1),
- {ok, State2}
+ _Locks ->
+ {ok, State}
end.
%% set REBAR_DEPS_DIR and ERL_LIBS environment variables
@@ -130,90 +126,30 @@ get_deps_dir(DepsDir, App) ->
%% Internal functions
%% ===================================================================
-new({Name, Vsn, Source}) when is_tuple(Source) ->
- #dep{name=ec_cnv:to_binary(Name), vsn=ec_cnv:to_binary(Vsn), source=Source};
-new({Name, Vsn, Source}) when is_binary(Source) ->
- #dep{name=ec_cnv:to_binary(Name)
- ,vsn=ec_cnv:to_binary(Vsn)
- ,source={ec_cnv:to_binary(Name), ec_cnv:to_binary(Vsn), Source}};
-new(Name) ->
- #dep{name=ec_cnv:to_binary(Name)}.
-
%% Fetch missing binary deps
-update_deps(State, Deps) ->
- DepsDir = get_deps_dir(State),
-
- %% Find available apps to fulfill dependencies
- %% Should only have to do this once, not every iteration
- UnbuiltApps = rebar_app_discover:find_unbuilt_apps([DepsDir]),
- FoundApps = rebar_app_discover:find_apps([DepsDir]),
-
- download_missing_deps(State, DepsDir, UnbuiltApps++FoundApps, Deps).
-
-%% Find source deps to build and download
-update_src_deps(State, Deps, Goals, SrcApps, Locked) ->
- DepsDir = get_deps_dir(State),
-
- %% Find available apps to fulfill dependencies
- %% Should only have to do this once, not every iteration
- UnbuiltApps = rebar_app_discover:find_unbuilt_apps([DepsDir]),
- FoundApps = rebar_app_discover:find_apps([DepsDir]),
-
- %% Resolve deps and their dependencies
- {Deps1, NewGoals} = handle_src_deps(Deps, UnbuiltApps++FoundApps, Goals),
- case download_missing_deps(State, DepsDir, UnbuiltApps++FoundApps, Deps1) of
- {State1, [], SrcApps1, []} ->
- Locked1 = lists:map(fun(AppSrc) ->
- Source = rebar_app_info:source(AppSrc),
- Name = rebar_app_info:name(AppSrc),
- C = rebar_config:consult(rebar_app_info:dir(AppSrc)),
- S = rebar_state:new(rebar_state:new()
- ,C
- ,rebar_app_info:dir(AppSrc)),
- TargetDir = get_deps_dir(DepsDir, Name),
- Ref = rebar_fetch:current_ref(binary_to_list(TargetDir), Source),
- AppInfo = rebar_prv_app_builder:build(S, AppSrc),
-
- {Name
- ,ec_cnv:to_binary(rebar_app_info:original_vsn(AppInfo))
- ,erlang:setelement(3, Source, Ref)}
- end, SrcApps1++SrcApps),
- {State1, Deps1, NewGoals, Locked1++Locked};
- {State1, Missing, SrcApps1, Locked1} ->
- update_src_deps(State1, Missing, NewGoals, SrcApps1++SrcApps, Locked1++Locked)
+update_deps(State) ->
+ State.
+
+update_src_deps(State) ->
+ SrcDeps = rebar_state:src_deps(State),
+ case lists:foldl(fun(AppInfo, {StateAcc, SrcDepsAcc, GoalsAcc}) ->
+ ok = maybe_fetch(StateAcc, 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, []),
+ {SrcDeps1, Goals} = parse_deps(Deps),
+ NewSrcDeps = SrcDeps1++SrcDepsAcc,
+ {StateAcc, NewSrcDeps, Goals++GoalsAcc}
+ end, {State, [], rebar_state:goals(State)}, SrcDeps) of
+ {State1, [], NewGoals} ->
+ rebar_state:goals(State1, NewGoals);
+ {State1, NewSrcDeps, NewGoals}->
+ State2 = rebar_state:src_deps(rebar_state:goals(State1, NewGoals), SrcDeps++NewSrcDeps),
+ update_src_deps(State2)
end.
-%% Collect deps of new deps
-handle_src_deps(Deps, Found, Goals) ->
- lists:foldl(fun(X, {DepsAcc, GoalsAcc}) ->
- C = rebar_config:consult(rebar_app_info:dir(X)),
- S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(X)),
- {ParsedDeps, NewGoals} = parse_deps(rebar_state:get(S, deps, [])),
- {ParsedDeps++DepsAcc, NewGoals++GoalsAcc}
- end, {Deps, Goals}, Found).
-
-%% Fetch missing deps from source
-download_missing_deps(State, DepsDir, Found, Deps) ->
- Missing =
- lists:filter(fun(#dep{name=Name}) ->
- not lists:any(fun(F) ->
- Name =:= rebar_app_info:name(F)
- end, Found)
- end, Deps),
- {SrcApps, Locked} = lists:foldl(fun(Dep=#dep{name=Name, source=Source}, {SrcAppsAcc, LockedAcc}) ->
- TargetDir = get_deps_dir(DepsDir, Name),
- ?INFO("Fetching ~s ~s~n", [Name
- ,element(2, Source)]),
- rebar_fetch:download_source(TargetDir, Source),
- case rebar_app_discover:find_unbuilt_apps([TargetDir]) of
- [AppSrc] ->
- {[rebar_app_info:source(AppSrc, Source) | SrcAppsAcc], LockedAcc};
- [] ->
- {SrcAppsAcc, [Source | LockedAcc]}
- end
- end, {[], []}, Missing),
-
- {State, Missing, lists:reverse(SrcApps), Locked}.
+maybe_fetch(_State, _Dep) ->
+ ok.
parse_deps(Deps) ->
lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, GoalsAcc}) ->
@@ -221,9 +157,10 @@ parse_deps(Deps) ->
,ec_cnv:to_binary(Vsn)) | GoalsAcc]};
(Name, {SrcDepsAcc, GoalsAcc}) when is_atom(Name) ->
{SrcDepsAcc, [ec_cnv:to_binary(Name) | GoalsAcc]};
- (SrcDep, {SrcDepsAcc, GoalsAcc}) ->
- Dep = new(SrcDep),
- {[Dep | SrcDepsAcc], GoalsAcc}
+ ({Name, _, Source}, {SrcDepsAcc, GoalsAcc}) ->
+ {ok, Dep} = rebar_app_info:new(Name),
+ Dep1 = rebar_app_info:source(Dep, Source),
+ {[Dep1 | SrcDepsAcc], GoalsAcc}
end, {[], []}, Deps).
parse_goal(Name, Constraint) ->