From 0191806f9282c6ce1da0f1a2c0672406de15ed24 Mon Sep 17 00:00:00 2001 From: Amit Kapoor Date: Mon, 2 Apr 2012 08:01:39 -0700 Subject: [PATCH] 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. --- Makefile | 7 ++----- rebar.config | 6 +++++- rebar.config.sample | 10 ++++++++++ src/rebar_xref.erl | 19 ++++++++++++++++++- xref_reference | 2 -- 5 files changed, 35 insertions(+), 9 deletions(-) delete mode 100644 xref_reference diff --git a/Makefile b/Makefile index e521f08..a5cdf74 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/rebar.config b/rebar.config index 815636b..869303e 100644 --- a/rebar.config +++ b/rebar.config @@ -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\"))",[]}]}. diff --git a/rebar.config.sample b/rebar.config.sample index 0ffa884..b83ea87 100644 --- a/rebar.config.sample +++ b/rebar.config.sample @@ -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\"))",[]}]}. diff --git a/src/rebar_xref.erl b/src/rebar_xref.erl index 84d422e..cfdfb8c 100644 --- a/src/rebar_xref.erl +++ b/src/rebar_xref.erl @@ -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")]. diff --git a/xref_reference b/xref_reference deleted file mode 100644 index 77a49fb..0000000 --- a/xref_reference +++ /dev/null @@ -1,2 +0,0 @@ -==> rebar (xref) -src/rebar_utils.erl:148: Warning escript_foldl/3 calls undefined function escript:foldl/3