Browse Source

fix check that modules in .app modules list are from src_dirs

pull/1893/head
Tristan Sloughter 6 years ago
parent
commit
02af35eff6
No known key found for this signature in database GPG Key ID: AAB97DDECCEB8150
5 changed files with 87 additions and 33 deletions
  1. +1
    -0
      rebar.config
  2. +0
    -1
      src/rebar3.erl
  3. +1
    -2
      src/rebar_compiler.erl
  4. +10
    -25
      src/rebar_otp_app.erl
  5. +75
    -5
      src/rebar_utils.erl

+ 1
- 0
rebar.config View File

@ -33,6 +33,7 @@
{erl_opts, [{platform_define, "^[0-9]+", namespaced_types}, {erl_opts, [{platform_define, "^[0-9]+", namespaced_types},
{platform_define, "^(19|2)", rand_only}, {platform_define, "^(19|2)", rand_only},
{platform_define, "^2", unicode_str}, {platform_define, "^2", unicode_str},
{platform_define, "^2", filelib_find_source},
{platform_define, "^(R|1|20)", fun_stacktrace}, {platform_define, "^(R|1|20)", fun_stacktrace},
warnings_as_errors warnings_as_errors
]}. ]}.

+ 0
- 1
src/rebar3.erl View File

@ -411,7 +411,6 @@ test_state(State) ->
ProfileOpts = proplists:get_value(test, Profiles, []), ProfileOpts = proplists:get_value(test, Profiles, []),
ErlOpts = proplists:get_value(erl_opts, ProfileOpts, []), ErlOpts = proplists:get_value(erl_opts, ProfileOpts, []),
TestOpts = safe_define_test_macro(ErlOpts), TestOpts = safe_define_test_macro(ErlOpts),
%% [{erl_opts, TestOpts}].
[{extra_src_dirs, ["test"]}, {erl_opts, TestOpts}]. [{extra_src_dirs, ["test"]}, {erl_opts, TestOpts}].
-spec safe_define_test_macro([any()]) -> [any()] | [{'d',atom()} | any()]. -spec safe_define_test_macro([any()]) -> [any()] | [{'d',atom()} | any()].

+ 1
- 2
src/rebar_compiler.erl View File

@ -24,7 +24,7 @@
ok | {ok, [string()]} | {ok, [string()], [string()]}. ok | {ok, [string()]} | {ok, [string()], [string()]}.
-define(DAG_VSN, 2). -define(DAG_VSN, 2).
-define(DAG_FILE, "erlcinfo").
-define(DAG_FILE, "source.dag").
-type dag_v() :: {digraph:vertex(), term()} | 'false'. -type dag_v() :: {digraph:vertex(), term()} | 'false'.
-type dag_e() :: {digraph:vertex(), digraph:vertex()}. -type dag_e() :: {digraph:vertex(), digraph:vertex()}.
-type dag() :: {list(dag_v()), list(dag_e()), list(string())}. -type dag() :: {list(dag_v()), list(dag_e()), list(string())}.
@ -132,7 +132,6 @@ run_on_extra_src_dirs([Dir | Rest], CompilerMod, AppInfo, Fun) ->
end, end,
run_on_extra_src_dirs(Rest, CompilerMod, AppInfo, Fun). run_on_extra_src_dirs(Rest, CompilerMod, AppInfo, Fun).
%% These functions are here for the ultimate goal of getting rid of %% These functions are here for the ultimate goal of getting rid of
%% rebar_base_compiler. This can't be done because of existing plugins. %% rebar_base_compiler. This can't be done because of existing plugins.

+ 10
- 25
src/rebar_otp_app.erl View File

@ -125,7 +125,7 @@ preprocess(State, AppInfo, AppSrcFile) ->
%% Setup file .app filename and write new contents %% Setup file .app filename and write new contents
EbinDir = rebar_app_info:ebin_dir(AppInfo), EbinDir = rebar_app_info:ebin_dir(AppInfo),
filelib:ensure_dir(filename:join(EbinDir, "dummy.beam")),
rebar_file_utils:ensure_dir(EbinDir),
AppFile = rebar_app_utils:app_src_to_app(OutDir, AppSrcFile), AppFile = rebar_app_utils:app_src_to_app(OutDir, AppSrcFile),
ok = rebar_file_utils:write_file_if_contents_differ(AppFile, Spec, utf8), ok = rebar_file_utils:write_file_if_contents_differ(AppFile, Spec, utf8),
@ -163,32 +163,17 @@ validate_name(AppName, File) ->
ebin_modules(AppInfo, Dir) -> ebin_modules(AppInfo, Dir) ->
Beams = lists:sort(rebar_utils:beams(filename:join(Dir, "ebin"))), Beams = lists:sort(rebar_utils:beams(filename:join(Dir, "ebin"))),
ExtraDirs = extra_dirs(AppInfo),
F = fun(Beam) -> not in_extra_dir(AppInfo, Beam, ExtraDirs) end,
Filtered = lists:filter(F, Beams),
SrcDirs = rebar_dir:src_dirs(rebar_app_info:opts(AppInfo), ["src"]),
FindSourceRules = [{".beam", ".erl",
[{"ebin", SrcDir} || SrcDir <- SrcDirs]}],
Filtered = lists:filter(fun(Beam) ->
rebar_utils:find_source(filename:basename(Beam),
filename:dirname(Beam),
FindSourceRules)
=/= {error, not_found}
end, Beams),
[rebar_utils:beam_to_mod(N) || N <- Filtered]. [rebar_utils:beam_to_mod(N) || N <- Filtered].
extra_dirs(State) ->
Extras = rebar_dir:extra_src_dirs(rebar_app_info:opts(State)),
SrcDirs = rebar_dir:src_dirs(rebar_app_info:opts(State), ["src"]),
%% remove any dirs that are defined in `src_dirs` from `extra_src_dirs`
Extras -- SrcDirs.
in_extra_dir(AppInfo, Beam, Dirs) ->
lists:any(fun(Dir) -> lists:prefix(filename:join([rebar_app_info:out_dir(AppInfo), Dir]),
beam_src(Beam)) end,
Dirs).
beam_src(Beam) ->
case beam_lib:chunks(Beam, [compile_info]) of
{ok, {_mod, Chunks}} ->
CompileInfo = proplists:get_value(compile_info, Chunks, []),
proplists:get_value(source, CompileInfo, []);
{error, beam_lib, Reason} ->
?WARN("Couldn't read debug info from ~p for reason: ~p", [Beam, Reason]),
[]
end.
ensure_registered(AppData) -> ensure_registered(AppData) ->
case lists:keyfind(registered, 1, AppData) of case lists:keyfind(registered, 1, AppData) of
false -> false ->

