summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Sloughter <t@crashfast.com>2015-05-17 14:36:03 -0500
committerTristan Sloughter <t@crashfast.com>2015-05-17 14:36:03 -0500
commit3a201230fedb01ba258c291ed56450300caeac56 (patch)
tree77853d81ec2ed2c00be88fa23e7be553484df58c
parent162f0f8f63c99c6a9800ef1911060fad8b257b8b (diff)
install plugins from the global config to ~/.cache/plugins
-rw-r--r--src/rebar3.erl11
-rw-r--r--src/rebar_dir.erl13
-rw-r--r--src/rebar_plugins.erl24
-rw-r--r--src/rebar_prv_common_test.erl2
-rw-r--r--src/rebar_prv_install_deps.erl3
-rw-r--r--src/rebar_state.erl5
-rw-r--r--test/rebar_compile_SUITE.erl57
-rw-r--r--test/rebar_test_utils.erl17
8 files changed, 110 insertions, 22 deletions
diff --git a/src/rebar3.erl b/src/rebar3.erl
index 1a02407..523b8b0 100644
--- a/src/rebar3.erl
+++ b/src/rebar3.erl
@@ -141,7 +141,16 @@ init_config() ->
?DEBUG("Load global config file ~p",
[GlobalConfigFile]),
GlobalConfig = rebar_state:new(rebar_config:consult_file(GlobalConfigFile)),
- rebar_state:new(GlobalConfig, Config1);
+
+ %% We don't want to worry about global plugin install state effecting later
+ %% usage. So we throw away the global profile state used for plugin install.
+ GlobalConfigThrowAway = rebar_state:current_profiles(GlobalConfig, ["global"]),
+ rebar_plugins:handle_plugins(global,
+ rebar_state:get(GlobalConfigThrowAway, plugins, []),
+ GlobalConfigThrowAway),
+
+ GlobalConfig2 = rebar_state:set(GlobalConfig, plugins, []),
+ rebar_state:new(GlobalConfig2, Config1);
false ->
rebar_state:new(Config1)
end,
diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl
index a94c72d..8d8a39e 100644
--- a/src/rebar_dir.erl
+++ b/src/rebar_dir.erl
@@ -30,14 +30,15 @@ base_dir(State) ->
-spec profile_dir(rebar_state:t(), [atom()]) -> file:filename_all().
profile_dir(State, Profiles) ->
- ProfilesStrings = case [ec_cnv:to_list(P) || P <- Profiles] of
- ["default"] -> ["default"];
+ {BaseDir, ProfilesStrings} = case [ec_cnv:to_list(P) || P <- Profiles] of
+ ["global"] -> {?MODULE:global_cache_dir(State), [""]};
+ ["default"] -> {rebar_state:get(State, base_dir, ?DEFAULT_BASE_DIR), ["default"]};
%% drop `default` from the profile dir if it's implicit and reverse order
%% of profiles to match order passed to `as`
- ["default"|Rest] -> Rest
+ ["default"|Rest] -> {rebar_state:get(State, base_dir, ?DEFAULT_BASE_DIR), Rest}
end,
ProfilesDir = string:join(ProfilesStrings, "+"),
- filename:join(rebar_state:get(State, base_dir, ?DEFAULT_BASE_DIR), ProfilesDir).
+ filename:join(BaseDir, ProfilesDir).
-spec deps_dir(rebar_state:t()) -> file:filename_all().
@@ -81,11 +82,11 @@ global_config_dir(State) ->
rebar_state:get(State, global_rebar_dir, filename:join([Home, ".config", "rebar3"])).
global_config(State) ->
- filename:join(global_config_dir(State), "config").
+ filename:join(global_config_dir(State), "rebar.config").
global_config() ->
Home = home_dir(),
- filename:join([Home, ".config", "rebar3", "config"]).
+ filename:join([Home, ".config", "rebar3", "rebar.config"]).
global_cache_dir(State) ->
Home = home_dir(),
diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl
index c16223e..d03ada0 100644
--- a/src/rebar_plugins.erl
+++ b/src/rebar_plugins.erl
@@ -3,7 +3,7 @@
-module(rebar_plugins).
--export([install/1, handle_plugins/2]).
+-export([install/1, handle_plugins/2, handle_plugins/3]).
-include("rebar.hrl").
@@ -28,16 +28,24 @@ install(State) ->
-spec handle_plugins([rebar_prv_install_deps:dep()], rebar_state:t()) -> rebar_state:t().
handle_plugins(Plugins, State) ->
+ handle_plugins(default, Plugins, State).
+
+handle_plugins(Profile, Plugins, State) ->
+ %% Set deps dir to plugins dir so apps are installed there
+ State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR),
+
PluginProviders = lists:flatmap(fun(Plugin) ->
- handle_plugin(Plugin, State)
+ handle_plugin(Profile, Plugin, State1)
end, Plugins),
- rebar_state:create_logic_providers(PluginProviders, State).
-handle_plugin(Plugin, State) ->
+ %% reset deps dir
+ State2 = rebar_state:set(State1, deps_dir, ?DEFAULT_DEPS_DIR),
+
+ rebar_state:create_logic_providers(PluginProviders, State2).
+
+handle_plugin(Profile, Plugin, State) ->
try
- %% 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]),
+ {ok, _, State2} = rebar_prv_install_deps:handle_deps(Profile, State, [Plugin]),
Apps = rebar_state:all_deps(State2),
ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Apps),
@@ -46,7 +54,7 @@ handle_plugin(Plugin, State) ->
plugin_providers(Plugin)
catch
C:T ->
- ?DEBUG("~p ~p", [C, T]),
+ ?DEBUG("~p ~p ~p", [C, T, erlang:get_stacktrace()]),
?WARN("Plugin ~p not available. It will not be used.", [Plugin]),
[]
end.
diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl
index eb51d8d..d4370de 100644
--- a/src/rebar_prv_common_test.erl
+++ b/src/rebar_prv_common_test.erl
@@ -303,7 +303,7 @@ copy(State, Dir) ->
compile_dir(State, Dir, OutDir) ->
NewState = replace_src_dirs(State, [Dir]),
- ok = rebar_erlc_compiler:compile(NewState, rebar_state:dir(State), OutDir),
+ ok = rebar_erlc_compiler:compile(NewState, rebar_dir:base_dir(State), OutDir),
ok = maybe_cover_compile(State, Dir),
OutDir.
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index ba49532..2d69aa9 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -380,7 +380,6 @@ handle_dep(State, DepsDir, AppInfo, Locks, Level) ->
%% 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} ||
@@ -432,7 +431,7 @@ maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) ->
already_in_default(AppInfo, State) ->
Name = ec_cnv:to_list(rebar_app_info:name(AppInfo)),
- DefaultAppDir = filename:join([rebar_state:get(State, base_dir), "default", "lib", Name]),
+ DefaultAppDir = filename:join([rebar_state:get(State, base_dir, []), "default", "lib", Name]),
rebar_app_discover:find_app(DefaultAppDir, all).
needs_symlinking(State, Profile) ->
diff --git a/src/rebar_state.erl b/src/rebar_state.erl
index 7a6e60d..dd72fed 100644
--- a/src/rebar_state.erl
+++ b/src/rebar_state.erl
@@ -12,7 +12,7 @@
lock/1, lock/2,
- current_profiles/1,
+ current_profiles/1, current_profiles/2,
command_args/1, command_args/2,
command_parsed_args/1, command_parsed_args/2,
@@ -175,6 +175,9 @@ opts(State, Opts) ->
current_profiles(#state_t{current_profiles=Profiles}) ->
Profiles.
+current_profiles(State, Profiles) ->
+ State#state_t{current_profiles=Profiles}.
+
lock(#state_t{lock=Lock}) ->
Lock.
diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl
index bdab075..2dc57c5 100644
--- a/test/rebar_compile_SUITE.erl
+++ b/test/rebar_compile_SUITE.erl
@@ -19,6 +19,7 @@
delete_beam_if_source_deleted/1,
checkout_priority/1,
compile_plugins/1,
+ compile_global_plugins/1,
highest_version_of_pkg_dep/1,
parse_transform_test/1]).
@@ -47,8 +48,8 @@ all() ->
build_all_srcdirs, recompile_when_hrl_changes,
recompile_when_opts_change, dont_recompile_when_opts_dont_change,
dont_recompile_yrl_or_xrl, delete_beam_if_source_deleted,
- deps_in_path, checkout_priority, compile_plugins, highest_version_of_pkg_dep,
- parse_transform_test].
+ deps_in_path, checkout_priority, compile_plugins, compile_global_plugins,
+ highest_version_of_pkg_dep, parse_transform_test].
build_basic_app(Config) ->
AppDir = ?config(apps, Config),
@@ -427,6 +428,58 @@ compile_plugins(Config) ->
{ok, [{app, Name}, {plugin, PluginName}, {dep, DepName}]}
).
+%% Tests that compiling a project installs and compiles the global plugins
+compile_global_plugins(Config) ->
+ AppDir = ?config(apps, Config),
+ GlobalDir = filename:join(AppDir, "global"),
+ GlobalConfigDir = filename:join([GlobalDir, ".config", "rebar3"]),
+ GlobalConfig = filename:join([GlobalDir, ".config", "rebar3", "rebar.config"]),
+
+ meck:new(rebar_dir, [passthrough]),
+ meck:expect(rebar_dir, global_config, fun() -> GlobalConfig end),
+ meck:expect(rebar_dir, global_cache_dir, fun(_) -> GlobalDir end),
+
+ Name = rebar_test_utils:create_random_name("app1_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ Vsn2 = 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([{deps, [{list_to_atom(PluginName), Vsn},
+ {list_to_atom(PluginName), Vsn2},
+ {{iolist_to_binary(DepName), iolist_to_binary(Vsn)}, []}]}]),
+
+
+ rebar_test_utils:create_config(GlobalConfigDir,
+ [{plugins, [
+ {list_to_atom(PluginName), {git, "http://site.com/user/"++PluginName++".git", {tag, Vsn}}}
+ ]}]),
+ RConfFile =
+ rebar_test_utils:create_config(AppDir,
+ [{deps, [
+ {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}}
+ ]},
+ {plugins, [
+ {list_to_atom(PluginName), {git, "http://site.com/user/"++PluginName++".git", {tag, Vsn2}}}
+ ]}]),
+ {ok, RConf} = file:consult(RConfFile),
+
+ %% Runs global plugin install
+ rebar3:init_config(),
+
+ %% Build with deps.
+ rebar_test_utils:run_and_check(
+ Config, RConf, ["compile"],
+ {ok, [{app, Name},
+ {global_plugin, PluginName, Vsn},
+ {plugin, PluginName, Vsn2},
+ {dep, DepName}]}
+ ),
+
+ meck:unload(rebar_dir).
+
highest_version_of_pkg_dep(Config) ->
AppDir = ?config(apps, Config),
diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl
index 2cdc58b..c4dc663 100644
--- a/test/rebar_test_utils.erl
+++ b/test/rebar_test_utils.erl
@@ -160,6 +160,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"])),
+ GlobalPluginDirs = filelib:wildcard(filename:join([AppDir, "global", "plugins"])),
CheckoutsDir = filename:join([AppDir, "_checkouts"]),
LockFile = filename:join([AppDir, "rebar.lock"]),
Locks = lists:flatten(rebar_config:consult_file(LockFile)),
@@ -176,6 +177,8 @@ check_results(AppDir, Expected) ->
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],
+ GlobalPlugins = rebar_app_discover:find_apps(GlobalPluginDirs, all),
+ GlobalPluginsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- GlobalPlugins],
lists:foreach(
fun({app, Name}) ->
@@ -224,7 +227,19 @@ check_results(AppDir, Expected) ->
ct:pal("Name: ~p, Vsn: ~p", [Name, Vsn]),
case lists:keyfind(Name, 1, PluginsNames) of
false ->
- error({dep_not_found, Name});
+ error({plugin_not_found, Name});
+ {Name, App} ->
+ ?assertEqual(iolist_to_binary(Vsn),
+ iolist_to_binary(rebar_app_info:original_vsn(App)))
+ end
+ ; ({global_plugin, Name}) ->
+ ct:pal("Name: ~p", [Name]),
+ ?assertNotEqual(false, lists:keyfind(Name, 1, GlobalPluginsNames))
+ ; ({global_plugin, Name, Vsn}) ->
+ ct:pal("Name: ~p, Vsn: ~p", [Name, Vsn]),
+ case lists:keyfind(Name, 1, GlobalPluginsNames) of
+ false ->
+ error({global_plugin_not_found, Name});
{Name, App} ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App)))