Add support for custom xref queries

The custom queries are configured in rebar.config via the tuple
{xref_queries, [{query(), query_result()},...]}.  The implementation
passes the query() string to xref:q and compares the return value with
query_result(). It will result in an error if they do not match.

The following configuration, for example, is the same as running the
xref check undefined_function_calls. It additionally filters
ejabberd_logger:*_msg/4 from the result as these functions are generated
on execution by ejabberd and not available at compile time.

{xref_queries, [{"(XC - UC) || (XU - X - B -
                 (\"ejabberd_logger\":\".*_msg\"/\"4\"))",[]}]}.

This patch also modifies the build process of this package by running a
custom query instead of doing a diff against a static xref_warning file.
This commit is contained in:
Amit Kapoor 2012-04-02 08:01:39 -07:00 committed by Tuncer Ayaz
parent 26e1252250
commit 0191806f92
5 changed files with 35 additions and 9 deletions

View file

@ -11,11 +11,8 @@ debug:
check: debug xref dialyzer
xref: xref_warnings
@diff -U0 xref_reference xref_warnings
xref_warnings:
-@./rebar xref > xref_warnings
xref:
-@./rebar xref
dialyzer: dialyzer_warnings
@diff -U0 dialyzer_reference dialyzer_warnings

View file

@ -3,4 +3,8 @@
{app_bin, ["priv/rebar"]}.
{erl_opts, [warnings_as_errors]}.
{xref_checks, [undefined_function_calls]}.
{xref_checks, []}.
{xref_queries,
[{"(XC - UC) || (XU - X - B
- (\"escript\":\"foldl\"/\"3\")
- (\"abnfc\":\"file\"/\"2\"))",[]}]}.

View file

@ -151,5 +151,15 @@
%% == xref ==
{xref_warnings, false}.
%% xref checks to run
{xref_checks, [exports_not_used, undefined_function_calls]}.
%% Optional custom xref queries (xref manual has details) specified as
%% {xref_queries, [{query_string(), expected_query_result()},...]}
%% The following for example removes all references to ejabberd:*_msg/4
%% functions from undefined external function calls as those are in a
%% generated module
{xref_queries,
[{"(XC - UC) || (XU - X - B"
" - (\"ejabberd_logger\":\".*_msg\"/\"4\"))",[]}]}.

View file

@ -77,13 +77,19 @@ xref(Config, _) ->
false ->
true
end,
%% Run custom queries
QueryChecks = rebar_config:get(Config, xref_queries, []),
QueryNoWarn = lists:all(fun check_query/1, QueryChecks),
%% Restore the original code path
true = code:set_path(OrigPath),
%% Stop xref
stopped = xref:stop(xref),
case lists:all(fun(NoWarn) -> NoWarn end, [ExportsNoWarn, UndefNoWarn]) of
case lists:all(fun(NoWarn) -> NoWarn end,
[ExportsNoWarn, UndefNoWarn, QueryNoWarn]) of
true ->
ok;
false ->
@ -115,6 +121,17 @@ check_undefined_function_calls() ->
end, UndefinedCalls),
UndefinedCalls =:= [].
check_query({Query, Value}) ->
{ok, Answer} = xref:q(xref, Query),
case Answer =:= Value of
false ->
?CONSOLE("Query ~s~n answer ~p~n did not match ~p~n",
[Query, Answer, Value]),
false;
_ ->
true
end.
code_path() ->
[P || P <- code:get_path(),
filelib:is_dir(P)] ++ [filename:join(rebar_utils:get_cwd(), "ebin")].

View file

@ -1,2 +0,0 @@
==> rebar (xref)
src/rebar_utils.erl:148: Warning escript_foldl/3 calls undefined function escript:foldl/3