|
@@ -5,33 +5,43 @@
|
|
% dependency graph solver
|
|
% dependency graph solver
|
|
|
|
|
|
sort(Pairs) -> iterate(Pairs, [], lhs(Pairs) ++ rhs(Pairs)).
|
|
sort(Pairs) -> iterate(Pairs, [], lhs(Pairs) ++ rhs(Pairs)).
|
|
-lhs(L) -> [X || {X, _} <- L].
|
|
|
|
-rhs(L) -> [Y || {_, Y} <- L].
|
|
|
|
-rm_pairs(L1, L2) -> [All || All={X, _Y} <- L2, not lists:member(X, L1)].
|
|
|
|
|
|
+lhs(L) -> [X || {X, _, _} <- L].
|
|
|
|
+rhs(L) -> [Y || {_, Y, _} <- L].
|
|
|
|
+rm_pairs(L1, L2) -> [All || All={X, _Y, _} <- L2, not lists:member(X, L1)].
|
|
subtract(L1, L2) -> [X || X <- L1, not lists:member(X, L2)].
|
|
subtract(L1, L2) -> [X || X <- L1, not lists:member(X, L2)].
|
|
iterate([], L, All) -> {ok,rm_dups(L ++ subtract(All, L))};
|
|
iterate([], L, All) -> {ok,rm_dups(L ++ subtract(All, L))};
|
|
iterate(P, L, All) -> case subtract(lhs(P), rhs(P)) of [] -> P; Lhs -> iterate(rm_pairs(Lhs, P), L ++ Lhs, All) end.
|
|
iterate(P, L, All) -> case subtract(lhs(P), rhs(P)) of [] -> P; Lhs -> iterate(rm_pairs(Lhs, P), L ++ Lhs, All) end.
|
|
rm_dups([]) -> [];
|
|
rm_dups([]) -> [];
|
|
rm_dups([H|T]) -> case lists:member(H, T) of true -> rm_dups(T); false -> [H|rm_dups(T)] end.
|
|
rm_dups([H|T]) -> case lists:member(H, T) of true -> rm_dups(T); false -> [H|rm_dups(T)] end.
|
|
|
|
|
|
-orderapps() ->
|
|
|
|
- Pairs = lists:flatten([ case
|
|
|
|
|
|
+appdir(A) -> filename:join(lists:reverse(tl(tl(lists:reverse(filename:split(A)))))).
|
|
|
|
+
|
|
|
|
+triples() ->
|
|
|
|
+ lists:flatten([ case
|
|
file:consult(F) of
|
|
file:consult(F) of
|
|
{ok,[{application,Name,Opt}]} ->
|
|
{ok,[{application,Name,Opt}]} ->
|
|
Apps = proplists:get_value(applications,Opt,[]),
|
|
Apps = proplists:get_value(applications,Opt,[]),
|
|
|
|
+ Vsn = proplists:get_value(vsn,Opt,[]),
|
|
[ case lists:member(A,mad_repl:system()) of
|
|
[ case lists:member(A,mad_repl:system()) of
|
|
- false -> {A,Name};
|
|
|
|
- true -> [{A,Name}]++ system_deps(A) end || A <- Apps ];
|
|
|
|
|
|
+ false -> {A,Name,{Vsn,appdir(filename:absname(F))}};
|
|
|
|
+ true -> [{A,Name,{Vsn,appdir(filename:absname(F))}}]++ system_deps(A) end || A <- Apps ];
|
|
{error,_} ->
|
|
{error,_} ->
|
|
mad:info("AppName: ~p~n",[F]), skip
|
|
mad:info("AppName: ~p~n",[F]), skip
|
|
- end || F <- mad_repl:wildcards(["{apps,deps}/*/ebin/*.app","ebin/*.app"]), not filelib:is_dir(F) ]),
|
|
|
|
- case sort(lists:flatten(Pairs)) of
|
|
|
|
|
|
+ end || F <- mad_repl:wildcards(["{apps,deps}/*/ebin/*.app","ebin/*.app"]), not filelib:is_dir(F) ]).
|
|
|
|
+
|
|
|
|
+orderapps() ->
|
|
|
|
+ Apps = triples(),
|
|
|
|
+% mad:info("Triples: ~p~n",[Apps]),
|
|
|
|
+ case sort(lists:flatten(Apps)) of
|
|
{ok,Sorted} -> {ok,Sorted};
|
|
{ok,Sorted} -> {ok,Sorted};
|
|
Return -> {error,{cycling_apps,Return}} end.
|
|
Return -> {error,{cycling_apps,Return}} end.
|
|
|
|
|
|
system_deps(A) ->
|
|
system_deps(A) ->
|
|
- case file:consult(code:where_is_file(lists:concat([A,".app"]))) of
|
|
|
|
- {ok,[{application,Name,Opt}]} -> [ {_A,Name} || _A <- proplists:get_value(applications,Opt,[]) ];
|
|
|
|
|
|
+ F = code:where_is_file(lists:concat([A,".app"])),
|
|
|
|
+ case file:consult(F) of
|
|
|
|
+ {ok,[{application,Name,Opt}]} ->
|
|
|
|
+ Vsn = proplists:get_value(vsn,Opt,[]),
|
|
|
|
+ [ {_A,Name,{Vsn,appdir(F)}} || _A <- proplists:get_value(applications,Opt,[]) ];
|
|
{error,_} -> [] end.
|
|
{error,_} -> [] end.
|
|
|
|
|
|
main(_) ->
|
|
main(_) ->
|