mirror of
https://github.com/correl/rebar.git
synced 2024-11-14 11:09:35 +00:00
Assemble Dirs passed to update_erlcinfo in one place
Current separation of part of the logic into include_path obscures the purpose of Dirs (see expand_file_names). Moreover for each particular Erl its source file was included twice in Dirs, which is now corrected. Also InclDirs (specified in erl_opts) as part of erlcinfo since they can affect resulting graph, which needs to be therefore regenerated when InclDirs change. See added test as an example.
This commit is contained in:
parent
df97a49ce7
commit
22acf8db67
6 changed files with 56 additions and 29 deletions
|
@ -32,13 +32,22 @@
|
|||
|
||||
files() ->
|
||||
[{copy, "../../rebar", "rebar"},
|
||||
{copy, "src", "src"}].
|
||||
{copy, "rebar.config", "rebar.config"},
|
||||
{copy, "src", "src"},
|
||||
{copy, "include", "include"},
|
||||
{copy, "extra_include", "extra_include"}].
|
||||
|
||||
run(_Dir) ->
|
||||
compile_all(ok, ""),
|
||||
check_beams_ok(),
|
||||
check_beams_untouched(),
|
||||
modify_and_recompile_ok(),
|
||||
modify_and_recompile_ok("src/lisp.erl", "ebin/lisp.beam"),
|
||||
|
||||
clean_all_ok(),
|
||||
compile_all(error, "-C rebar.config.non-existing"),
|
||||
compile_all(ok, ""),
|
||||
modify_and_recompile_ok("extra_include/extra.hrl", "ebin/java.beam"),
|
||||
|
||||
ok.
|
||||
|
||||
check_beams_ok() ->
|
||||
|
@ -49,9 +58,9 @@ check_beams_untouched() ->
|
|||
Beams = filelib:wildcard("ebin/*.beam"),
|
||||
compile_all_and_assert_mtimes(Beams, fun erlang:'=:='/2).
|
||||
|
||||
modify_and_recompile_ok() ->
|
||||
touch(["src/lisp.erl"]),
|
||||
compile_all_and_assert_mtimes(["ebin/lisp.beam"], fun erlang:'<'/2).
|
||||
modify_and_recompile_ok(TouchFile, CheckFile) ->
|
||||
touch([TouchFile]),
|
||||
compile_all_and_assert_mtimes([CheckFile], fun erlang:'<'/2).
|
||||
|
||||
compile_all_and_assert_mtimes(Beams, Cmp) ->
|
||||
BeamsModifiedBefore = mtime_ns(Beams),
|
||||
|
|
3
inttest/erlc_dep_graph/extra_include/extra.hrl
Normal file
3
inttest/erlc_dep_graph/extra_include/extra.hrl
Normal file
|
@ -0,0 +1,3 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ts=4 sw=4 ft=erlang et
|
||||
-define(CONCISE, impossible).
|
3
inttest/erlc_dep_graph/include/lambda.hrl
Normal file
3
inttest/erlc_dep_graph/include/lambda.hrl
Normal file
|
@ -0,0 +1,3 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ts=4 sw=4 ft=erlang et
|
||||
-define(FUN, fake).
|
6
inttest/erlc_dep_graph/rebar.config
Normal file
6
inttest/erlc_dep_graph/rebar.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ts=4 sw=4 ft=erlang et
|
||||
{erl_opts,
|
||||
[
|
||||
{i, "extra_include"}
|
||||
]}.
|
11
inttest/erlc_dep_graph/src/java.erl
Normal file
11
inttest/erlc_dep_graph/src/java.erl
Normal file
|
@ -0,0 +1,11 @@
|
|||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ts=4 sw=4 ft=erlang et
|
||||
-module(java).
|
||||
|
||||
-export([factory/0]).
|
||||
|
||||
-include("lambda.hrl").
|
||||
-include("extra.hrl").
|
||||
|
||||
factory() ->
|
||||
?FUN.
|
|
@ -40,11 +40,11 @@
|
|||
-define(ERLCINFO_FILE, "erlcinfo").
|
||||
-type erlc_info_v() :: {digraph:vertex(), term()} | 'false'.
|
||||
-type erlc_info_e() :: {digraph:vertex(), digraph:vertex()}.
|
||||
-type erlc_info() :: {list(erlc_info_v()), list(erlc_info_e())}.
|
||||
-type erlc_info() :: {list(erlc_info_v()), list(erlc_info_e()), list(string())}.
|
||||
-record(erlcinfo,
|
||||
{
|
||||
vsn = ?ERLCINFO_VSN :: pos_integer(),
|
||||
info = {[], []} :: erlc_info()
|
||||
info = {[], [], []} :: erlc_info()
|
||||
}).
|
||||
|
||||
-ifdef(namespaced_types).
|
||||
|
@ -387,10 +387,6 @@ u_add_element(Elem, [Elem|_]=Set) -> Set;
|
|||
u_add_element(Elem, [E1|Set]) -> [E1|u_add_element(Elem, Set)];
|
||||
u_add_element(Elem, []) -> [Elem].
|
||||
|
||||
-spec include_path(file:filename(), list()) -> [file:filename(), ...].
|
||||
include_path(Source, InclDirs) ->
|
||||
lists:usort(["include", filename:dirname(Source) |InclDirs]).
|
||||
|
||||
-spec needs_compile(file:filename(), file:filename(),
|
||||
[string()]) -> boolean().
|
||||
needs_compile(Source, Target, Parents) ->
|
||||
|
@ -403,26 +399,22 @@ erlcinfo_file() ->
|
|||
|
||||
init_erlcinfo(InclDirs, Erls) ->
|
||||
G = digraph:new(),
|
||||
try restore_erlcinfo(G)
|
||||
try restore_erlcinfo(G, InclDirs)
|
||||
catch
|
||||
_ ->
|
||||
_:_ ->
|
||||
?WARN("Failed to restore ~s file. Discarding it.~n", [erlcinfo_file()]),
|
||||
ok = file:delete(erlcinfo_file())
|
||||
end,
|
||||
%% Get a unique list of dirs based on the source files' locations.
|
||||
%% This is used for finding files in sub dirs of the configured
|
||||
%% src_dirs. For example, src/sub_dir/foo.erl.
|
||||
Dirs = sets:to_list(lists:foldl(
|
||||
fun(Erl, Acc) ->
|
||||
Dir = filename:dirname(Erl),
|
||||
sets:add_element(Dir, Acc)
|
||||
end, sets:new(), Erls)),
|
||||
Updates = [update_erlcinfo(G, Erl, include_path(Erl, InclDirs) ++ Dirs)
|
||||
|| Erl <- Erls],
|
||||
Dirs = source_and_include_dirs(InclDirs, Erls),
|
||||
Updates = [update_erlcinfo(G, Erl, Dirs) || Erl <- Erls],
|
||||
Modified = lists:member(modified, Updates),
|
||||
ok = store_erlcinfo(G, Modified),
|
||||
ok = store_erlcinfo(G, Modified, InclDirs),
|
||||
G.
|
||||
|
||||
source_and_include_dirs(InclDirs, Erls) ->
|
||||
SourceDirs = lists:map(fun filename:dirname/1, Erls),
|
||||
lists:usort(["include" | InclDirs ++ SourceDirs]).
|
||||
|
||||
update_erlcinfo(G, Source, Dirs) ->
|
||||
case digraph:vertex(G, Source) of
|
||||
{_, LastUpdated} ->
|
||||
|
@ -457,10 +449,13 @@ modify_erlcinfo(G, Source, Dirs) ->
|
|||
digraph:add_edge(G, Source, Incl)
|
||||
end, AbsIncls).
|
||||
|
||||
restore_erlcinfo(G) ->
|
||||
restore_erlcinfo(G, InclDirs) ->
|
||||
case file:read_file(erlcinfo_file()) of
|
||||
{ok, Data} ->
|
||||
#erlcinfo{vsn=?ERLCINFO_VSN, info={Vs, Es}} = binary_to_term(Data),
|
||||
%% Since externally passed InclDirs can influence erlcinfo graph (see
|
||||
%% modify_erlcinfo), we have to check here that they didn't change.
|
||||
#erlcinfo{vsn=?ERLCINFO_VSN, info={Vs, Es, InclDirs}} =
|
||||
binary_to_term(Data),
|
||||
lists:foreach(
|
||||
fun({V, LastUpdated}) ->
|
||||
digraph:add_vertex(G, V, LastUpdated)
|
||||
|
@ -473,9 +468,9 @@ restore_erlcinfo(G) ->
|
|||
ok
|
||||
end.
|
||||
|
||||
store_erlcinfo(_G, _Modified = false) ->
|
||||
store_erlcinfo(_G, _Modified = false, _InclDirs) ->
|
||||
ok;
|
||||
store_erlcinfo(G, _Modified) ->
|
||||
store_erlcinfo(G, _Modified, InclDirs) ->
|
||||
Vs = lists:map(
|
||||
fun(V) ->
|
||||
digraph:vertex(G, V)
|
||||
|
@ -490,7 +485,7 @@ store_erlcinfo(G, _Modified) ->
|
|||
end, Vs),
|
||||
File = erlcinfo_file(),
|
||||
ok = filelib:ensure_dir(File),
|
||||
Data = term_to_binary(#erlcinfo{info={Vs, Es}}, [{compressed, 9}]),
|
||||
Data = term_to_binary(#erlcinfo{info={Vs, Es, InclDirs}}, [{compressed, 9}]),
|
||||
file:write_file(File, Data).
|
||||
|
||||
%% NOTE: If, for example, one of the entries in Files refers to
|
||||
|
|
Loading…
Reference in a new issue