diff options
| -rw-r--r-- | src/rebar3.erl | 11 | ||||
| -rw-r--r-- | src/rebar_dir.erl | 13 | ||||
| -rw-r--r-- | src/rebar_plugins.erl | 24 | ||||
| -rw-r--r-- | src/rebar_prv_common_test.erl | 2 | ||||
| -rw-r--r-- | src/rebar_prv_install_deps.erl | 3 | ||||
| -rw-r--r-- | src/rebar_state.erl | 5 | ||||
| -rw-r--r-- | test/rebar_compile_SUITE.erl | 57 | ||||
| -rw-r--r-- | test/rebar_test_utils.erl | 17 | 
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))) | 
