diff options
| author | Tristan Sloughter <t@crashfast.com> | 2015-05-25 23:23:29 -0500 | 
|---|---|---|
| committer | Tristan Sloughter <t@crashfast.com> | 2015-05-27 20:02:04 -0500 | 
| commit | 20f4562c6dabfcf9df1e52ec2c83307b33c24090 (patch) | |
| tree | daa894e5efb10b215321bfb983f64ca579b88f00 /src | |
| parent | 8687ddc14a20606fafdd666ee058932b361e5113 (diff) | |
fix for plugin installation and code paths
Diffstat (limited to 'src')
| -rw-r--r-- | src/rebar_hooks.erl | 6 | ||||
| -rw-r--r-- | src/rebar_plugins.erl | 42 | ||||
| -rw-r--r-- | src/rebar_prv_compile.erl | 3 | ||||
| -rw-r--r-- | src/rebar_prv_install_deps.erl | 17 | ||||
| -rw-r--r-- | src/rebar_state.erl | 11 | ||||
| -rw-r--r-- | src/rebar_utils.erl | 17 | 
6 files changed, 77 insertions, 19 deletions
diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index e144a8e..037a85a 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -10,11 +10,15 @@ run_all_hooks(Dir, Type, Command, Providers, State) ->      run_hooks(Dir, Type, Command, State).  run_provider_hooks(Dir, Type, Command, Providers, State) -> +    PluginDepsPaths = rebar_state:code_paths(State, all_plugin_deps), +    code:add_pathsa(PluginDepsPaths),      State1 = rebar_state:providers(rebar_state:dir(State, Dir), Providers),      AllHooks = rebar_state:get(State1, provider_hooks, []),      TypeHooks = proplists:get_value(Type, AllHooks, []),      HookProviders = proplists:get_all_values(Command, TypeHooks), -    rebar_core:do(HookProviders, State1). +    State2 = rebar_core:do(HookProviders, State1), +    rebar_utils:remove_from_code_path(PluginDepsPaths), +    State2.  run_hooks(Dir, Type, Command, State) ->      Hooks = case Type of diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index 6d0a4dc..b1d54c4 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -32,31 +32,49 @@ handle_plugins(Plugins, State) ->  handle_plugins(Profile, Plugins, State) ->      %% Set deps dir to plugins dir so apps are installed there +    Locks = rebar_state:lock(State), +    DepsDir = rebar_state:get(State, deps_dir, ?DEFAULT_DEPS_DIR),      State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR), -    PluginProviders = lists:flatmap(fun(Plugin) -> -                                            handle_plugin(Profile, Plugin, State1) -                                    end, Plugins), +    {PluginProviders, State2} = +        lists:foldl(fun(Plugin, {PluginAcc, StateAcc}) -> +                            {NewPlugins, NewState} = handle_plugin(Profile, Plugin, StateAcc), +                            {PluginAcc++NewPlugins, NewState} +                      end, {[], State1}, Plugins),      %% reset deps dir -    State2 = rebar_state:set(State1, deps_dir, ?DEFAULT_DEPS_DIR), +    State3 = rebar_state:set(State2, deps_dir, DepsDir), +    State4 = rebar_state:lock(State3, Locks), -    rebar_state:create_logic_providers(PluginProviders, State2). +    rebar_state:create_logic_providers(PluginProviders, State4).  handle_plugin(Profile, Plugin, State) ->      try -        {ok, _, State2} = rebar_prv_install_deps:handle_deps(Profile, State, [Plugin]), +        {ok, Apps, State2} = rebar_prv_install_deps:handle_deps(Profile, State, [Plugin]), +        {no_cycle, Sorted} = rebar_prv_install_deps:find_cycles(Apps), +        ToBuild = rebar_prv_install_deps:cull_compile(Sorted, []), -        Apps = rebar_state:all_deps(State2), -        ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Apps), +        %% Add already built plugin deps to the code path +        CodePaths = [rebar_app_info:ebin_dir(A) || A <- Apps -- ToBuild], +        code:add_pathsa(CodePaths), + +        %% Build plugin and its deps          [build_plugin(AppInfo) || AppInfo <- ToBuild], -        [true = code:add_patha(filename:join(rebar_app_info:dir(AppInfo), "ebin")) || AppInfo <- Apps], -        plugin_providers(Plugin) + +        %% Add newly built deps and plugin to code path +        State3 = rebar_state:update_all_plugin_deps(State2, Apps), +        NewCodePaths = [rebar_app_info:ebin_dir(A) || A <- ToBuild], +        code:add_pathsa(CodePaths), + +        %% Store plugin code paths so we can remove them when compiling project apps +        State4 = rebar_state:update_code_paths(State3, all_plugin_deps, CodePaths++NewCodePaths), + +        {plugin_providers(Plugin), State4}      catch          C:T ->              ?DEBUG("~p ~p ~p", [C, T, erlang:get_stacktrace()]),              ?WARN("Plugin ~p not available. It will not be used.", [Plugin]), -            [] +            {[], State}      end.  build_plugin(AppInfo) -> @@ -65,6 +83,8 @@ build_plugin(AppInfo) ->      S = rebar_state:new(rebar_state:new(), C, AppDir),      rebar_prv_compile:compile(S, [], AppInfo). +plugin_providers({Plugin, _, _, _}) when is_atom(Plugin) -> +    validate_plugin(Plugin);  plugin_providers({Plugin, _, _}) when is_atom(Plugin) ->      validate_plugin(Plugin);  plugin_providers({Plugin, _}) when is_atom(Plugin) -> diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 4a0fea8..c60406d 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -32,8 +32,11 @@ init(State) ->  -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.  do(State) ->      DepsPaths = rebar_state:code_paths(State, all_deps), +    PluginDepsPaths = rebar_state:code_paths(State, all_plugin_deps), +    rebar_utils:remove_from_code_path(PluginDepsPaths),      code:add_pathsa(DepsPaths), +      ProjectApps = rebar_state:project_apps(State),      Providers = rebar_state:providers(State),      Deps = rebar_state:deps_to_build(State), diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 80fdbc3..23f2830 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -37,7 +37,10 @@  -export([handle_deps/3,           handle_deps/4, -         handle_deps/5]). +         handle_deps/5, + +         find_cycles/1, +         cull_compile/2]).  -export_type([dep/0]). @@ -76,6 +79,10 @@ do(State) ->          {Apps, State1} =              lists:foldl(fun deps_per_profile/2, {[], State}, lists:reverse(Profiles)), +        State2 = rebar_state:update_all_deps(State1, Apps), +        CodePaths = [rebar_app_info:ebin_dir(A) || A <- Apps], +        State3 = rebar_state:update_code_paths(State2, all_deps, CodePaths), +          Source = ProjectApps ++ Apps,          case find_cycles(Source) of              {cycles, Cycles} -> @@ -84,7 +91,7 @@ do(State) ->                  {error, Error};              {no_cycle, Sorted} ->                  ToCompile = cull_compile(Sorted, ProjectApps), -                {ok, rebar_state:deps_to_build(State1, ToCompile)} +                {ok, rebar_state:deps_to_build(State3, ToCompile)}          end      catch          %% maybe_fetch will maybe_throw an exception to break out of some loops @@ -158,11 +165,7 @@ handle_deps(Profile, State0, Deps, Upgrade, Locks) ->                               ,lists:ukeysort(2, SrcApps)                               ,lists:ukeysort(2, Solved)), -    State5 = rebar_state:update_all_deps(State4, AllDeps), -    CodePaths = [rebar_app_info:ebin_dir(A) || A <- AllDeps], -    State6 = rebar_state:update_code_paths(State5, all_deps, CodePaths), - -    {ok, AllDeps, State6}. +    {ok, AllDeps, State4}.  %% ===================================================================  %% Internal functions diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 18d6be7..96daf39 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -24,6 +24,7 @@           project_apps/1, project_apps/2,           deps_to_build/1, deps_to_build/2, +         all_plugin_deps/1, all_plugin_deps/2, update_all_plugin_deps/2,           all_deps/1, all_deps/2, update_all_deps/2,           namespace/1, namespace/2, @@ -55,6 +56,7 @@                    project_apps        = []          :: [rebar_app_info:t()],                    deps_to_build       = []          :: [rebar_app_info:t()], +                  all_plugin_deps     = []          :: [rebar_app_info:t()],                    all_deps            = []          :: [rebar_app_info:t()],                    packages            = undefined   :: {rebar_dict(), rebar_digraph()} | undefined, @@ -347,6 +349,15 @@ all_deps(#state_t{all_deps=Apps}) ->  all_deps(State=#state_t{}, NewApps) ->      State#state_t{all_deps=NewApps}. +all_plugin_deps(#state_t{all_plugin_deps=Apps}) -> +    Apps. + +all_plugin_deps(State=#state_t{}, NewApps) -> +    State#state_t{all_plugin_deps=NewApps}. + +update_all_plugin_deps(State=#state_t{all_plugin_deps=Apps}, NewApps) -> +    State#state_t{all_plugin_deps=Apps++NewApps}. +  update_all_deps(State=#state_t{all_deps=Apps}, NewApps) ->      State#state_t{all_deps=Apps++NewApps}. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index ffa29e6..cc59ed0 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -48,6 +48,7 @@           erl_opts/1,           indent/1,           update_code/1, +         remove_from_code_path/1,           cleanup_code_path/1,           args_to_tasks/1,           expand_env_variable/3, @@ -581,6 +582,22 @@ update_code(Paths) ->                            end                    end, Paths). +remove_from_code_path(Paths) -> +    lists:foreach(fun(Path) -> +                          Name = filename:basename(Path, "/ebin"), +                          App = list_to_atom(Name), +                          application:load(App), +                          case application:get_key(App, modules) of +                              undefined -> +                                  application:unload(App), +                                  ok; +                              {ok, Modules} -> +                                  application:unload(App), +                                  [begin code:purge(M), code:delete(M) end || M <- Modules] +                          end, +                          code:del_path(Path) +                  end, Paths). +  cleanup_code_path(OrigPath) ->      CurrentPath = code:get_path(),      AddedPaths = CurrentPath -- OrigPath,  | 
