diff options
| author | Fred Hebert <mononcqc@ferd.ca> | 2015-04-05 10:23:43 -0400 | 
|---|---|---|
| committer | Fred Hebert <mononcqc@ferd.ca> | 2015-04-05 10:23:43 -0400 | 
| commit | 3250faa75683bdbfc521c4e8c6772f45d6d2e863 (patch) | |
| tree | 869b863aff8062d78042d27ef62f9236c3a4559f /src | |
| parent | a99344a47066dd26b02cf34e84c15aa2f6f4dbe5 (diff) | |
| parent | 79e2d6006c989a241d4599d048ff39f094f9e886 (diff) | |
Merge pull request #320 from tsloughter/dep_plugins
install dep plugins & run provider hooks the same as shell hooks (Rereopen 316)
Diffstat (limited to 'src')
| -rw-r--r-- | src/rebar.app.src | 4 | ||||
| -rw-r--r-- | src/rebar3.erl | 24 | ||||
| -rw-r--r-- | src/rebar_core.erl | 2 | ||||
| -rw-r--r-- | src/rebar_fetch.erl | 43 | ||||
| -rw-r--r-- | src/rebar_hooks.erl | 27 | ||||
| -rw-r--r-- | src/rebar_plugins.erl | 59 | ||||
| -rw-r--r-- | src/rebar_prv_clean.erl | 15 | ||||
| -rw-r--r-- | src/rebar_prv_common_test.erl | 16 | ||||
| -rw-r--r-- | src/rebar_prv_compile.erl | 22 | ||||
| -rw-r--r-- | src/rebar_prv_deps.erl | 6 | ||||
| -rw-r--r-- | src/rebar_prv_eunit.erl | 15 | ||||
| -rw-r--r-- | src/rebar_prv_install_deps.erl | 15 | ||||
| -rw-r--r-- | src/rebar_prv_lock.erl | 2 | ||||
| -rw-r--r-- | src/rebar_state.erl | 70 | 
14 files changed, 177 insertions, 143 deletions
diff --git a/src/rebar.app.src b/src/rebar.app.src index ee4bfd7..eada93b 100644 --- a/src/rebar.app.src +++ b/src/rebar.app.src @@ -23,6 +23,10 @@          %% Default log level          {log_level, warn}, +        {resources, [{git, rebar_git_resource}, +                     {pkg, rebar_pkg_resource}, +                     {hg, rebar_hg_resource}]}, +          {providers, [rebar_prv_app_discovery,                       rebar_prv_as,                       rebar_prv_clean, diff --git a/src/rebar3.erl b/src/rebar3.erl index 87258aa..461206d 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -77,7 +77,7 @@ run(BaseState, Commands) ->      _ = application:load(rebar),      BaseState1 = rebar_state:set(BaseState, task, Commands),      BaseState2 = rebar_state:set(BaseState1, caller, api), -    run_aux(BaseState2, [], Commands). +    run_aux(BaseState2, Commands).  %% ====================================================================  %% Internal functions @@ -86,7 +86,7 @@ run(BaseState, Commands) ->  run(RawArgs) ->      _ = application:load(rebar), -    {GlobalPluginProviders, BaseState} = init_config(), +    BaseState = init_config(),      BaseState1 = rebar_state:set(BaseState, caller, command_line),      case erlang:system_info(version) of @@ -98,9 +98,9 @@ run(RawArgs) ->      end,      {BaseState2, _Args1} = set_options(BaseState1, {[], []}), -    run_aux(BaseState2, GlobalPluginProviders, RawArgs). +    run_aux(BaseState2, RawArgs). -run_aux(State, GlobalPluginProviders, RawArgs) -> +run_aux(State, RawArgs) ->      %% Make sure crypto is running      case crypto:start() of          ok -> ok; @@ -124,16 +124,17 @@ run_aux(State, GlobalPluginProviders, RawArgs) ->                              filename:join(filename:absname(rebar_state:dir(State2)), BaseDir)),      {ok, Providers} = application:get_env(rebar, providers), -    {ok, PluginProviders, State4} = rebar_plugins:install(State3), +    {ok, Resources} = application:get_env(rebar, resources), +    State4 = rebar_state:resources(State3, Resources), +    State5 = rebar_plugins:install(State4),      %% Providers can modify profiles stored in opts, so set default after initializing providers -    AllProviders = Providers++PluginProviders++GlobalPluginProviders, -    State5 = rebar_state:create_logic_providers(AllProviders, State4), -    State6 = rebar_state:default(State5, rebar_state:opts(State5)), +    State6 = rebar_state:create_logic_providers(Providers, State5), +    State7 = rebar_state:default(State6, rebar_state:opts(State6)),      {Task, Args} = parse_args(RawArgs), -    rebar_core:init_command(rebar_state:command_args(State6, Args), Task). +    rebar_core:init_command(rebar_state:command_args(State7, Args), Task).  init_config() ->      %% Initialize logging system @@ -156,10 +157,9 @@ init_config() ->                      ?DEBUG("Load global config file ~p",                             [GlobalConfigFile]),                      GlobalConfig = rebar_state:new(global, rebar_config:consult_file(GlobalConfigFile)), -                    {ok, PluginProviders, GlobalConfig1} = rebar_plugins:install(GlobalConfig), +                    GlobalConfig1 = rebar_plugins:install(GlobalConfig),                      rebar_state:new(GlobalConfig1, Config1);                  false -> -                    PluginProviders = [],                      rebar_state:new(Config1)              end, @@ -175,7 +175,7 @@ init_config() ->      %% TODO: Do we need this still? I think it may still be used.      %% Initialize vsn cache -    {PluginProviders, rebar_state:set(State1, vsn_cache, dict:new())}. +    rebar_state:set(State1, vsn_cache, dict:new()).  parse_args([]) ->      parse_args(["help"]); diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 6abab68..7fe7332 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -26,7 +26,7 @@  %% -------------------------------------------------------------------  -module(rebar_core). --export([init_command/2, process_namespace/2, process_command/2]). +-export([init_command/2, process_namespace/2, process_command/2, do/2]).  -include("rebar.hrl"). diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl index b2ad211..20bf46b 100644 --- a/src/rebar_fetch.erl +++ b/src/rebar_fetch.erl @@ -7,30 +7,28 @@  %% -------------------------------------------------------------------  -module(rebar_fetch). --export([lock_source/2, +-export([lock_source/3,           download_source/3, -         needs_update/2]). +         needs_update/3]).  -export([format_error/1]).  -include("rebar.hrl").  -include_lib("providers/include/providers.hrl"). -%% map short versions of resources to module names --define(RESOURCES, [{git, rebar_git_resource}, {pkg, rebar_pkg_resource}, -                    {hg, rebar_hg_resource}]). - --spec lock_source(file:filename_all(), rebar_resource:resource()) -> +-spec lock_source(file:filename_all(), rebar_resource:resource(), rebar_state:t()) ->                           rebar_resource:resource() | {error, string()}. -lock_source(AppDir, Source) -> -    Module = get_resource_type(Source), +lock_source(AppDir, Source, State) -> +    Resources = rebar_state:resources(State), +    Module = get_resource_type(Source, Resources),      Module:lock(AppDir, Source).  -spec download_source(file:filename_all(), rebar_resource:resource(), rebar_state:t()) ->                               true | {error, any()}.  download_source(AppDir, Source, State) ->      try -        Module = get_resource_type(Source), +        Resources = rebar_state:resources(State), +        Module = get_resource_type(Source, Resources),          TmpDir = ec_file:insecure_mkdtemp(),          AppDir1 = ec_cnv:to_list(AppDir),          case Module:download(TmpDir, Source, State) of @@ -64,9 +62,10 @@ download_source(AppDir, Source, State) ->              throw(?PRV_ERROR({fetch_fail, Source}))      end. --spec needs_update(file:filename_all(), rebar_resource:resource()) -> boolean() | {error, string()}. -needs_update(AppDir, Source) -> -    Module = get_resource_type(Source), +-spec needs_update(file:filename_all(), rebar_resource:resource(), rebar_state:t()) -> boolean() | {error, string()}. +needs_update(AppDir, Source, State) -> +    Resources = rebar_state:resources(State), +    Module = get_resource_type(Source, Resources),      try          Module:needs_update(AppDir, Source)      catch @@ -77,17 +76,17 @@ needs_update(AppDir, Source) ->  format_error({fetch_fail, Source}) ->      io_lib:format("Failed to fetch and copy dep: ~p", [Source]). -get_resource_type({Type, Location}) -> -    find_resource_module(Type, Location); -get_resource_type({Type, Location, _}) -> -    find_resource_module(Type, Location); -get_resource_type({Type, _, _, Location}) -> -    find_resource_module(Type, Location); -get_resource_type(_) -> +get_resource_type({Type, Location}, Resources) -> +    find_resource_module(Type, Location, Resources); +get_resource_type({Type, Location, _}, Resources) -> +    find_resource_module(Type, Location, Resources); +get_resource_type({Type, _, _, Location}, Resources) -> +    find_resource_module(Type, Location, Resources); +get_resource_type(_, _) ->      rebar_pkg_resource. -find_resource_module(Type, Location) -> -    case lists:keyfind(Type, 1, ?RESOURCES) of +find_resource_module(Type, Location, Resources) -> +    case lists:keyfind(Type, 1, Resources) of          false ->              case code:which(Type) of                  non_existing -> diff --git a/src/rebar_hooks.erl b/src/rebar_hooks.erl index 706d6b9..e144a8e 100644 --- a/src/rebar_hooks.erl +++ b/src/rebar_hooks.erl @@ -1,9 +1,30 @@  -module(rebar_hooks). --export([run_compile_hooks/4]). +-export([run_all_hooks/5]). -run_compile_hooks(Dir, Type, Command, State) -> -    Hooks = rebar_state:get(State, Type, []), +-spec run_all_hooks(file:filename_all(), pre | post, +                   atom() | {atom(), atom()} | string(), +                   [providers:t()], rebar_state:t()) -> ok. +run_all_hooks(Dir, Type, Command, Providers, State) -> +    run_provider_hooks(Dir, Type, Command, Providers, State), +    run_hooks(Dir, Type, Command, State). + +run_provider_hooks(Dir, Type, Command, Providers, State) -> +    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). + +run_hooks(Dir, Type, Command, State) -> +    Hooks = case Type of +                pre -> +                    rebar_state:get(State, pre_hooks, []); +                post -> +                    rebar_state:get(State, post_hooks, []); +                _ -> +                    [] +            end,      Env = [{"REBAR_DEPS_DIR", filename:absname(rebar_dir:deps_dir(State))}],      lists:foreach(fun({_, C, _}=Hook) when C =:= Command ->                            apply_hook(Dir, Env, Hook); diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index 5a0ca3c..a9550ff 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -3,7 +3,7 @@  -module(rebar_plugins). --export([install/1]). +-export([install/1, handle_plugins/2]).  -include("rebar.hrl"). @@ -11,34 +11,45 @@  %% Public API  %% =================================================================== +-spec install(rebar_state:t()) -> rebar_state:t().  install(State) -> -    %% Set deps_dir to a different dir for plugin so they don't collide -    OldDepsDir = rebar_state:get(State, deps_dir, ?DEFAULT_DEPS_DIR), -    State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR), -    DepsDir = rebar_dir:deps_dir(State1), -    expand_plugins(DepsDir), -    Plugins = rebar_state:get(State1, plugins, []), -    PluginProviders = lists:flatten(rebar_utils:filtermap(fun(Plugin) -> -                                                                  handle_plugin(Plugin, State1) -                                                          end, Plugins)), +    DepsDir = rebar_dir:deps_dir(State), +    Plugins = rebar_state:get(State, plugins, []), -    State2 = rebar_state:set(State1, deps_dir, OldDepsDir), -    {ok, PluginProviders, State2}. +    ProjectApps = rebar_state:project_apps(State), +    DepApps = rebar_app_discover:find_apps([DepsDir], all), + +    OtherPlugins = lists:flatmap(fun(App) -> +                                         AppDir = rebar_app_info:dir(App), +                                         C = rebar_config:consult(AppDir), +                                         S = rebar_state:new(rebar_state:new(), C, AppDir), +                                         rebar_state:get(S, plugins, []) +                                 end, ProjectApps++DepApps), + +    handle_plugins(Plugins++OtherPlugins, State). + +-spec handle_plugins([rebar_prv_install_deps:dep()], rebar_state:t()) -> rebar_state:t(). +handle_plugins(Plugins, State) -> +    PluginProviders = lists:flatmap(fun(Plugin) -> +                                            handle_plugin(Plugin, State) +                                    end, Plugins), +    rebar_state:create_logic_providers(PluginProviders, State). --spec handle_plugin(rebar_prv_install_deps:dep(), rebar_state:t()) -> {true, any()} | false.  handle_plugin(Plugin, State) ->      try -        {ok, _, State1} = rebar_prv_install_deps:handle_deps(default, State, [Plugin]), +        %% Set deps dir to plugins dir so apps are installed there +        State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR), +        {ok, _, State2} = rebar_prv_install_deps:handle_deps(default, State1, [Plugin]), -        Apps = rebar_state:all_deps(State1), +        Apps = rebar_state:all_deps(State2),          ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Apps),          [build_plugin(AppInfo) || AppInfo <- ToBuild],          plugin_providers(Plugin)      catch          C:T ->              ?DEBUG("~p ~p", [C, T]), -            ?WARN("Plugin ~p not available. It will not be used.~n", [Plugin]), -            false +            ?WARN("Plugin ~p not available. It will not be used.", [Plugin]), +            []      end.  build_plugin(AppInfo) -> @@ -56,21 +67,17 @@ plugin_providers(Plugin) when is_atom(Plugin) ->      validate_plugin(Plugin).  validate_plugin(Plugin) -> -    ok = application:load(Plugin), +    _ = application:load(Plugin),      case application:get_env(Plugin, providers) of          {ok, Providers} -> -            {true, Providers}; +            Providers;          undefined ->              Exports = Plugin:module_info(exports),              case lists:member({init,1}, Exports) of                  false -> -                    ?WARN("Plugin ~p does not export init/1. It will not be used.~n", [Plugin]), -                    false; +                    ?WARN("Plugin ~p does not export init/1. It will not be used.", [Plugin]), +                    [];                  true -> -                    {true, Plugin} +                    [Plugin]              end      end. - -expand_plugins(Dir) -> -    Apps = filelib:wildcard(filename:join([Dir, "*", "ebin"])), -    ok = code:add_pathsa(Apps). diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index a0793c1..8fafe23 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -32,6 +32,7 @@ init(State) ->  -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.  do(State) -> +    Providers = rebar_state:providers(State),      ProjectApps = rebar_state:project_apps(State),      {all, All} = handle_args(State), @@ -46,12 +47,12 @@ do(State) ->      %% Need to allow global config vars used on deps      %% Right now no way to differeniate and just give deps a new state      EmptyState = rebar_state:new(), -    clean_apps(EmptyState, DepApps), +    clean_apps(EmptyState, Providers, DepApps),      Cwd = rebar_dir:get_cwd(), -    rebar_hooks:run_compile_hooks(Cwd, pre_hooks, clean, State), -    clean_apps(State, ProjectApps), -    rebar_hooks:run_compile_hooks(Cwd, post_hooks, clean, State), +    rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), +    clean_apps(State, Providers, ProjectApps), +    rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State),      {ok, State}. @@ -63,7 +64,7 @@ format_error(Reason) ->  %% Internal functions  %% =================================================================== -clean_apps(State, Apps) -> +clean_apps(State, Providers, Apps) ->      lists:foreach(fun(AppInfo) ->                            AppDir = rebar_app_info:dir(AppInfo),                            C = rebar_config:consult(AppDir), @@ -71,9 +72,9 @@ clean_apps(State, Apps) ->                            ?INFO("Cleaning out ~s...", [rebar_app_info:name(AppInfo)]),                            %% Legacy hook support -                          rebar_hooks:run_compile_hooks(AppDir, pre_hooks, clean, S), +                          rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER, Providers, S),                            rebar_erlc_compiler:clean(State, rebar_app_info:out_dir(AppInfo)), -                          rebar_hooks:run_compile_hooks(AppDir, post_hooks, clean, S) +                          rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S)                    end, Apps).  handle_args(State) -> diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl index de77257..7602906 100644 --- a/src/rebar_prv_common_test.erl +++ b/src/rebar_prv_common_test.erl @@ -38,6 +38,11 @@ init(State) ->  -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.  do(State) ->      ?INFO("Running Common Test suites...", []), +    %% Run ct provider prehooks +    Providers = rebar_state:providers(State), +    Cwd = rebar_dir:get_cwd(), +    rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), +      try          case setup_ct(State) of              {error, {no_tests_specified, Opts}} -> @@ -46,9 +51,14 @@ do(State) ->              Opts ->                  Opts1 = setup_logdir(State, Opts),                  ?DEBUG("common test opts: ~p", [Opts1]), -                run_test(State, Opts1) +                {ok, State1} = run_test(State, Opts1), +                %% Run ct provider posthooks +                rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1), +                {ok, State1}          end -    catch error:Reason -> ?PRV_ERROR(Reason) +    catch +        error:Reason -> +            ?PRV_ERROR(Reason)      end.  -spec format_error(any()) -> iolist(). @@ -251,7 +261,7 @@ join(undefined, Suites) -> Suites;  join(Dir, Suites) when is_list(Dir), is_integer(hd(Dir)) ->      lists:map(fun(S) -> filename:join([Dir, S]) end, Suites);  %% multiple dirs or a bad dir argument, try to continue anyways -join(_, Suites) -> Suites.  +join(_, Suites) -> Suites.  find_suite_dirs(Suites) ->      AllDirs = lists:map(fun(S) -> filename:dirname(filename:absname(S)) end, Suites), diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl index 5053e57..a440927 100644 --- a/src/rebar_prv_compile.erl +++ b/src/rebar_prv_compile.erl @@ -32,20 +32,23 @@ init(State) ->  -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.  do(State) ->      ProjectApps = rebar_state:project_apps(State), +    Providers = rebar_state:providers(State),      Deps = rebar_state:deps_to_build(State),      Cwd = rebar_dir:get_cwd(), -    rebar_hooks:run_compile_hooks(Cwd, pre_hooks, compile, State), + +    rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State),      %% Need to allow global config vars used on deps      %% Right now no way to differeniate and just give deps a new state      EmptyState = rebar_state:new(), -    build_apps(EmptyState, Deps), +    build_apps(EmptyState, Providers, Deps),      %% Use the project State for building project apps      %% Set hooks to empty so top-level hooks aren't run for each project app      State2 = rebar_state:set(rebar_state:set(State, post_hooks, []), pre_hooks, []), -    ProjectApps1 = build_apps(State2, ProjectApps), -    rebar_hooks:run_compile_hooks(Cwd, post_hooks, compile, State), +    ProjectApps1 = build_apps(State2, Providers, ProjectApps), + +    rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State),      {ok, rebar_state:project_apps(State, ProjectApps1)}. @@ -53,10 +56,10 @@ do(State) ->  format_error(Reason) ->      io_lib:format("~p", [Reason]). -build_apps(State, Apps) -> -    [build_app(State, AppInfo) || AppInfo <- Apps]. +build_apps(State, Providers, Apps) -> +    [build_app(State, Providers, AppInfo) || AppInfo <- Apps]. -build_app(State, AppInfo) -> +build_app(State, Providers, AppInfo) ->      AppDir = rebar_app_info:dir(AppInfo),      OutDir = rebar_app_info:out_dir(AppInfo), @@ -71,9 +74,10 @@ build_app(State, AppInfo) ->          end,      %% Legacy hook support -    rebar_hooks:run_compile_hooks(AppDir, pre_hooks, compile, S), + +    rebar_hooks:run_all_hooks(AppDir, pre, ?PROVIDER,  Providers, S),      AppInfo1 = compile(S, AppInfo), -    rebar_hooks:run_compile_hooks(AppDir, post_hooks, compile, S), +    rebar_hooks:run_all_hooks(AppDir, post, ?PROVIDER, Providers, S),      true = code:add_patha(rebar_app_info:ebin_dir(AppInfo1)),      AppInfo1. diff --git a/src/rebar_prv_deps.erl b/src/rebar_prv_deps.erl index f1697b6..3627e91 100644 --- a/src/rebar_prv_deps.erl +++ b/src/rebar_prv_deps.erl @@ -77,7 +77,7 @@ display_dep(_State, {Name, _Vsn, Source, _Opts}) when is_tuple(Source) ->  display_dep(State, {Name, Source={pkg, _, Vsn}, Level}) when is_integer(Level) ->      DepsDir = rebar_dir:deps_dir(State),      AppDir = filename:join([DepsDir, ec_cnv:to_binary(Name)]), -    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source) of +    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source, State) of          true -> "*";          false -> ""      end, @@ -85,7 +85,7 @@ display_dep(State, {Name, Source={pkg, _, Vsn}, Level}) when is_integer(Level) -  display_dep(State, {Name, Source, Level}) when is_tuple(Source), is_integer(Level), element(1, Source) =:= git ->      DepsDir = rebar_dir:deps_dir(State),      AppDir = filename:join([DepsDir, ec_cnv:to_binary(Name)]), -    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source) of +    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source, State) of          true -> "*";          false -> ""      end, @@ -93,7 +93,7 @@ display_dep(State, {Name, Source, Level}) when is_tuple(Source), is_integer(Leve  display_dep(State, {Name, Source, Level}) when is_tuple(Source), is_integer(Level) ->      DepsDir = rebar_dir:deps_dir(State),      AppDir = filename:join([DepsDir, ec_cnv:to_binary(Name)]), -    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source) of +    NeedsUpdate = case rebar_fetch:needs_update(AppDir, Source, State) of          true -> "*";          false -> ""      end, diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl index 371d205..3e57fb0 100644 --- a/src/rebar_prv_eunit.erl +++ b/src/rebar_prv_eunit.erl @@ -37,9 +37,19 @@ init(State) ->  -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.  do(State) ->      ?INFO("Performing EUnit tests...", []), +    %% Run eunit provider prehooks +    Providers = rebar_state:providers(State), +    Cwd = rebar_dir:get_cwd(), +    rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State), +      case prepare_tests(State) of -        {ok, Tests} -> do_tests(State, Tests); -        Error       -> Error +        {ok, Tests} -> +            {ok, State1} = do_tests(State, Tests), +            %% Run eunit provider posthooks +            rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1), +            {ok, State1}; +        Error -> +            Error      end.  do_tests(State, Tests) -> @@ -250,4 +260,3 @@ help(app)    -> "List of application test suites to run";  help(cover)   -> "Generate cover data";  help(suite)   -> "List of test suites to run";  help(verbose) -> "Verbose output". - diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index e92a3f0..db2b036 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -336,13 +336,13 @@ handle_upgrade(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->  handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->      DepsDir = rebar_dir:deps_dir(State), -    {AppInfo1, NewSrcDeps, NewPkgDeps, NewLocks} = +    {AppInfo1, NewSrcDeps, NewPkgDeps, NewLocks, State1} =          handle_dep(State, DepsDir, AppInfo, Locks, Level),      AppInfo2 = rebar_app_info:dep_level(AppInfo1, Level),      {NewSrcDeps ++ SrcDeps      ,NewPkgDeps++PkgDeps      ,[AppInfo2 | SrcApps] -    ,State +    ,State1      ,NewLocks}.  -spec handle_dep(rebar_state:t(), file:filename_all(), rebar_app_info:t(), list(), integer()) -> @@ -359,13 +359,16 @@ handle_dep(State, DepsDir, AppInfo, Locks, Level) ->      S3 = rebar_state:apply_overrides(S2, Name),      AppInfo1 = rebar_app_info:state(AppInfo, S3), +    %% Dep may have plugins to install. Find and install here. +    State1 = rebar_plugins:handle_plugins(rebar_state:get(S3, plugins, []), State), +      Deps = rebar_state:get(S3, deps, []),      %% Upgrade lock level to be the level the dep will have in this dep tree      NewLocks = [{DepName, Source, LockLevel+Level} ||                     {DepName, Source, LockLevel} <- rebar_state:get(S3, {locks, default}, [])],      AppInfo2 = rebar_app_info:deps(AppInfo1, rebar_state:deps_names(Deps)),      {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, S3, Locks, Level), -    {AppInfo2, SrcDeps, PkgDeps, Locks++NewLocks}. +    {AppInfo2, SrcDeps, PkgDeps, Locks++NewLocks, State1}.  -spec maybe_fetch(rebar_app_info:t(), boolean() | {true, binary(), integer()},                    sets:set(binary()), rebar_state:t()) -> boolean(). @@ -507,12 +510,12 @@ fetch_app(AppInfo, AppDir, State) ->              Result      end. -maybe_upgrade(AppInfo, AppDir, false, _State) -> +maybe_upgrade(AppInfo, AppDir, false, State) ->      Source = rebar_app_info:source(AppInfo), -    rebar_fetch:needs_update(AppDir, Source); +    rebar_fetch:needs_update(AppDir, Source, State);  maybe_upgrade(AppInfo, AppDir, true, State) ->      Source = rebar_app_info:source(AppInfo), -    case rebar_fetch:needs_update(AppDir, Source) of +    case rebar_fetch:needs_update(AppDir, Source, State) of          true ->              ?INFO("Updating ~s", [rebar_app_info:name(AppInfo)]),              case rebar_fetch:download_source(AppDir, Source, State) of diff --git a/src/rebar_prv_lock.erl b/src/rebar_prv_lock.erl index e839168..5536ec9 100644 --- a/src/rebar_prv_lock.erl +++ b/src/rebar_prv_lock.erl @@ -37,7 +37,7 @@ do(State) ->                   %% If source is tuple it is a source dep                   %% e.g. {git, "git://github.com/ninenines/cowboy.git", "master"}                   {rebar_app_info:name(Dep) -                 ,rebar_fetch:lock_source(Dir, Source) +                 ,rebar_fetch:lock_source(Dir, Source, State)                   ,rebar_app_info:dep_level(Dep)}               end || Dep <- AllDeps, not(rebar_app_info:is_checkout(Dep))],      Dir = rebar_state:dir(State), diff --git a/src/rebar_state.erl b/src/rebar_state.erl index cd127c0..68c71a9 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -30,6 +30,7 @@           overrides/1, overrides/2,           apply_overrides/2, +         resources/1, resources/2, add_resource/2,           providers/1, providers/2, add_provider/2]).  -include("rebar.hrl"). @@ -51,6 +52,7 @@                    all_deps            = []          :: [rebar_app_info:t()],                    overrides           = [], +                  resources           = [],                    providers           = []}).  -export_type([t/0]). @@ -296,6 +298,18 @@ namespace(#state_t{namespace=Namespace}) ->  namespace(State=#state_t{}, Namespace) ->      State#state_t{namespace=Namespace}. +-spec resources(t()) -> rebar_resource:resource(). +resources(#state_t{resources=Resources}) -> +    Resources. + +-spec resources(t(), [rebar_resource:resource()]) -> t(). +resources(State, NewResources) -> +    State#state_t{resources=NewResources}. + +-spec add_resource(t(), rebar_resource:resource()) -> t(). +add_resource(State=#state_t{resources=Resources}, Resource) -> +    State#state_t{resources=[Resource | Resources]}. +  providers(#state_t{providers=Providers}) ->      Providers. @@ -308,62 +322,25 @@ add_provider(State=#state_t{providers=Providers}, Provider) ->  create_logic_providers(ProviderModules, State0) ->      try -        State1 = lists:foldl(fun(ProviderMod, StateAcc) -> -                                     case providers:new(ProviderMod, StateAcc) of -                                         {error, Reason} -> -                                             ?ERROR(Reason++"~n", []), -                                             StateAcc; -                                         {ok, StateAcc1} -> -                                             StateAcc1 -                                     end -                             end, State0, ProviderModules), -        apply_hooks(State1) +        lists:foldl(fun(ProviderMod, StateAcc) -> +                            case providers:new(ProviderMod, StateAcc) of +                                {error, Reason} -> +                                    ?ERROR(Reason++"~n", []), +                                    StateAcc; +                                {ok, StateAcc1} -> +                                    StateAcc1 +                            end +                    end, State0, ProviderModules)      catch          C:T ->              ?DEBUG("~p: ~p ~p", [C, T, erlang:get_stacktrace()]),              throw({error, "Failed creating providers. Run with DEBUG=1 for stacktrace."})      end. -apply_hooks(State0) -> -    try -        Hooks = rebar_state:get(State0, provider_hooks, []), -        PreHooks = proplists:get_value(pre, Hooks, []), -        PostHooks = proplists:get_value(post, Hooks, []), -        State1 = lists:foldl(fun({Target, Hook}, StateAcc) -> -                                     prepend_hook(StateAcc, Target, Hook) -                             end, State0, PreHooks), -        lists:foldl(fun({Target, Hook}, StateAcc) -> -                            append_hook(StateAcc, Target, Hook) -                    end, State1, PostHooks) -    catch -        C:T -> -            ?DEBUG("~p: ~p ~p", [C, T, erlang:get_stacktrace()]), -            throw({error, "Failed parsing provider hooks. Run with DEBUG=1 for stacktrace."}) -    end. -  %% ===================================================================  %% Internal functions  %% =================================================================== -prepend_hook(State=#state_t{providers=Providers}, Target, Hook) -> -    State#state_t{providers=add_hook(pre, Providers, Target, Hook)}. - -append_hook(State=#state_t{providers=Providers}, Target, Hook) -> -    State#state_t{providers=add_hook(post, Providers, Target, Hook)}. - -add_hook(Which, Providers, Target, Hook) -> -    Provider = providers:get_provider(Target, Providers), -    Hooks = providers:hooks(Provider), -    NewHooks = add_hook(Which, Hooks, Hook), -    NewProvider = providers:hooks(Provider, NewHooks), -    [NewProvider | lists:delete(Provider, Providers)]. - -add_hook(pre, {PreHooks, PostHooks}, Hook) -> -    {[Hook | PreHooks], PostHooks}; -add_hook(post, {PreHooks, PostHooks}, Hook) -> -    {PreHooks, [Hook | PostHooks]}. - -  %% Sort the list in proplist-order, meaning that `{a,b}' and `{a,c}'  %% both compare as usual, and `a' and `b' do the same, but `a' and `{a,b}' will  %% compare based on the first element of the key, and in order. So the following @@ -425,4 +402,3 @@ umerge([], Olds, Merged, CmpMerged, Cmp) when CmpMerged == Cmp ->      lists:reverse(Olds, Merged);  umerge([], Olds, Merged, _CmpMerged, Cmp) ->      lists:reverse(Olds, [Cmp | Merged]). -  | 
