diff options
-rw-r--r-- | src/rebar_digraph.erl | 20 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 4 | ||||
-rw-r--r-- | src/rebar_prv_test_deps.erl | 2 |
3 files changed, 15 insertions, 11 deletions
diff --git a/src/rebar_digraph.erl b/src/rebar_digraph.erl index 0ca5984..27bbdd2 100644 --- a/src/rebar_digraph.erl +++ b/src/rebar_digraph.erl @@ -1,14 +1,15 @@ -module(rebar_digraph). --export([sort_apps/1 +-export([compile_order/1 ,restore_graph/1 - ,solve/2 + ,cull_deps/2 ,subgraph/2 ,format_error/1]). -include("rebar.hrl"). -sort_apps(Apps) -> +%% Sort apps with topological sort to get proper build order +compile_order(Apps) -> Graph = digraph:new(), lists:foreach(fun(App) -> Name = rebar_app_info:name(App), @@ -50,15 +51,18 @@ restore_graph({Vs, Es}) -> end, Es), Graph. -solve(Graph, Vertices) -> - solve(Graph, Vertices, lists:foldl(fun({Key, _}=N, Solution) -> +%% Pick packages to fullfill dependencies +%% The first dep while traversing the graph is chosen and any conflicting +%% dep encountered later on is ignored. +cull_deps(Graph, Vertices) -> + cull_deps(Graph, Vertices, lists:foldl(fun({Key, _}=N, Solution) -> dict:store(Key, N, Solution) end, dict:new(), Vertices)). -solve(_Graph, [], Solution) -> +cull_deps(_Graph, [], Solution) -> {_, Vertices} = lists:unzip(dict:to_list(Solution)), {ok, Vertices}; -solve(Graph, Vertices, Solution) -> +cull_deps(Graph, Vertices, Solution) -> {NV, NS} = lists:foldl(fun(V, {NewVertices, SolutionAcc}) -> OutNeighbors = digraph:out_neighbours(Graph, V), @@ -71,7 +75,7 @@ solve(Graph, Vertices, Solution) -> end end, {NewVertices, SolutionAcc}, OutNeighbors) end, {[], Solution}, Vertices), - solve(Graph, NV, NS). + cull_deps(Graph, NV, NS). subgraph(Graph, Vertices) -> digraph_utils:subgraph(Graph, Vertices). diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index d9cf7ac..9822b32 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -77,7 +77,7 @@ do(State) -> end, Source = ProjectApps ++ rebar_state:src_apps(State1), - case rebar_digraph:sort_apps(Source) of + case rebar_digraph:compile_order(Source) of {ok, Sort} -> {ok, rebar_state:set(State1, deps_to_build, lists:dropwhile(fun rebar_app_info:valid/1, Sort -- ProjectApps))}; @@ -130,7 +130,7 @@ handle_deps(State, Deps, Update) -> []; PkgDeps1 -> %% Find pkg deps needed - S = case rebar_digraph:solve(Graph, PkgDeps1) of + S = case rebar_digraph:cull_deps(Graph, PkgDeps1) of {ok, []} -> throw({rebar_digraph, no_solution}); {ok, Solution} -> diff --git a/src/rebar_prv_test_deps.erl b/src/rebar_prv_test_deps.erl index 108af98..b7341d0 100644 --- a/src/rebar_prv_test_deps.erl +++ b/src/rebar_prv_test_deps.erl @@ -43,7 +43,7 @@ do(State) -> AllDeps = rebar_state:get(State2, all_deps, []), State3 = rebar_state:set(State2, deps_dir, DepsDir), - case rebar_digraph:sort_apps(ProjectApps1++AllDeps) of + case rebar_digraph:compile_order(ProjectApps1++AllDeps) of {ok, Sort} -> ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Sort -- ProjectApps1), State4 = rebar_state:set(State3, deps_to_build, ToBuild), |