summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
12 files changed, 158 insertions, 56 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..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,