mirror of
https://github.com/correl/rebar.git
synced 2024-11-14 19:19:30 +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() ->
|
files() ->
|
||||||
[{copy, "../../rebar", "rebar"},
|
[{copy, "../../rebar", "rebar"},
|
||||||
{copy, "src", "src"}].
|
{copy, "rebar.config", "rebar.config"},
|
||||||
|
{copy, "src", "src"},
|
||||||
|
{copy, "include", "include"},
|
||||||
|
{copy, "extra_include", "extra_include"}].
|
||||||
|
|
||||||
run(_Dir) ->
|
run(_Dir) ->
|
||||||
compile_all(ok, ""),
|
compile_all(ok, ""),
|
||||||
check_beams_ok(),
|
check_beams_ok(),
|
||||||
check_beams_untouched(),
|
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.
|
ok.
|
||||||
|
|
||||||
check_beams_ok() ->
|
check_beams_ok() ->
|
||||||
|
@ -49,9 +58,9 @@ check_beams_untouched() ->
|
||||||
Beams = filelib:wildcard("ebin/*.beam"),
|
Beams = filelib:wildcard("ebin/*.beam"),
|
||||||
compile_all_and_assert_mtimes(Beams, fun erlang:'=:='/2).
|
compile_all_and_assert_mtimes(Beams, fun erlang:'=:='/2).
|
||||||
|
|
||||||
modify_and_recompile_ok() ->
|
modify_and_recompile_ok(TouchFile, CheckFile) ->
|
||||||
touch(["src/lisp.erl"]),
|
touch([TouchFile]),
|
||||||
compile_all_and_assert_mtimes(["ebin/lisp.beam"], fun erlang:'<'/2).
|
compile_all_and_assert_mtimes([CheckFile], fun erlang:'<'/2).
|
||||||
|
|
||||||
compile_all_and_assert_mtimes(Beams, Cmp) ->
|
compile_all_and_assert_mtimes(Beams, Cmp) ->
|
||||||
BeamsModifiedBefore = mtime_ns(Beams),
|
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").
|
-define(ERLCINFO_FILE, "erlcinfo").
|
||||||
-type erlc_info_v() :: {digraph:vertex(), term()} | 'false'.
|
-type erlc_info_v() :: {digraph:vertex(), term()} | 'false'.
|
||||||
-type erlc_info_e() :: {digraph:vertex(), digraph:vertex()}.
|
-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,
|
-record(erlcinfo,
|
||||||
{
|
{
|
||||||
vsn = ?ERLCINFO_VSN :: pos_integer(),
|
vsn = ?ERLCINFO_VSN :: pos_integer(),
|
||||||
info = {[], []} :: erlc_info()
|
info = {[], [], []} :: erlc_info()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-ifdef(namespaced_types).
|
-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, [E1|Set]) -> [E1|u_add_element(Elem, Set)];
|
||||||
u_add_element(Elem, []) -> [Elem].
|
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(),
|
-spec needs_compile(file:filename(), file:filename(),
|
||||||
[string()]) -> boolean().
|
[string()]) -> boolean().
|
||||||
needs_compile(Source, Target, Parents) ->
|
needs_compile(Source, Target, Parents) ->
|
||||||
|
@ -403,26 +399,22 @@ erlcinfo_file() ->
|
||||||
|
|
||||||
init_erlcinfo(InclDirs, Erls) ->
|
init_erlcinfo(InclDirs, Erls) ->
|
||||||
G = digraph:new(),
|
G = digraph:new(),
|
||||||
try restore_erlcinfo(G)
|
try restore_erlcinfo(G, InclDirs)
|
||||||
catch
|
catch
|
||||||
_ ->
|
_:_ ->
|
||||||
?WARN("Failed to restore ~s file. Discarding it.~n", [erlcinfo_file()]),
|
?WARN("Failed to restore ~s file. Discarding it.~n", [erlcinfo_file()]),
|
||||||
ok = file:delete(erlcinfo_file())
|
ok = file:delete(erlcinfo_file())
|
||||||
end,
|
end,
|
||||||
%% Get a unique list of dirs based on the source files' locations.
|
Dirs = source_and_include_dirs(InclDirs, Erls),
|
||||||
%% This is used for finding files in sub dirs of the configured
|
Updates = [update_erlcinfo(G, Erl, Dirs) || Erl <- Erls],
|
||||||
%% 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],
|
|
||||||
Modified = lists:member(modified, Updates),
|
Modified = lists:member(modified, Updates),
|
||||||
ok = store_erlcinfo(G, Modified),
|
ok = store_erlcinfo(G, Modified, InclDirs),
|
||||||
G.
|
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) ->
|
update_erlcinfo(G, Source, Dirs) ->
|
||||||
case digraph:vertex(G, Source) of
|
case digraph:vertex(G, Source) of
|
||||||
{_, LastUpdated} ->
|
{_, LastUpdated} ->
|
||||||
|
@ -457,10 +449,13 @@ modify_erlcinfo(G, Source, Dirs) ->
|
||||||
digraph:add_edge(G, Source, Incl)
|
digraph:add_edge(G, Source, Incl)
|
||||||
end, AbsIncls).
|
end, AbsIncls).
|
||||||
|
|
||||||
restore_erlcinfo(G) ->
|
restore_erlcinfo(G, InclDirs) ->
|
||||||
case file:read_file(erlcinfo_file()) of
|
case file:read_file(erlcinfo_file()) of
|
||||||
{ok, Data} ->
|
{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(
|
lists:foreach(
|
||||||
fun({V, LastUpdated}) ->
|
fun({V, LastUpdated}) ->
|
||||||
digraph:add_vertex(G, V, LastUpdated)
|
digraph:add_vertex(G, V, LastUpdated)
|
||||||
|
@ -473,9 +468,9 @@ restore_erlcinfo(G) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
store_erlcinfo(_G, _Modified = false) ->
|
store_erlcinfo(_G, _Modified = false, _InclDirs) ->
|
||||||
ok;
|
ok;
|
||||||
store_erlcinfo(G, _Modified) ->
|
store_erlcinfo(G, _Modified, InclDirs) ->
|
||||||
Vs = lists:map(
|
Vs = lists:map(
|
||||||
fun(V) ->
|
fun(V) ->
|
||||||
digraph:vertex(G, V)
|
digraph:vertex(G, V)
|
||||||
|
@ -490,7 +485,7 @@ store_erlcinfo(G, _Modified) ->
|
||||||
end, Vs),
|
end, Vs),
|
||||||
File = erlcinfo_file(),
|
File = erlcinfo_file(),
|
||||||
ok = filelib:ensure_dir(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).
|
file:write_file(File, Data).
|
||||||
|
|
||||||
%% NOTE: If, for example, one of the entries in Files refers to
|
%% NOTE: If, for example, one of the entries in Files refers to
|
||||||
|
|
Loading…
Reference in a new issue