From 6cfe28c954dc12f847a15a78b5fcf65154f0407a Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 6 Dec 2014 16:29:44 +0000 Subject: Partial fix to circular deps (#40) - Adding tests - fixing use of set fetching to find repeated deps and prevent infinite loops On a circular loop rebar3 now fails with `{error, no_sort}`, which is uncaught and should be handled to consider the issue fully fixed. --- src/rebar_prv_install_deps.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index a3ffc66..461baa5 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -151,7 +151,7 @@ update_pkg_deps(Pkgs, Packages, Update, Seen, State) -> ,Packages ,Pkg), {SeenAcc1, StateAcc1} = maybe_lock(AppInfo, SeenAcc, StateAcc), - case maybe_fetch(StateAcc1, AppInfo, Update, SeenAcc) of + case maybe_fetch(StateAcc1, AppInfo, Update, SeenAcc1) of true -> {[AppInfo | Acc], SeenAcc1, StateAcc1}; false -> @@ -167,7 +167,7 @@ maybe_lock(AppInfo, Seen, State) -> {sets:add_element(Name, Seen), rebar_state:lock(State, AppInfo)}; true -> - {sets:add_element(Name, Seen), State} + {Seen, State} end. package_to_app(DepsDir, Packages, {Name, Vsn}) -> @@ -204,7 +204,7 @@ update_src_deps(Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen) -> ,Level ,StateAcc1); _ -> - maybe_fetch(StateAcc, AppInfo, false, SeenAcc), + maybe_fetch(StateAcc, AppInfo, false, SeenAcc1), handle_dep(AppInfo ,SrcDepsAcc ,PkgDepsAcc -- cgit v1.1 From 63003c3986ca20e2f733e79453315fa0b7076bd9 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 6 Dec 2014 23:18:35 +0000 Subject: Return cycles in deps solver --- src/rebar_digraph.erl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/rebar_digraph.erl b/src/rebar_digraph.erl index bb031cb..dbcf649 100644 --- a/src/rebar_digraph.erl +++ b/src/rebar_digraph.erl @@ -18,7 +18,15 @@ compile_order(Apps) -> end, Apps), case digraph_utils:topsort(Graph) of false -> - {error, no_sort}; + case digraph_utils:is_acyclic(Graph) of + true -> + {error, no_sort}; + false -> + Cycles = lists:sort( + [lists:sort(Comp) || Comp <- digraph_utils:strong_components(Graph), + length(Comp)>1]), + {error, {cycles, Cycles}} + end; V -> {ok, names_to_apps(lists:reverse(V), Apps)} end. -- cgit v1.1 From be39ab9e7bd1553132def2a1e89f1ce38f6f2fcc Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 6 Dec 2014 23:53:11 +0000 Subject: Handle cycle errors in provider --- src/rebar_prv_install_deps.erl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 461baa5..1be094c 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -81,6 +81,8 @@ do(State) -> {ok, rebar_state:deps_to_build(State1, lists:dropwhile(fun rebar_app_info:valid/1 , Sort -- ProjectApps))}; + {error, {cycles, Cycles}} -> + {error, {?MODULE, {cycles, Cycles}}}; {error, Error} -> {error, Error} end @@ -91,6 +93,12 @@ do(State) -> end. -spec format_error(any()) -> iolist(). +format_error({cycles, Cycles}) -> + Prints = [["applications: ", + [io_lib:format("~s ", [Dep]) || Dep <- Cycle], + "depend on each other~n"] + || Cycle <- Cycles], + ["Dependency cycle(s) detected:~n", Prints]; format_error(Reason) -> io_lib:format("~p", [Reason]). -- cgit v1.1