From da0e2c22959c976420b60def760b348aa200d6e2 Mon Sep 17 00:00:00 2001 From: Garrett Smith Date: Mon, 2 May 2016 16:03:01 -0500 Subject: 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. --- src/rebar_base_compiler.erl | 12 ++++++------ src/rebar_erlc_compiler.erl | 39 +++++++++++++++++++++++++++++++++++++-- src/rebar_file_utils.erl | 20 +++++++++++++++++++- 3 files changed, 62 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 31292af..2f67f25 100644 --- a/src/rebar_base_compiler.erl +++ b/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]). diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 3480cf6..4955357 100644 --- a/src/rebar_erlc_compiler.erl +++ b/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")). diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl index 0f84520..19cc94d 100644 --- a/src/rebar_file_utils.erl +++ b/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 %% =================================================================== -- cgit v1.1 From 76f30b18845039bcd749f0f99164924e04fa1e1c Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 6 Jun 2016 19:48:08 -0400 Subject: Rename 'unchanged' option to 'build' This will allow us to eventually change the default type without it looking ridiculous. --- src/rebar_erlc_compiler.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 4955357..a2eb2e2 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -54,8 +54,8 @@ -define(DEFAULT_OUTDIR, "ebin"). -define(RE_PREFIX, "^[^._]"). --type compiler_source_format() :: absolute | relative | unchanged. --define(DEFAULT_COMPILER_SOURCE_FORMAT, unchanged). +-type compiler_source_format() :: absolute | relative | build. +-define(DEFAULT_COMPILER_SOURCE_FORMAT, build). %% =================================================================== %% Public API @@ -522,7 +522,7 @@ source_format(Opts) -> ?DEFAULT_COMPILER_SOURCE_FORMAT) of V when V == absolute; V == relative; - V == unchanged -> V; + V == build -> V; Other -> ?WARN("Invalid argument ~p for compiler_source_format - " "assuming ~s~n", [Other, ?DEFAULT_COMPILER_SOURCE_FORMAT]), @@ -542,7 +542,7 @@ 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) -> +format_error_source(Src, build, _Cwd) -> Src. resolve_linked_source(Src) -> -- cgit v1.1 From 1875eadd9a752464babb96a1b9711a5b6d754855 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 9 Jun 2016 21:01:55 -0400 Subject: Fix alternative path printing, default is relative This required moving the reporting functions to rebar_base_compiler but since this was already done for error_tuple, this seems to make sense. Paths are also reformatted for warnings in erlc files. --- src/rebar_base_compiler.erl | 31 ++++++++++++++++++++++++++++-- src/rebar_erlc_compiler.erl | 46 ++++++++++----------------------------------- 2 files changed, 39 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index 2f67f25..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 diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index a2eb2e2..7875449 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -54,9 +54,6 @@ -define(DEFAULT_OUTDIR, "ebin"). -define(RE_PREFIX, "^[^._]"). --type compiler_source_format() :: absolute | relative | build. --define(DEFAULT_COMPILER_SOURCE_FORMAT, build). - %% =================================================================== %% Public API %% =================================================================== @@ -511,43 +508,20 @@ 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} -> - error_tuple(Module, Es, Ws, AllOpts, source_format(Opts)) + error_tuple(Module, Es, Ws, AllOpts, 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 == build -> 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, AllOpts, Opts) -> + FormattedEs = format_error_sources(Es, Opts), + FormattedWs = format_error_sources(Ws, Opts), + rebar_base_compiler:error_tuple(Module, FormattedEs, FormattedWs, AllOpts). -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, build, _Cwd) -> - Src. - -resolve_linked_source(Src) -> - {Dir, Base} = rebar_file_utils:split_dirname(Src), - filename:join(rebar_file_utils:resolve_link(Dir), Base). +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")). -- cgit v1.1