Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

79 linhas
3.0 KiB

10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. -module(rebar_plugins).
  4. -export([install/1]).
  5. -include("rebar.hrl").
  6. %% ===================================================================
  7. %% Public API
  8. %% ===================================================================
  9. install(State) ->
  10. %% Set deps_dir to a different dir for plugin so they don't collide
  11. OldDepsDir = rebar_state:get(State, deps_dir, ?DEFAULT_DEPS_DIR),
  12. State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR),
  13. DepsDir = rebar_dir:deps_dir(State1),
  14. expand_plugins(DepsDir),
  15. Plugins = rebar_state:get(State1, plugins, []),
  16. PluginProviders = lists:flatten(rebar_utils:filtermap(fun(Plugin) ->
  17. handle_plugin(Plugin, State1)
  18. end, Plugins)),
  19. State2 = rebar_state:set(State1, deps_dir, OldDepsDir),
  20. {ok, PluginProviders, State2}.
  21. -spec handle_plugin(rebar_prv_install_deps:dep(), rebar_state:t()) -> {true, any()} | false.
  22. handle_plugin(Plugin, State) ->
  23. try
  24. {ok, _, State1} = rebar_prv_install_deps:handle_deps(default, State, [Plugin]),
  25. Apps = rebar_state:all_deps(State1),
  26. ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Apps),
  27. lists:foreach(fun(AppInfo) ->
  28. AppDir = rebar_app_info:dir(AppInfo),
  29. C = rebar_config:consult(AppDir),
  30. S = rebar_state:new(rebar_state:new(), C, AppDir),
  31. rebar_prv_compile:build(S, AppInfo),
  32. true = code:add_patha(filename:join(AppDir, "ebin"))
  33. end, ToBuild),
  34. plugin_providers(Plugin)
  35. catch
  36. C:T ->
  37. ?DEBUG("~p ~p", [C, T]),
  38. ?WARN("Plugin ~p not available. It will not be used.~n", [Plugin]),
  39. false
  40. end.
  41. plugin_providers({Plugin, _, _}) when is_atom(Plugin) ->
  42. validate_plugin(Plugin);
  43. plugin_providers({Plugin, _}) when is_atom(Plugin) ->
  44. validate_plugin(Plugin);
  45. plugin_providers(Plugin) when is_atom(Plugin) ->
  46. validate_plugin(Plugin).
  47. validate_plugin(Plugin) ->
  48. ok = application:load(Plugin),
  49. case application:get_env(Plugin, providers) of
  50. {ok, Providers} ->
  51. {true, Providers};
  52. undefined ->
  53. Exports = sets:from_list(Plugin:module_info(exports)),
  54. Required = sets:from_list([{init,1},
  55. {do,1},
  56. {format_error,1}]),
  57. case sets:is_subset(Required, Exports) of
  58. false ->
  59. ?WARN("Plugin ~p is not a provider. It will not be used.~n", [Plugin]),
  60. false;
  61. true ->
  62. {true, Plugin}
  63. end
  64. end.
  65. expand_plugins(Dir) ->
  66. Apps = filelib:wildcard(filename:join([Dir, "*", "ebin"])),
  67. ok = code:add_pathsa(Apps).