+ 75
- 5
src/rebar_utils.erl View File

@ -38,8 +38,8 @@
find_files/2, find_files/2,
find_files/3, find_files/3,
find_files_in_dirs/3, find_files_in_dirs/3,
find_source/3,
beam_to_mod/1, beam_to_mod/1,
beam_to_mod/2,
erl_to_mod/1, erl_to_mod/1,
beams/1, beams/1,
find_executable/1, find_executable/1,
@ -678,10 +678,6 @@ sh_loop(Port, Fun, Acc) ->
end end
end. end.
beam_to_mod(Dir, Filename) ->
[Dir | Rest] = filename:split(Filename),
list_to_atom(filename:basename(rebar_string:join(Rest, "."), ".beam")).
beam_to_mod(Filename) -> beam_to_mod(Filename) ->
list_to_atom(filename:basename(Filename, ".beam")). list_to_atom(filename:basename(Filename, ".beam")).
@ -1081,3 +1077,77 @@ version_pad([Major, Minor, Patch]) ->
{list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}; {list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)};
version_pad([Major, Minor, Patch | _]) -> version_pad([Major, Minor, Patch | _]) ->
{list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}. {list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}.
-ifdef(filelib_find_source).
find_source(Filename, Dir, Rules) ->
filelib:find_source(Filename, Dir, Rules).
-else.
%% Looks for a file relative to a given directory
-type find_file_rule() :: {ObjDirSuffix::string(), SrcDirSuffix::string()}.
%% Looks for a source file relative to the object file name and directory
-type find_source_rule() :: {ObjExtension::string(), SrcExtension::string(),
[find_file_rule()]}.
keep_suffix_search_rules(Rules) ->
[T || {_,_,_}=T <- Rules].
-spec find_source(file:filename(), file:filename(), [find_source_rule()]) ->
{ok, file:filename()} | {error, not_found}.
find_source(Filename, Dir, Rules) ->
try_suffix_rules(keep_suffix_search_rules(Rules), Filename, Dir).
try_suffix_rules(Rules, Filename, Dir) ->
Ext = filename:extension(Filename),
try_suffix_rules(Rules, filename:rootname(Filename, Ext), Dir, Ext).
try_suffix_rules([{Ext,Src,Rules}|Rest], Root, Dir, Ext)
when is_list(Src), is_list(Rules) ->
case try_dir_rules(add_local_search(Rules), Root ++ Src, Dir) of
{ok, File} -> {ok, File};
_Other ->
try_suffix_rules(Rest, Root, Dir, Ext)
end;
try_suffix_rules([_|Rest], Root, Dir, Ext) ->
try_suffix_rules(Rest, Root, Dir, Ext);
try_suffix_rules([], _Root, _Dir, _Ext) ->
{error, not_found}.
%% ensuring we check the directory of the object file before any other directory
add_local_search(Rules) ->
Local = {"",""},
[Local] ++ lists:filter(fun (X) -> X =/= Local end, Rules).
try_dir_rules([{From, To}|Rest], Filename, Dir)
when is_list(From), is_list(To) ->
case try_dir_rule(Dir, Filename, From, To) of
{ok, File} -> {ok, File};
error -> try_dir_rules(Rest, Filename, Dir)
end;
try_dir_rules([], _Filename, _Dir) ->
{error, not_found}.
try_dir_rule(Dir, Filename, From, To) ->
case lists:suffix(From, Dir) of
true ->
NewDir = lists:sublist(Dir, 1, length(Dir)-length(From))++To,
Src = filename:join(NewDir, Filename),
case filelib:is_regular(Src) of
true -> {ok, Src};
false -> find_regular_file(filelib:wildcard(Src))
end;
false ->
error
end.
find_regular_file([]) ->
error;
find_regular_file([File|Files]) ->
case filelib:is_regular(File) of
true -> {ok, File};
false -> find_regular_file(Files)
end.
-endif.

Loading…
Cancel
Save