Skip to content

Instantly share code, notes, and snippets.

@lefant
Created July 30, 2013 14:41
Show Gist options
  • Save lefant/6113511 to your computer and use it in GitHub Desktop.
Save lefant/6113511 to your computer and use it in GitHub Desktop.
sort erlang/otp applications into an order suitable for starting while keeping dependencies satisfied
-module(eapplication).
-export([deps_order/1]).
deps_order(App) ->
G = digraph:new(),
add_app_and_deps(G, [App], []),
L = lists:reverse(digraph_utils:topsort(G)),
digraph:delete(G),
L.
add_app_and_deps(_, [], _) -> ok;
add_app_and_deps(G, [App | Todo], Done) ->
Deps = get_deps(App),
lists:foreach(fun(Dep) ->
ensure_edge(G, App, Dep)
end, Deps),
add_app_and_deps(G, Todo ++ (Deps -- Done), Done).
get_deps(App) ->
application:load(App),
{ok, Deps} = application_controller:get_key(App, applications),
Deps.
ensure_edge(G, A, B) ->
ensure_vertex(G, A),
ensure_vertex(G, B),
case digraph:get_short_path(G, A, B) of
L when length(L) == 1 -> ok;
_ -> digraph:add_edge(G, A, B)
end.
ensure_vertex(G, A) ->
case digraph:vertex(G, A) of
false -> digraph:add_vertex(G, A);
_ -> ok
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment