Quellcode durchsuchen

Merge pull request #320 from tsloughter/dep_plugins

install dep plugins & run provider hooks the same as shell hooks (Rereopen 316)
pull/272/merge
Fred Hebert vor 10 Jahren
Ursprung
Commit
3250faa756
18 geänderte Dateien mit 234 neuen und 148 gelöschten Zeilen
  1. +4
    -0
      src/rebar.app.src
  2. +12
    -12
      src/rebar3.erl
  3. +1
    -1
      src/rebar_core.erl
  4. +21
    -22
      src/rebar_fetch.erl
  5. +24
    -3
      src/rebar_hooks.erl
  6. +33
    -26
      src/rebar_plugins.erl
  7. +8
    -7
      src/rebar_prv_clean.erl
  8. +13
    -3
      src/rebar_prv_common_test.erl
  9. +13
    -9
      src/rebar_prv_compile.erl
  10. +3
    -3
      src/rebar_prv_deps.erl
  11. +12
    -3
      src/rebar_prv_eunit.erl
  12. +9
    -6
      src/rebar_prv_install_deps.erl
  13. +1
    -1
      src/rebar_prv_lock.erl
  14. +23
    -47
      src/rebar_state.erl
  15. +2
    -1
      test/mock_git_resource.erl
  16. +34
    -2
      test/rebar_compile_SUITE.erl
  17. +6
    -2
      test/rebar_resource_SUITE.erl
  18. +15
    -0
      test/rebar_test_utils.erl

+ 4
- 0
src/rebar.app.src Datei anzeigen

@ -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,

+ 12
- 12
src/rebar3.erl Datei anzeigen

@ -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"]);

+ 1
- 1
src/rebar_core.erl Datei anzeigen

@ -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").

+ 21
- 22
src/rebar_fetch.erl Datei anzeigen

@ -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 ->

+ 24
- 3
src/rebar_hooks.erl Datei anzeigen

@ -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);

+ 33
- 26
src/rebar_plugins.erl Datei anzeigen

@ -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).

+ 8
- 7
src/rebar_prv_clean.erl Datei anzeigen

@ -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) ->

+ 13
- 3
src/rebar_prv_common_test.erl Datei anzeigen

@ -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),

+ 13
- 9
src/rebar_prv_compile.erl Datei anzeigen

@ -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.

+ 3
- 3
src/rebar_prv_deps.erl Datei anzeigen

@ -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,

+ 12
- 3
src/rebar_prv_eunit.erl Datei anzeigen

@ -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".

+ 9
- 6
src/rebar_prv_install_deps.erl Datei anzeigen

@ -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

+ 1
- 1
src/rebar_prv_lock.erl Datei anzeigen

@ -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),

+ 23
- 47
src/rebar_state.erl Datei anzeigen

@ -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]).

+ 2
- 1
test/mock_git_resource.erl Datei anzeigen

