Skip to content

Instantly share code, notes, and snippets.

@archaelus
Created February 26, 2010 02:39
Show Gist options
  • Select an option

  • Save archaelus/315333 to your computer and use it in GitHub Desktop.

Select an option

Save archaelus/315333 to your computer and use it in GitHub Desktop.
build_rel_file({ReleaseName, ReleaseVSN}, RelFileName, Apps) ->
Deps = walk_deps(Apps),
{ok, FD} = file:open(RelFileName, [write]),
RelInfo = {release,
{ReleaseName, ReleaseVSN},
{erts, erts_vsn()},
[{Pkg, lib_vsn(Pkg)} || Pkg <- Deps]
},
io:format(FD, "~p.", [RelInfo]),
file:close(FD).
erts_vsn() ->
erlang:system_info(version).
lib_vsn(App) ->
load(App),
{ok, Vsn} = application:get_key(App, vsn),
Vsn.
load(App) ->
case application:load(App) of
ok -> ok;
{error, {already_loaded, _}} -> ok;
E -> io:format(standard_error, "Warning - can't load ~p (~p)~n", [App, E]),
erlang:exit(E)
end.
app_deps(App) when is_atom(App) ->
load(App),
Deps = case application:get_key(App, applications) of
{ok, Apps} -> Apps;
E -> io:format(standard_error, "Warning - no deps for ~p (~p)~n", [App, E]),
erlang:exit(E)
end,
Included = case application:get_key(App, included_applications) of
{ok, IApps} -> IApps;
_ -> []
end,
Deps ++ Included.
walk_deps(Apps) ->
G = digraph:new(),
walk_deps(Apps, G),
Deps = digraph_utils:topsort(G),
case digraph_utils:is_acyclic(G) of
true -> ok;
false -> io:format(standard_error, "Warning! There's a cyclic app dependency somewhere.~n", [])
end,
digraph:delete(G),
Deps.
walk_deps([], _G) -> ok;
walk_deps([App | Apps], G) ->
case digraph:vertex(G, App) of
false ->
digraph:add_vertex(G, App),
lists:foreach(fun (Dep) ->
walk_deps([Dep], G),
digraph:add_edge(G, App, Dep)
end,
app_deps(App)),
ok;
{App, _} -> ok
end,
walk_deps(Apps, G).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment