diff options
| -rw-r--r-- | src/rebar_base_compiler.erl | 43 | ||||
| -rw-r--r-- | src/rebar_erlc_compiler.erl | 17 | ||||
| -rw-r--r-- | src/rebar_file_utils.erl | 20 | ||||
| -rw-r--r-- | test/rebar_file_utils_SUITE.erl | 28 | 
4 files changed, 93 insertions, 15 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 3480cf6..7875449 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  %% =================================================================== @@ -500,7 +499,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 ++ @@ -509,11 +508,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 45da782..667be62 100644 --- a/src/rebar_file_utils.erl +++ b/src/rebar_file_utils.erl @@ -40,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"). @@ -288,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/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index c1f85b3..a44a06d 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/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,10 @@  all() ->      [{group, tmpdir},       {group, reset_dir}, -     path_from_ancestor, canonical_path]. +     path_from_ancestor, +     canonical_path, +     resolve_link, +     split_dirname].  groups() ->      [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]}, @@ -111,3 +116,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")). | 