@ -99,6 +99,7 @@ mock_vsn(Opts) ->
%% into a `rebar.config' file to describe dependencies.
mock_download(Opts) ->
Deps = proplists:get_value(deps, Opts, []),
Config = proplists:get_value(config, Opts, []),
Default = proplists:get_value(default_vsn, Opts, "0.0.0"),
Overrides = proplists:get_value(override_vsn, Opts, []),
meck:expect(
@ -112,7 +113,7 @@ mock_download(Opts) ->
Dir, App, Vsn,
[kernel, stdlib] ++ [element(1,D) || D <- AppDeps]
),
rebar_test_utils:create_config(Dir, [{deps, AppDeps}]),
rebar_test_utils:create_config(Dir, [{deps, AppDeps}]++Config),
{ok, 'WHATEVER'}
end).

+ 34
- 2
test/rebar_compile_SUITE.erl Datei anzeigen

@ -15,7 +15,8 @@
dont_recompile_when_opts_dont_change/1,
dont_recompile_yrl_or_xrl/1,
deps_in_path/1,
checkout_priority/1]).
checkout_priority/1,
compile_plugins/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@ -41,7 +42,7 @@ all() ->
build_checkout_apps, build_checkout_deps,
build_all_srcdirs,
recompile_when_opts_change, dont_recompile_when_opts_dont_change,
dont_recompile_yrl_or_xrl, deps_in_path, checkout_priority].
dont_recompile_yrl_or_xrl, deps_in_path, checkout_priority, compile_plugins].
build_basic_app(Config) ->
AppDir = ?config(apps, Config),
@ -332,3 +333,34 @@ checkout_priority(Config) ->
?assertEqual(Vsn2, proplists:get_value(vsn, DepProps)),
?assertEqual(Vsn2, proplists:get_value(vsn, PkgProps)).
%% Tests that compiling a project installs and compiles the plugins of deps
compile_plugins(Config) ->
AppDir = ?config(apps, Config),
PluginsDir = filename:join([?config(base_dir, Config), "default", "plugins"]),
Name = rebar_test_utils:create_random_name("app1_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
DepName = rebar_test_utils:create_random_name("dep1_"),
PluginName = rebar_test_utils:create_random_name("plugin1_"),
mock_git_resource:mock([{config, [{plugins, [
{list_to_atom(PluginName), Vsn}
]}]}]),
mock_pkg_resource:mock([
{pkgdeps, [{{iolist_to_binary(PluginName), iolist_to_binary(Vsn)}, []}]}
]),
RConfFile =
rebar_test_utils:create_config(AppDir,
[{deps, [
{list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}}
]}]),
{ok, RConf} = file:consult(RConfFile),
%% Build with deps.
rebar_test_utils:run_and_check(
Config, RConf, ["compile"],
{ok, [{app, Name}, {plugin, PluginName}, {dep, DepName}]}
).

+ 6
- 2
test/rebar_resource_SUITE.erl Datei anzeigen

@ -12,7 +12,10 @@ groups() ->
{hg, [], [{group, all}]}].
init_per_group(all, Config) ->
Config;
State = rebar_state:resources(rebar_state:new(), [{git, rebar_git_resource},
{pkg, rebar_pkg_resource},
{hg, rebar_hg_resource}]),
[{state, State} | Config];
init_per_group(Name, Config) ->
[{type, Name},
{resource, {Name, "https://example.org/user/app", "vsn"}} | Config].
@ -33,4 +36,5 @@ end_per_testcase(_, Config) ->
change_type_upgrade(Config) ->
?assert(rebar_fetch:needs_update(?config(path, Config),
?config(resource, Config))).
?config(resource, Config),
?config(state, Config))).

+ 15
- 0
test/rebar_test_utils.erl Datei anzeigen

@ -158,6 +158,7 @@ top_level_deps([{{Name, Vsn, Ref}, _} | Deps]) ->
%%%%%%%%%%%%%%%
check_results(AppDir, Expected) ->
BuildDirs = filelib:wildcard(filename:join([AppDir, "_build", "*", "lib"])),
PluginDirs = filelib:wildcard(filename:join([AppDir, "_build", "*", "plugins"])),
CheckoutsDir = filename:join([AppDir, "_checkouts"]),
LockFile = filename:join([AppDir, "rebar.lock"]),
Locks = lists:flatten(rebar_config:consult_file(LockFile)),
@ -172,6 +173,8 @@ check_results(AppDir, Expected) ->
DepsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Deps],
Checkouts = rebar_app_discover:find_apps([CheckoutsDir], all),
CheckoutsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Checkouts],
Plugins = rebar_app_discover:find_apps(PluginDirs, all),
PluginsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Plugins],
lists:foreach(
fun({app, Name}) ->
@ -213,6 +216,18 @@ check_results(AppDir, Expected) ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App)))
end
; ({plugin, Name}) ->
ct:pal("Name: ~p", [Name]),
?assertNotEqual(false, lists:keyfind(Name, 1, PluginsNames))
; ({plugin, Name, Vsn}) ->
ct:pal("Name: ~p, Vsn: ~p", [Name, Vsn]),
case lists:keyfind(Name, 1, PluginsNames) of
false ->
error({dep_not_found, Name});
{Name, App} ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App)))
end
; ({lock, Name}) ->
ct:pal("Name: ~p", [Name]),
?assertNotEqual(false, lists:keyfind(iolist_to_binary(Name), 1, Locks))

Laden…
Abbrechen
Speichern