summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar_base_compiler.erl43
-rw-r--r--src/rebar_erlc_compiler.erl17
-rw-r--r--src/rebar_file_utils.erl35
-rw-r--r--src/rebar_prv_common_test.erl25
-rw-r--r--src/rebar_prv_shell.erl32
-rw-r--r--src/rebar_utils.erl14
6 files changed, 123 insertions, 43 deletions
diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl
index 31292af..6b8c7ca 100644
--- a/src/rebar_base_compiler.erl
+++ b/src/rebar_base_compiler.erl
@@ -32,7 +32,11 @@
run/7,
run/8,
ok_tuple/2,
- error_tuple/4]).
+ error_tuple/4,
+ format_error_source/2]).
+
+-define(DEFAULT_COMPILER_SOURCE_FORMAT, relative).
+
%% ===================================================================
%% Public API
@@ -76,6 +80,28 @@ error_tuple(Source, Es, Ws, Opts) ->
{error, format_errors(Source, Es),
format_warnings(Source, Ws, Opts)}.
+format_error_source(Path, Opts) ->
+ Type = case rebar_opts:get(Opts, compiler_source_format,
+ ?DEFAULT_COMPILER_SOURCE_FORMAT) of
+ V when V == absolute; V == relative; V == build ->
+ V;
+ Other ->
+ ?WARN("Invalid argument ~p for compiler_source_format - "
+ "assuming ~s~n", [Other, ?DEFAULT_COMPILER_SOURCE_FORMAT]),
+ ?DEFAULT_COMPILER_SOURCE_FORMAT
+ end,
+ case Type of
+ absolute -> resolve_linked_source(Path);
+ build -> Path;
+ relative ->
+ Cwd = rebar_dir:get_cwd(),
+ rebar_dir:make_relative_path(resolve_linked_source(Path), Cwd)
+ end.
+
+resolve_linked_source(Src) ->
+ {Dir, Base} = rebar_file_utils:split_dirname(Src),
+ filename:join(rebar_file_utils:resolve_link(Dir), Base).
+
%% ===================================================================
%% Internal functions
%% ===================================================================
@@ -114,7 +140,8 @@ compile_each([Source | Rest], Config, CompileFn) ->
skipped ->
?DEBUG("~sSkipped ~s", [rebar_utils:indent(1), filename:basename(Source)]);
Error ->
- ?ERROR("Compiling ~s failed", [Source]),
+ NewSource = format_error_source(Source, Config),
+ ?ERROR("Compiling ~s failed", [NewSource]),
maybe_report(Error),
?DEBUG("Compilation failed: ~p", [Error]),
?FAIL
@@ -153,12 +180,12 @@ format_errors(_MainSource, Extra, Errors) ->
end
|| {Source, Descs} <- Errors].
-format_error(AbsSource, Extra, {{Line, Column}, Mod, Desc}) ->
+format_error(Source, Extra, {{Line, Column}, Mod, Desc}) ->
ErrorDesc = Mod:format_error(Desc),
- ?FMT("~s:~w:~w: ~s~s~n", [AbsSource, Line, Column, Extra, ErrorDesc]);
-format_error(AbsSource, Extra, {Line, Mod, Desc}) ->
+ ?FMT("~s:~w:~w: ~s~s~n", [Source, Line, Column, Extra, ErrorDesc]);
+format_error(Source, Extra, {Line, Mod, Desc}) ->
ErrorDesc = Mod:format_error(Desc),
- ?FMT("~s:~w: ~s~s~n", [AbsSource, Line, Extra, ErrorDesc]);
-format_error(AbsSource, Extra, {Mod, Desc}) ->
+ ?FMT("~s:~w: ~s~s~n", [Source, Line, Extra, ErrorDesc]);
+format_error(Source, Extra, {Mod, Desc}) ->
ErrorDesc = Mod:format_error(Desc),
- ?FMT("~s: ~s~s~n", [AbsSource, Extra, ErrorDesc]).
+ ?FMT("~s: ~s~s~n", [Source, Extra, ErrorDesc]).
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 2a9f310..bdd1868 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -54,7 +54,6 @@
-define(DEFAULT_OUTDIR, "ebin").
-define(RE_PREFIX, "^[^._]").
-
%% ===================================================================
%% Public API
%% ===================================================================
@@ -507,7 +506,7 @@ expand_file_names(Files, Dirs) ->
-spec internal_erl_compile(rebar_dict(), file:filename(), file:filename(),
file:filename(), list()) -> ok | {ok, any()} | {error, any(), any()}.
-internal_erl_compile(_Opts, Dir, Module, OutDir, ErlOpts) ->
+internal_erl_compile(Opts, Dir, Module, OutDir, ErlOpts) ->
Target = target_base(OutDir, Module) ++ ".beam",
ok = filelib:ensure_dir(Target),
AllOpts = [{outdir, filename:dirname(Target)}] ++ ErlOpts ++
@@ -516,11 +515,21 @@ internal_erl_compile(_Opts, Dir, Module, OutDir, ErlOpts) ->
{ok, _Mod} ->
ok;
{ok, _Mod, Ws} ->
- rebar_base_compiler:ok_tuple(Module, Ws);
+ FormattedWs = format_error_sources(Ws, Opts),
+ rebar_base_compiler:ok_tuple(Module, FormattedWs);
{error, Es, Ws} ->
- rebar_base_compiler:error_tuple(Module, Es, Ws, AllOpts)
+ error_tuple(Module, Es, Ws, AllOpts, Opts)
end.
+error_tuple(Module, Es, Ws, AllOpts, Opts) ->
+ FormattedEs = format_error_sources(Es, Opts),
+ FormattedWs = format_error_sources(Ws, Opts),
+ rebar_base_compiler:error_tuple(Module, FormattedEs, FormattedWs, AllOpts).
+
+format_error_sources(Es, Opts) ->
+ [{rebar_base_compiler:format_error_source(Src, Opts), Desc}
+ || {Src, Desc} <- Es].
+
target_base(OutDir, Source) ->
filename:join(OutDir, filename:basename(Source, ".erl")).
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl
index 0f84520..667be62 100644
--- a/src/rebar_file_utils.erl
+++ b/src/rebar_file_utils.erl
@@ -27,6 +27,7 @@
-module(rebar_file_utils).
-export([try_consult/1,
+ consult_config/2,
format_error/1,
symlink_or_copy/2,
rm_rf/1,
@@ -39,7 +40,9 @@
reset_dir/1,
touch/1,
path_from_ancestor/2,
- canonical_path/1]).
+ canonical_path/1,
+ resolve_link/1,
+ split_dirname/1]).
-include("rebar.hrl").
@@ -61,6 +64,20 @@ try_consult(File) ->
throw(?PRV_ERROR({bad_term_file, File, Reason}))
end.
+-spec consult_config(rebar_state:t(), string()) -> [[tuple()]].
+consult_config(State, Filename) ->
+ Fullpath = filename:join(rebar_dir:root_dir(State), Filename),
+ ?DEBUG("Loading configuration from ~p", [Fullpath]),
+ Config = case try_consult(Fullpath) of
+ [T] -> T;
+ [] -> []
+ end,
+ SubConfigs = [consult_config(State, Entry ++ ".config") ||
+ Entry <- Config, is_list(Entry)
+ ],
+
+ [Config | lists:merge(SubConfigs)].
+
format_error({bad_term_file, AppFile, Reason}) ->
io_lib:format("Error reading file ~s: ~s", [AppFile, file:format_error(Reason)]).
@@ -273,6 +290,22 @@ canonical_path([_|Acc], [".."|Rest]) -> canonical_path(Acc, Rest);
canonical_path([], [".."|Rest]) -> canonical_path([], Rest);
canonical_path(Acc, [Component|Rest]) -> canonical_path([Component|Acc], Rest).
+%% returns canonical target of path if path is a link, otherwise returns path
+-spec resolve_link(string()) -> string().
+
+resolve_link(Path) ->
+ case file:read_link(Path) of
+ {ok, Target} ->
+ canonical_path(filename:absname(Target, filename:dirname(Path)));
+ {error, _} -> Path
+ end.
+
+%% splits a path into dirname and basename
+-spec split_dirname(string()) -> {string(), string()}.
+
+split_dirname(Path) ->
+ {filename:dirname(Path), filename:basename(Path)}.
+
%% ===================================================================
%% Internal functions
%% ===================================================================
diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl
index 5712fbf..fbd0e89 100644
--- a/src/rebar_prv_common_test.erl
+++ b/src/rebar_prv_common_test.erl
@@ -116,6 +116,7 @@ prepare_tests(State) ->
%% rebar.config test options
CfgOpts = cfgopts(State),
ProjectApps = rebar_state:project_apps(State),
+
%% prioritize tests to run first trying any command line specified
%% tests falling back to tests specified in the config file finally
%% running a default set if no other tests are present
@@ -215,6 +216,14 @@ add_hooks(Opts, State) ->
select_tests(_, _, {error, _} = Error, _) -> Error;
select_tests(_, _, _, {error, _} = Error) -> Error;
select_tests(State, ProjectApps, CmdOpts, CfgOpts) ->
+ %% set application env if sys_config argument is provided
+ SysConfigs = sys_config_list(CmdOpts, CfgOpts),
+ Configs = lists:flatmap(fun(Filename) ->
+ rebar_file_utils:consult_config(State, Filename)
+ end, SysConfigs),
+ [application:load(Application) || Config <- SysConfigs, {Application, _} <- Config],
+ rebar_utils:reread_config(Configs),
+
Merged = lists:ukeymerge(1,
lists:ukeysort(1, CmdOpts),
lists:ukeysort(1, CfgOpts)),
@@ -229,6 +238,17 @@ select_tests(State, ProjectApps, CmdOpts, CfgOpts) ->
end,
discover_tests(State, ProjectApps, Opts).
+sys_config_list(CmdOpts, CfgOpts) ->
+ CmdSysConfigs = split_string(proplists:get_value(sys_config, CmdOpts, "")),
+ case proplists:get_value(sys_config, CfgOpts, []) of
+ [H | _]=Configs when is_list(H) ->
+ Configs ++ CmdSysConfigs;
+ [] ->
+ CmdSysConfigs;
+ Configs ->
+ [Configs | CmdSysConfigs]
+ end.
+
discover_tests(State, ProjectApps, Opts) ->
case {proplists:get_value(suite, Opts), proplists:get_value(dir, Opts)} of
%% no dirs or suites defined, try using `$APP/test` and `$ROOT/test`
@@ -647,7 +667,8 @@ ct_opts(_State) ->
{verbose, $v, "verbose", boolean, help(verbose)},
{name, undefined, "name", atom, help(name)},
{sname, undefined, "sname", atom, help(sname)},
- {setcookie, undefined, "setcookie", atom, help(setcookie)}
+ {setcookie, undefined, "setcookie", atom, help(setcookie)},
+ {sys_config, undefined, "sys_config", string, help(sys_config)} %% comma-seperated list
].
help(dir) ->
@@ -662,6 +683,8 @@ help(label) ->
"Test label";
help(config) ->
"List of config files";
+help(sys_config) ->
+ "List of application config files";
help(allow_user_terms) ->
"Allow user defined config values in config files";
help(logdir) ->
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl
index a5457ad..2e6c296 100644
--- a/src/rebar_prv_shell.erl
+++ b/src/rebar_prv_shell.erl
@@ -111,7 +111,7 @@ shell(State) ->
%% Hack to fool the init process into thinking we have stopped and the normal
%% node start process can go on. Without it, init:get_status() always return
%% '{starting, started}' instead of '{started, started}'
- init ! {'EXIT', self(), normal},
+ init ! {'EXIT', self(), normal},
gen_server:enter_loop(rebar_agent, [], GenState, {local, rebar_agent}, hibernate).
info() ->
@@ -332,16 +332,7 @@ reread_config(State) ->
no_config ->
ok;
ConfigList ->
- try
- [application:set_env(Application, Key, Val)
- || Config <- ConfigList,
- {Application, Items} <- Config,
- {Key, Val} <- Items]
- catch _:_ ->
- ?ERROR("The configuration file submitted could not be read "
- "and will be ignored.", [])
- end,
- ok
+ rebar_utils:reread_config(ConfigList)
end.
boot_apps(Apps) ->
@@ -406,7 +397,7 @@ find_config(State) ->
no_value ->
no_config;
Filename when is_list(Filename) ->
- consult_config(State, Filename)
+ rebar_file_utils:consult_config(State, Filename)
end.
-spec first_value([Fun], State) -> no_value | Value when
@@ -414,7 +405,7 @@ find_config(State) ->
State :: rebar_state:t(),
Fun :: fun ((State) -> no_value | Value).
first_value([], _) -> no_value;
-first_value([Fun | Rest], State) ->
+first_value([Fun | Rest], State) ->
case Fun(State) of
no_value ->
first_value(Rest, State);
@@ -445,18 +436,3 @@ find_config_rebar(State) ->
find_config_relx(State) ->
debug_get_value(sys_config, rebar_state:get(State, relx, []), no_value,
"Found config from relx.").
-
--spec consult_config(rebar_state:t(), string()) -> [[tuple()]].
-consult_config(State, Filename) ->
- Fullpath = filename:join(rebar_dir:root_dir(State), Filename),
- ?DEBUG("Loading configuration from ~p", [Fullpath]),
- Config = case rebar_file_utils:try_consult(Fullpath) of
- [T] -> T;
- [] -> []
- end,
- SubConfigs = [consult_config(State, Entry ++ ".config") ||
- Entry <- Config, is_list(Entry)
- ],
-
- [Config | lists:merge(SubConfigs)].
-
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index ce6996c..aa9e268 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -69,7 +69,8 @@
check_blacklisted_otp_versions/1,
info_useless/2,
list_dir/1,
- user_agent/0]).
+ user_agent/0,
+ reread_config/1]).
%% for internal use only
-export([otp_release/0]).
@@ -412,6 +413,17 @@ user_agent() ->
{ok, Vsn} = application:get_key(rebar, vsn),
?FMT("Rebar/~s (OTP/~s)", [Vsn, otp_release()]).
+reread_config(ConfigList) ->
+ try
+ [application:set_env(Application, Key, Val)
+ || Config <- ConfigList,
+ {Application, Items} <- Config,
+ {Key, Val} <- Items]
+ catch _:_ ->
+ ?ERROR("The configuration file submitted could not be read "
+ "and will be ignored.", [])
+ end.
+
%% ====================================================================
%% Internal functions
%% ====================================================================