mad_resolve.erl 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. -module(mad_resolve).
  2. %%-author('Maxim Sokhatsky').
  3. -compile([export_all, nowarn_export_all]).
  4. %% dependency graph solver
  5. sort(Pairs) -> iterate(Pairs, [], lhs(Pairs) ++ rhs(Pairs)).
  6. lhs(L) -> [X || {X, _, _} <- L].
  7. rhs(L) -> [Y || {_, Y, _} <- L].
  8. rm_pairs(L1, L2) -> [All || All={X, _Y, _} <- L2, not lists:member(X, L1)].
  9. subtract(L1, L2) -> [X || X <- L1, not lists:member(X, L2)].
  10. iterate([], L, All) -> {ok,rm_dups(L ++ subtract(All, L))};
  11. iterate(P, L, All) -> case subtract(lhs(P), rhs(P)) of [] -> P; Lhs -> iterate(rm_pairs(Lhs, P), L ++ Lhs, All) end.
  12. rm_dups([]) -> [];
  13. rm_dups([H|T]) -> case lists:member(H, T) of true -> rm_dups(T); false -> [H|rm_dups(T)] end.
  14. appdir(A) -> filename:join(lists:reverse(tl(tl(lists:reverse(filename:split(A)))))).
  15. triples() ->
  16. lists:flatten([ case
  17. file:consult(F) of
  18. {ok,[{application,Name,Opt}]} ->
  19. Apps1 = proplists:get_value(included_applications,Opt,[]),
  20. Apps2 = proplists:get_value(applications,Opt,[]),
  21. Apps = lists:usort(Apps1++Apps2),
  22. Vsn = proplists:get_value(vsn,Opt,[]),
  23. [ case lists:member(A,mad_repl:system()) of
  24. false -> {A,Name,{Vsn,appdir(filename:absname(F))}};
  25. true -> [{A,Name,{Vsn,appdir(filename:absname(F))}}]++ system_deps(A) end || A <- Apps ];
  26. {error,_} ->
  27. mad:info("AppName: ~p~n",[F]), skip
  28. end || F <- mad_repl:wildcards(["{apps,deps}/*/ebin/*.app","ebin/*.app"]), not filelib:is_dir(F) ]).
  29. orderapps() ->
  30. Apps = triples(),
  31. case sort(lists:flatten(Apps)) of
  32. {ok,Sorted} -> {ok,Sorted};
  33. Return -> {error,{cycling_apps,Return}} end.
  34. system_deps(A) ->
  35. F = code:where_is_file(lists:concat([A,".app"])),
  36. case file:consult(F) of
  37. {ok,[{application,Name,Opt}]} ->
  38. Vsn = proplists:get_value(vsn,Opt,[]),
  39. [ {_A,Name,{Vsn,appdir(F)}} || _A <- proplists:get_value(applications,Opt,[]) ];
  40. {error,_} -> [] end.
  41. main(_) ->
  42. case orderapps() of
  43. {ok,Ordered} -> mad:info("Ordered: ~p~n",[Ordered]),
  44. file:write_file(".applist",io_lib:format("~w",[Ordered])), {ok,Ordered};
  45. {error,Reason} -> {error,Reason} end.