Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

96 rindas
3.5 KiB

pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
  1. -module(rebar_digraph).
  2. -export([compile_order/1
  3. ,restore_graph/1
  4. ,subgraph/2
  5. ,format_error/1]).
  6. -include("rebar.hrl").
  7. %% Sort apps with topological sort to get proper build order
  8. compile_order(Apps) ->
  9. Graph = digraph:new(),
  10. lists:foreach(fun(App) ->
  11. Name = rebar_app_info:name(App),
  12. Deps = all_apps_deps(App),
  13. add(Graph, {Name, Deps})
  14. end, Apps),
  15. Order =
  16. case digraph_utils:topsort(Graph) of
  17. false ->
  18. case digraph_utils:is_acyclic(Graph) of
  19. true ->
  20. {error, no_sort};
  21. false ->
  22. Cycles = lists:sort(
  23. [lists:sort(Comp) || Comp <- digraph_utils:strong_components(Graph),
  24. length(Comp)>1]),
  25. {error, {cycles, Cycles}}
  26. end;
  27. V ->
  28. {ok, names_to_apps(lists:reverse(V), Apps)}
  29. end,
  30. true = digraph:delete(Graph),
  31. Order.
  32. add(Graph, {PkgName, Deps}) ->
  33. case digraph:vertex(Graph, PkgName) of
  34. false ->
  35. V = digraph:add_vertex(Graph, PkgName);
  36. {V, []} ->
  37. V
  38. end,
  39. lists:foreach(fun(DepName) ->
  40. Name1 = case DepName of
  41. {Name, _Vsn} ->
  42. ec_cnv:to_binary(Name);
  43. Name ->
  44. ec_cnv:to_binary(Name)
  45. end,
  46. V3 = case digraph:vertex(Graph, Name1) of
  47. false ->
  48. digraph:add_vertex(Graph, Name1);
  49. {V2, []} ->
  50. V2
  51. end,
  52. digraph:add_edge(Graph, V, V3)
  53. end, Deps).
  54. restore_graph({Vs, Es}) ->
  55. Graph = digraph:new(),
  56. lists:foreach(fun({V, LastUpdated}) ->
  57. digraph:add_vertex(Graph, V, LastUpdated)
  58. end, Vs),
  59. lists:foreach(fun({V1, V2}) ->
  60. digraph:add_edge(Graph, V1, V2)
  61. end, Es),
  62. Graph.
  63. format_error(no_solution) ->
  64. io_lib:format("No solution for packages found.", []).
  65. %%====================================================================
  66. %% Internal Functions
  67. %%====================================================================
  68. subgraph(Graph, Vertices) ->
  69. digraph_utils:subgraph(Graph, Vertices).
  70. -spec names_to_apps([atom()], [rebar_app_info:t()]) -> [rebar_app_info:t()].
  71. names_to_apps(Names, Apps) ->
  72. [element(2, App) || App <- [find_app_by_name(Name, Apps) || Name <- Names], App =/= error].
  73. -spec find_app_by_name(atom(), [rebar_app_info:t()]) -> {ok, rebar_app_info:t()} | error.
  74. find_app_by_name(Name, Apps) ->
  75. ec_lists:find(fun(App) ->
  76. rebar_app_info:name(App) =:= Name
  77. end, Apps).
  78. %% The union of all entries in the applications list for an app and
  79. %% the deps listed in its rebar.config is all deps that may be needed
  80. %% for building the app.
  81. all_apps_deps(App) ->
  82. Applications = lists:usort([atom_to_binary(X, utf8) || X <- rebar_app_info:applications(App)]),
  83. Deps = lists:usort(lists:map(fun({Name, _}) -> Name; (Name) -> Name end, rebar_app_info:deps(App))),
  84. lists:umerge(Deps, Applications).