Преглед на файлове

Option to format compiler sources

By default rebar3 displays compiler sources as absolute paths in their
original location, which is under the build dir.

This change introduces an option 'compiler_source_format' to format
sources in two alternative ways:

    relative
    absolute

When either 'relative' or 'absolute' are specified, the file is
resolved to its original location when it is a link. When 'relative'
is specified, the path is displayed relative to the current working
directory. When 'absolute' is specified, the path is absolute.

The default value is 'unchaged' which leaves the compiler source
unchanged.

This is arguably too flexible as I suspect most people would opt for
'relative' all the time - it's the most compact representation of the
file and is sufficient to find the source given cwd. The change
however is meant to introduce the change gradually, preserving
existing behavior and giving users a choice for formats.

In time perhaps the default can be changed to 'relative' - but still
allowing users to revert to the other two options ('absolutel' and
'unchanged') as needed.
pull/1174/head
Garrett Smith преди 9 години
родител
ревизия
da0e2c2295
променени са 4 файла, в които са добавени 87 реда и са изтрити 11 реда
  1. +6
    -6
      src/rebar_base_compiler.erl
  2. +37
    -2
      src/rebar_erlc_compiler.erl
  3. +19
    -1
      src/rebar_file_utils.erl
  4. +25
    -2
      test/rebar_file_utils_SUITE.erl

+ 6
- 6
src/rebar_base_compiler.erl Целия файл

@ -153,12 +153,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]).

+ 37
- 2
src/rebar_erlc_compiler.erl Целия файл

@ -54,6 +54,8 @@
-define(DEFAULT_OUTDIR, "ebin").
-define(RE_PREFIX, "^[^._]").
-type compiler_source_format() :: absolute | relative | unchanged.
-define(DEFAULT_COMPILER_SOURCE_FORMAT, unchanged).
%% ===================================================================
%% Public API
@ -500,7 +502,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 ++
@ -511,9 +513,42 @@ internal_erl_compile(_Opts, Dir, Module, OutDir, ErlOpts) ->
{ok, _Mod, Ws} ->
rebar_base_compiler:ok_tuple(Module, Ws);
{error, Es, Ws} ->
rebar_base_compiler:error_tuple(Module, Es, Ws, AllOpts)
error_tuple(Module, Es, Ws, AllOpts, source_format(Opts))
end.
-spec source_format(rebar_dict()) -> compiler_source_format().
source_format(Opts) ->
case rebar_opts:get(Opts, compiler_source_format,
?DEFAULT_COMPILER_SOURCE_FORMAT) of
V when V == absolute;
V == relative;
V == unchanged -> V;
Other ->
?WARN("Invalid argument ~p for compiler_source_format - "
"assuming ~s~n", [Other, ?DEFAULT_COMPILER_SOURCE_FORMAT]),
?DEFAULT_COMPILER_SOURCE_FORMAT
end.
error_tuple(Module, Es, Ws, Opts, SourceFormat) ->
Cwd = rebar_dir:get_cwd(),
FormattedEs = format_error_sources(Es, SourceFormat, Cwd),
FormattedWs = format_error_sources(Ws, SourceFormat, Cwd),
rebar_base_compiler:error_tuple(Module, FormattedEs, FormattedWs, Opts).
format_error_sources(Es, Format, Cwd) ->
[{format_error_source(Src, Format, Cwd), Desc} || {Src, Desc} <- Es].
format_error_source(Src, absolute, _Cwd) ->
resolve_linked_source(Src);
format_error_source(Src, relative, Cwd) ->
rebar_dir:make_relative_path(resolve_linked_source(Src), Cwd);
format_error_source(Src, unchanged, _Cwd) ->
Src.
resolve_linked_source(Src) ->
{Dir, Base} = rebar_file_utils:split_dirname(Src),
filename:join(rebar_file_utils:resolve_link(Dir), Base).
target_base(OutDir, Source) ->
filename:join(OutDir, filename:basename(Source, ".erl")).

+ 19
- 1
src/rebar_file_utils.erl Целия файл

@ -39,7 +39,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").
@ -273,6 +275,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
%% ===================================================================

+ 25
- 2
test/rebar_file_utils_SUITE.erl Целия файл

@ -12,7 +12,9 @@
reset_empty_dir/1,
reset_dir/1,
path_from_ancestor/1,
canonical_path/1]).
canonical_path/1,
resolve_link/1,
split_dirname/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@ -22,7 +24,9 @@
all() ->
[{group, tmpdir},
{group, reset_dir},
path_from_ancestor, canonical_path].
canonical_path,
resolve_link,
split_dirname].
groups() ->
[{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]},
@ -111,3 +115,22 @@ canonical_path(_Config) ->
?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")),
?assertEqual(filename:nativename(Root ++ "foo/bar"),
rebar_file_utils:canonical_path("/foo/./bar")).
resolve_link(_Config) ->
TmpDir = rebar_file_utils:system_tmpdir(
["rebar_file_utils_SUITE", "resolve_link"]),
Link = filename:join(TmpDir, "link"),
Target = filename:join(TmpDir, "link-target"),
ec_file:remove(TmpDir, [recursive]),
ok = filelib:ensure_dir(Target),
ok = file:write_file(Target, <<>>),
ok = file:make_symlink(Target, Link),
?assertEqual(Target, rebar_file_utils:resolve_link(Link)).
split_dirname(_Config) ->
?assertEqual({".", ""}, rebar_file_utils:split_dirname("")),
?assertEqual({"/", ""}, rebar_file_utils:split_dirname("/")),
?assertEqual({"/", "foo"}, rebar_file_utils:split_dirname("/foo")),
?assertEqual({".", "foo"}, rebar_file_utils:split_dirname("foo")),
?assertEqual({"/foo", "bar"}, rebar_file_utils:split_dirname("/foo/bar")),
?assertEqual({"foo", "bar"}, rebar_file_utils:split_dirname("foo/bar")).

Зареждане…
Отказ
Запис