summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.md2
-rw-r--r--priv/templates/gitignore1
-rw-r--r--rebar.config2
-rw-r--r--rebar.lock2
-rw-r--r--src/rebar3.erl11
-rw-r--r--src/rebar_dir.erl50
-rw-r--r--src/rebar_erlc_compiler.erl3
-rw-r--r--src/rebar_fetch.erl2
-rw-r--r--src/rebar_otp_app.erl5
-rw-r--r--src/rebar_plugins.erl24
-rw-r--r--src/rebar_prv_common_test.erl13
-rw-r--r--src/rebar_prv_compile.erl4
-rw-r--r--src/rebar_prv_eunit.erl74
-rw-r--r--src/rebar_prv_install_deps.erl3
-rw-r--r--src/rebar_state.erl7
-rw-r--r--src/rebar_utils.erl18
-rw-r--r--test/rebar_compile_SUITE.erl57
-rw-r--r--test/rebar_dir_SUITE.erl99
-rw-r--r--test/rebar_test_utils.erl17
20 files changed, 333 insertions, 62 deletions
diff --git a/.gitignore b/.gitignore
index bd0314f..8028d9c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.rebar3
rebar3
_build
.depsolver_plt
diff --git a/README.md b/README.md
index 8cca7de..659ceff 100644
--- a/README.md
+++ b/README.md
@@ -110,7 +110,7 @@ format_error(Reason) ->
Building
--------
-Recommended installation of [Erlang/OTP](http://www.erlang.org) is binary packages from [Erlang Solutions](https://www.erlang-solutions.com/downloads/download-erlang-otp). For source it is recommended you use [erln8](http://metadave.github.io/erln8/) or [kerl](https://github.com/yrashk/kerl).
+Recommended installation of [Erlang/OTP](http://www.erlang.org) is source built using [erln8](http://metadave.github.io/erln8/) or [kerl](https://github.com/yrashk/kerl). For binary packages use those provided by [Erlang Solutions](https://www.erlang-solutions.com/downloads/download-erlang-otp), but be sure to choose the "Standard" download option or you'll have issues building projects.
### Dependencies
diff --git a/priv/templates/gitignore b/priv/templates/gitignore
index 40a1d4f..a939dce 100644
--- a/priv/templates/gitignore
+++ b/priv/templates/gitignore
@@ -16,3 +16,4 @@ _deps
_plugins
_tdeps
logs
+_build \ No newline at end of file
diff --git a/rebar.config b/rebar.config
index 504a462..b885002 100644
--- a/rebar.config
+++ b/rebar.config
@@ -10,7 +10,7 @@
{tag, "v1.3.1"}}},
{relx, "",
{git, "https://github.com/erlware/relx.git",
- {tag, "v2.0.0"}}},
+ {branch, "master"}}},
{mustache, ".*",
{git, "https://github.com/soranoba/mustache.git",
{tag, "v0.3.0"}}},
diff --git a/rebar.lock b/rebar.lock
index 6bff315..b2783d2 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -1,6 +1,6 @@
[{<<"relx">>,
{git,"https://github.com/erlware/relx.git",
- {ref,"2e59b1c95575b3c104cc191e954c82baadc43c6c"}},
+ {ref,"74fec3455ba6dbb7d9e369137c1b15ab10804993"}},
0},
{<<"providers">>,
{git,"https://github.com/tsloughter/providers.git",
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..9bff2ab 100644
--- a/src/rebar_dir.erl
+++ b/src/rebar_dir.erl
@@ -20,7 +20,10 @@
template_dir/1,
processing_base_dir/1,
processing_base_dir/2,
- make_relative_path/2]).
+ make_relative_path/2,
+ src_dirs/1, src_dirs/2,
+ extra_src_dirs/1, extra_src_dirs/2,
+ all_src_dirs/1, all_src_dirs/3]).
-include("rebar.hrl").
@@ -30,14 +33,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 +85,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(),
@@ -120,3 +124,35 @@ do_make_relative_path([H|T1], [H|T2]) ->
do_make_relative_path(Source, Target) ->
Base = lists:duplicate(max(length(Target) - 1, 0), ".."),
filename:join(Base ++ Source).
+
+-spec src_dirs(rebar_state:t()) -> list(file:filename_all()).
+src_dirs(State) -> src_dirs(State, []).
+
+-spec src_dirs(rebar_state:t(), list(file:filename_all())) -> list(file:filename_all()).
+src_dirs(State, Default) ->
+ ErlOpts = rebar_utils:erl_opts(State),
+ Vs = proplists:get_all_values(src_dirs, ErlOpts),
+ case lists:append(Vs) of
+ [] -> Default;
+ Dirs -> Dirs
+ end.
+
+-spec extra_src_dirs(rebar_state:t()) -> list(file:filename_all()).
+extra_src_dirs(State) -> extra_src_dirs(State, []).
+
+-spec extra_src_dirs(rebar_state:t(), list(file:filename_all())) -> list(file:filename_all()).
+extra_src_dirs(State, Default) ->
+ ErlOpts = rebar_utils:erl_opts(State),
+ Vs = proplists:get_all_values(extra_src_dirs, ErlOpts),
+ case lists:append(Vs) of
+ [] -> Default;
+ Dirs -> Dirs
+ end.
+
+-spec all_src_dirs(rebar_state:t()) -> list(file:filename_all()).
+all_src_dirs(State) -> all_src_dirs(State, [], []).
+
+-spec all_src_dirs(rebar_state:t(), list(file:filename_all()), list(file:filename_all())) ->
+ list(file:filename_all()).
+all_src_dirs(State, SrcDefault, ExtraDefault) ->
+ src_dirs(State, SrcDefault) ++ extra_src_dirs(State, ExtraDefault).
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index c7a3474..b9072a3 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -143,8 +143,7 @@ doterl_compile(Config, Dir, OutDir, MoreSources, ErlOpts) ->
%% Support the src_dirs option allowing multiple directories to
%% contain erlang source. This might be used, for example, should
%% eunit tests be separated from the core application source.
- SrcDirs = [filename:join(Dir, X) || X <- proplists:get_value(src_dirs, ErlOpts, ["src"]) ++
- proplists:get_value(extra_src_dirs, ErlOpts, [])],
+ SrcDirs = [filename:join(Dir, X) || X <- rebar_dir:all_src_dirs(Config, ["src"], [])],
AllErlFiles = gather_src(SrcDirs, []) ++ MoreSources,
%% Make sure that ebin/ exists and is on the path
diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl
index 0aca308..64c5380 100644
--- a/src/rebar_fetch.erl
+++ b/src/rebar_fetch.erl
@@ -72,7 +72,7 @@ format_error({failed_extract, CachePath}) ->
format_error({bad_etag, Source}) ->
io_lib:format("MD5 Checksum comparison failed for: ~s", [Source]);
format_error({fetch_fail, Source}) ->
- io_lib:format("Failed to fetch and copy dep: ~s", [Source]);
+ io_lib:format("Failed to fetch and copy dep: ~p", [Source]);
format_error({bad_checksum, File}) ->
io_lib:format("Checksum mismatch against tarball in ~s", [File]);
format_error({bad_registry_checksum, File}) ->
diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl
index e5ad1d2..c457999 100644
--- a/src/rebar_otp_app.erl
+++ b/src/rebar_otp_app.erl
@@ -160,9 +160,8 @@ ebin_modules(State, App, Dir) ->
[rebar_utils:beam_to_mod(N) || N <- Filtered].
extra_dirs(State) ->
- ErlOpts = rebar_utils:erl_opts(State),
- Extras = proplists:get_value(extra_src_dirs, ErlOpts, []),
- SrcDirs = proplists:get_value(src_dirs, ErlOpts, ["src"]),
+ Extras = rebar_dir:extra_src_dirs(State),
+ SrcDirs = rebar_dir:src_dirs(State, ["src"]),
%% remove any dirs that are defined in `src_dirs` from `extra_src_dirs`
Extras -- SrcDirs.
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..af77fa2 100644
--- a/src/rebar_prv_common_test.erl
+++ b/src/rebar_prv_common_test.erl
@@ -38,7 +38,7 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
?INFO("Running Common Test suites...", []),
- code:add_pathsa(rebar_state:code_paths(State, all_deps)),
+ rebar_utils:update_code(rebar_state:code_paths(State, all_deps)),
%% Run ct provider prehooks
Providers = rebar_state:providers(State),
@@ -49,7 +49,7 @@ do(State) ->
{ok, State1} = Result ->
%% Run ct provider posthooks
rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1),
- rebar_utils:cleanup_code_path(rebar_state:code_paths(State1, default)),
+ rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
Result;
?PRV_ERROR(_) = Error ->
rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
@@ -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.
@@ -368,8 +368,11 @@ sub_dirs(Path) ->
replace_src_dirs(State, Dirs) ->
%% replace any `src_dirs` with the test dirs
ErlOpts = rebar_state:get(State, erl_opts, []),
- StrippedOpts = lists:keydelete(src_dirs, 1, ErlOpts),
- rebar_state:set(State, erl_opts, [{src_dirs, Dirs}|StrippedOpts]).
+ StrippedOpts = filter_src_dirs(ErlOpts),
+ rebar_state:set(State, erl_opts, [{extra_src_dirs, Dirs}|StrippedOpts]).
+
+filter_src_dirs(ErlOpts) ->
+ lists:filter(fun({src_dirs, _}) -> false; ({extra_src_dirs, _}) -> false; (_) -> true end, ErlOpts).
test_dirs(State, Opts) ->
BareTest = filename:join([rebar_state:dir(State), "test"]),
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl
index 704a9f0..1dff4d8 100644
--- a/src/rebar_prv_compile.erl
+++ b/src/rebar_prv_compile.erl
@@ -119,9 +119,7 @@ copy_app_dirs(State, OldAppDir, AppDir) ->
end,
filelib:ensure_dir(filename:join(AppDir, "dummy")),
%% link to src_dirs to be adjacent to ebin is needed for R15 use of cover/xref
- ErlOpts = rebar_utils:erl_opts(State),
- SrcDirs = proplists:get_value(src_dirs, ErlOpts, ["src"]) ++
- proplists:get_value(extra_src_dirs, ErlOpts, []),
+ SrcDirs = rebar_dir:all_src_dirs(State, ["src"], ["test"]),
[symlink_or_copy(OldAppDir, AppDir, Dir) || Dir <- ["priv", "include"] ++ SrcDirs];
false ->
ok
diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl
index 8eaa926..3ad593d 100644
--- a/src/rebar_prv_eunit.erl
+++ b/src/rebar_prv_eunit.erl
@@ -37,7 +37,8 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
?INFO("Performing EUnit tests...", []),
- code:add_pathsa(rebar_state:code_paths(State, all_deps)),
+ rebar_utils:update_code(rebar_state:code_paths(State, all_deps)),
+
%% Run eunit provider prehooks
Providers = rebar_state:providers(State),
Cwd = rebar_dir:get_cwd(),
@@ -49,7 +50,7 @@ do(State) ->
{ok, State1} ->
%% Run eunit provider posthooks
rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1),
- rebar_utils:cleanup_code_path(rebar_state:code_paths(State1, default)),
+ rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
{ok, State1};
Error ->
rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
@@ -84,8 +85,7 @@ format_error({error_running_tests, Reason}) ->
test_state(State) ->
ErlOpts = rebar_state:get(State, eunit_compile_opts, []),
TestOpts = safe_define_test_macro(ErlOpts),
- TestDir = [{extra_src_dirs, ["test"]}],
- first_files(State) ++ [{erl_opts, TestOpts ++ TestDir}].
+ first_files(State) ++ [{erl_opts, TestOpts}].
safe_define_test_macro(Opts) ->
%% defining a compile macro twice results in an exception so
@@ -106,38 +106,56 @@ first_files(State) ->
prepare_tests(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),
- ok = maybe_cover_compile(State, RawOpts),
- ProjectApps = project_apps(State),
- resolve_apps(ProjectApps, RawOpts).
-
-maybe_cover_compile(State, Opts) ->
- State1 = case proplists:get_value(cover, Opts, false) of
- true -> rebar_state:set(State, cover_enabled, true);
- false -> State
- end,
- rebar_prv_cover:maybe_cover_compile(State1).
+ resolve_apps(State, RawOpts).
-resolve_apps(ProjectApps, RawOpts) ->
+resolve_apps(State, RawOpts) ->
case proplists:get_value(app, RawOpts) of
- undefined -> resolve_suites(ProjectApps, RawOpts);
+ undefined -> resolve_suites(State, RawOpts);
%% convert app name strings to `rebar_app_info` objects
Apps -> AppNames = string:tokens(Apps, [$,]),
+ ProjectApps = project_apps(State),
case filter_apps_by_name(AppNames, ProjectApps) of
- {ok, TestApps} -> resolve_suites(TestApps, RawOpts);
+ {ok, TestApps} -> resolve_suites(State, TestApps, RawOpts);
Error -> Error
end
end.
-resolve_suites(Apps, RawOpts) ->
+resolve_suites(State, RawOpts) -> resolve_suites(State, project_apps(State), RawOpts).
+
+resolve_suites(State, Apps, RawOpts) ->
case proplists:get_value(suite, RawOpts) of
- undefined -> test_set(Apps, all);
+ undefined -> compile_tests(State, Apps, all, RawOpts);
Suites -> SuiteNames = string:tokens(Suites, [$,]),
case filter_suites_by_apps(SuiteNames, Apps) of
- {ok, S} -> test_set(Apps, S);
+ {ok, S} -> compile_tests(State, Apps, S, RawOpts);
Error -> Error
end
end.
+compile_tests(State, TestApps, Suites, RawOpts) ->
+ F = fun(AppInfo) ->
+ AppDir = rebar_app_info:dir(AppInfo),
+ S = case rebar_app_info:state(AppInfo) of
+ undefined ->
+ C = rebar_config:consult(AppDir),
+ rebar_state:new(State, C, AppDir);
+ AppState ->
+ AppState
+ end,
+ ok = rebar_erlc_compiler:compile(replace_src_dirs(S),
+ ec_cnv:to_list(rebar_app_info:out_dir(AppInfo)))
+ end,
+ lists:foreach(F, TestApps),
+ ok = maybe_cover_compile(State, RawOpts),
+ {ok, test_set(TestApps, Suites)}.
+
+maybe_cover_compile(State, Opts) ->
+ State1 = case proplists:get_value(cover, Opts, false) of
+ true -> rebar_state:set(State, cover_enabled, true);
+ false -> State
+ end,
+ rebar_prv_cover:maybe_cover_compile(State1).
+
project_apps(State) ->
filter_checkouts(rebar_state:project_apps(State)).
@@ -204,8 +222,20 @@ app_modules([App|Rest], Acc) ->
app_modules(Rest, NewAcc)
end.
-test_set(Apps, all) -> {ok, set_apps(Apps, [])};
-test_set(_Apps, Suites) -> {ok, set_suites(Suites, [])}.
+replace_src_dirs(State) ->
+ %% replace any `src_dirs` with the test dirs
+ ErlOpts = rebar_state:get(State, erl_opts, []),
+ StrippedOpts = filter_src_dirs(ErlOpts),
+ case rebar_dir:extra_src_dirs(State) of
+ [] -> rebar_state:set(State, erl_opts, [{src_dirs, ["test"]}|StrippedOpts]);
+ _ -> rebar_state:set(State, erl_opts, StrippedOpts)
+ end.
+
+filter_src_dirs(ErlOpts) ->
+ lists:filter(fun({src_dirs, _}) -> false; (_) -> true end, ErlOpts).
+
+test_set(Apps, all) -> set_apps(Apps, []);
+test_set(_Apps, Suites) -> set_suites(Suites, []).
set_apps([], Acc) -> lists:reverse(Acc);
set_apps([App|Rest], Acc) ->
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..55081a5 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,
@@ -51,7 +51,7 @@
namespace = undefined :: atom(),
command_args = [],
- command_parsed_args = [],
+ command_parsed_args = {[], []},
project_apps = [] :: [rebar_app_info:t()],
deps_to_build = [] :: [rebar_app_info:t()],
@@ -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/src/rebar_utils.erl b/src/rebar_utils.erl
index 160d547..ffa29e6 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -47,6 +47,7 @@
deprecated/4,
erl_opts/1,
indent/1,
+ update_code/1,
cleanup_code_path/1,
args_to_tasks/1,
expand_env_variable/3,
@@ -563,6 +564,23 @@ filter_defines([Opt | Rest], Acc) ->
indent(Amount) when erlang:is_integer(Amount) ->
[?ONE_LEVEL_INDENT || _ <- lists:seq(1, Amount)].
+%% Replace code paths with new paths for existing apps and
+%% purge code of the old modules from those apps.
+update_code(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 ->
+ code:add_patha(Path),
+ ok;
+ {ok, Modules} ->
+ code:replace_path(Name, Path),
+ [begin code:purge(M), code:delete(M) end || M <- Modules]
+ end
+ end, Paths).
+
cleanup_code_path(OrigPath) ->
CurrentPath = code:get_path(),
AddedPaths = CurrentPath -- OrigPath,
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_dir_SUITE.erl b/test/rebar_dir_SUITE.erl
new file mode 100644
index 0000000..a3c5052
--- /dev/null
+++ b/test/rebar_dir_SUITE.erl
@@ -0,0 +1,99 @@
+-module(rebar_dir_SUITE).
+
+-export([all/0, init_per_testcase/2, end_per_testcase/2]).
+
+-export([default_src_dirs/1, default_extra_src_dirs/1, default_all_src_dirs/1]).
+-export([src_dirs/1, extra_src_dirs/1, all_src_dirs/1]).
+-export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("kernel/include/file.hrl").
+
+
+all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs,
+ src_dirs, extra_src_dirs, all_src_dirs,
+ profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs].
+
+init_per_testcase(_, Config) ->
+ C = rebar_test_utils:init_rebar_state(Config),
+ AppDir = ?config(apps, C),
+
+ 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]),
+ C.
+
+end_per_testcase(_, _Config) -> ok.
+
+default_src_dirs(Config) ->
+ {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
+
+ [] = rebar_dir:src_dirs(State),
+ ["src"] = rebar_dir:src_dirs(State, ["src"]).
+
+default_extra_src_dirs(Config) ->
+ {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
+
+ [] = rebar_dir:extra_src_dirs(State),
+ ["src"] = rebar_dir:extra_src_dirs(State, ["src"]).
+
+default_all_src_dirs(Config) ->
+ {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
+
+ [] = rebar_dir:all_src_dirs(State),
+ ["src", "test"] = rebar_dir:all_src_dirs(State, ["src"], ["test"]).
+
+src_dirs(Config) ->
+ RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}]}],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
+
+ ["foo", "bar", "baz"] = rebar_dir:src_dirs(State).
+
+extra_src_dirs(Config) ->
+ RebarConfig = [{erl_opts, [{extra_src_dirs, ["foo", "bar", "baz"]}]}],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
+
+ ["foo", "bar", "baz"] = rebar_dir:extra_src_dirs(State).
+
+all_src_dirs(Config) ->
+ RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}, {extra_src_dirs, ["baz", "qux"]}]}],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
+
+ ["foo", "bar", "baz", "qux"] = rebar_dir:all_src_dirs(State).
+
+profile_src_dirs(Config) ->
+ RebarConfig = [
+ {erl_opts, [{src_dirs, ["foo", "bar"]}]},
+ {profiles, [
+ {more, [{erl_opts, [{src_dirs, ["baz", "qux"]}]}]}
+ ]}
+ ],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return),
+
+ R = lists:sort(["foo", "bar", "baz", "qux"]),
+ R = lists:sort(rebar_dir:src_dirs(State)).
+
+profile_extra_src_dirs(Config) ->
+ RebarConfig = [
+ {erl_opts, [{extra_src_dirs, ["foo", "bar"]}]},
+ {profiles, [
+ {more, [{erl_opts, [{extra_src_dirs, ["baz", "qux"]}]}]}
+ ]}
+ ],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return),
+
+ R = lists:sort(["foo", "bar", "baz", "qux"]),
+ R = lists:sort(rebar_dir:extra_src_dirs(State)).
+
+profile_all_src_dirs(Config) ->
+ RebarConfig = [
+ {erl_opts, [{src_dirs, ["foo"]}, {extra_src_dirs, ["bar"]}]},
+ {profiles, [
+ {more, [{erl_opts, [{src_dirs, ["baz"]}, {extra_src_dirs, ["qux"]}]}]}
+ ]}
+ ],
+ {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "more", "compile"], return),
+
+ R = lists:sort(["foo", "bar", "baz", "qux"]),
+ R = lists:sort(rebar_dir:all_src_dirs(State)).
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)))