Universally support apps=/skip_apps=

This commit is contained in:
Tuncer Ayaz 2011-12-12 19:08:40 +01:00
parent a5e39c2c54
commit 8c89a388bf
7 changed files with 168 additions and 158 deletions

View file

@ -11,8 +11,8 @@ _rebar()
cmdsnvars="check-deps clean compile create create-app create-node \ cmdsnvars="check-deps clean compile create create-app create-node \
ct doc delete-deps eunit get-deps generate generate-upgrade \ ct doc delete-deps eunit get-deps generate generate-upgrade \
help list-deps list-templates update-deps version xref overlay \ help list-deps list-templates update-deps version xref overlay \
case= force=1 jobs= suite= verbose=1 appid= previous_release= \ apps= case= force=1 jobs= suite= verbose=1 appid= previous_release= \
root_dir= skip_deps=true skip_app= template= template_dir=" root_dir= skip_deps=true skip_apps= template= template_dir="
if [[ ${cur} == --* ]] ; then if [[ ${cur} == --* ]] ; then
COMPREPLY=( $(compgen -W "${lopts}" -- ${cur}) ) COMPREPLY=( $(compgen -W "${lopts}" -- ${cur}) )

View file

@ -32,7 +32,7 @@
app_name/1, app_name/1,
app_applications/1, app_applications/1,
app_vsn/1, app_vsn/1,
is_skipped_app/0]). is_skipped_app/1]).
-export([load_app_file/1]). % TEMPORARY -export([load_app_file/1]). % TEMPORARY
@ -105,40 +105,26 @@ app_vsn(AppFile) ->
[AppFile, Reason]) [AppFile, Reason])
end. end.
%% is_skipped_app(AppFile) ->
%% Return: true, if we are in the context of a 'Skipped App', else: false ThisApp = app_name(AppFile),
%% (Example: rebar xref skip_app=mochiweb,webmachine) %% Check for apps global parameter; this is a comma-delimited list
is_skipped_app() -> %% of apps on which we want to run commands
case rebar_config:get_global(skip_app, undefined) of case get_apps() of
undefined -> undefined ->
%% no skip list %% No apps parameter specified, check the skip_apps list..
false; case get_skip_apps() of
undefined ->
SkipApps -> %% No skip_apps list, run everything..
case string:tokens(SkipApps, ",") of
[] ->
%% no tokens
false; false;
SkipApps ->
SkipAppsTokens -> TargetApps = [list_to_atom(A) ||
A <- string:tokens(SkipApps, ",")],
%% Where we are at the moment is_skipped_app(ThisApp, TargetApps)
Cwd = rebar_utils:get_cwd(), end;
Apps ->
%% Return true if app should be skipped %% run only selected apps
SkipPred = fun(App) -> TargetApps = [list_to_atom(A) || A <- string:tokens(Apps, ",")],
case re:run(Cwd, App) of is_selected_app(ThisApp, TargetApps)
{match,_} -> true;
_ -> false
end
end,
%% Check if 'we' are among the skipped apps.
lists:foldl(fun(SkippedApp, Bool) ->
SkipPred(SkippedApp) or Bool
end, false, SkipAppsTokens)
end
end. end.
%% =================================================================== %% ===================================================================
@ -224,3 +210,47 @@ vcs_vsn_cmd(Version) -> {unknown, Version}.
vcs_vsn_invoke(Cmd, Dir) -> vcs_vsn_invoke(Cmd, Dir) ->
{ok, VsnString} = rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, false}]), {ok, VsnString} = rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, false}]),
string:strip(VsnString, right, $\n). string:strip(VsnString, right, $\n).
%% apps= for selecting apps
is_selected_app(ThisApp, TargetApps) ->
case lists:member(ThisApp, TargetApps) of
false ->
{true, ThisApp};
true ->
false
end.
%% skip_apps= for filtering apps
is_skipped_app(ThisApp, TargetApps) ->
case lists:member(ThisApp, TargetApps) of
false ->
false;
true ->
{true, ThisApp}
end.
get_apps() ->
get_global_cs_opt(app, apps).
get_skip_apps() ->
get_global_cs_opt(skip_app, skip_apps).
get_global_cs_opt(Old, New) ->
Apps = rebar_config:get_global(New, undefined),
case rebar_config:get_global(Old, undefined) of
undefined ->
case Apps of
undefined ->
undefined;
Apps ->
Apps
end;
App ->
rebar_utils:deprecated(Old, Old, New, "soon"),
case Apps of
undefined ->
App;
Apps ->
string:join([App, Apps], ",")
end
end.

View file

@ -114,81 +114,111 @@ process_dir(Dir, ParentConfig, Command, DirSet) ->
%% CWD to see if it's a fit -- if it is, use that set of modules %% CWD to see if it's a fit -- if it is, use that set of modules
%% to process this dir. %% to process this dir.
{ok, AvailModuleSets} = application:get_env(rebar, modules), {ok, AvailModuleSets} = application:get_env(rebar, modules),
{DirModules, ModuleSetFile} = choose_module_set(AvailModuleSets, ModuleSet = choose_module_set(AvailModuleSets, Dir),
Dir), {_DirModules, ModuleSetFile} = ModuleSet,
%% Get the list of modules for "any dir". This is a catch-all list case lists:reverse(ModuleSetFile) of
%% of modules that are processed in addition to modules associated "ppa." ++ _ ->
%% with this directory type. These any_dir modules are processed %% .app file
%% FIRST. maybe_process_dir0(ModuleSetFile, ModuleSet, Config,
{ok, AnyDirModules} = application:get_env(rebar, any_dir_modules), CurrentCodePath, Dir,
Command, DirSet);
"crs.ppa." ++ _ ->
%% .app.src file
maybe_process_dir0(ModuleSetFile, ModuleSet, Config,
CurrentCodePath, Dir,
Command, DirSet);
_ ->
process_dir0(Dir, Command, DirSet, Config,
CurrentCodePath, ModuleSet)
end
end.
Modules = AnyDirModules ++ DirModules, maybe_process_dir0(AppFile, ModuleSet, Config, CurrentCodePath,
Dir, Command, DirSet) ->
case rebar_app_utils:is_skipped_app(AppFile) of
{true, SkippedApp} ->
?DEBUG("Skipping app: ~p~n", [SkippedApp]),
increment_operations(),
DirSet;
false ->
process_dir0(Dir, Command, DirSet, Config,
CurrentCodePath, ModuleSet)
end.
%% Invoke 'preprocess' on the modules -- this yields a list of other process_dir0(Dir, Command, DirSet, Config, CurrentCodePath,
%% directories that should be processed _before_ the current one. {DirModules, ModuleSetFile}) ->
Predirs = acc_modules(Modules, preprocess, Config, ModuleSetFile), %% Get the list of modules for "any dir". This is a catch-all list
%% of modules that are processed in addition to modules associated
%% with this directory type. These any_dir modules are processed
%% FIRST.
{ok, AnyDirModules} = application:get_env(rebar, any_dir_modules),
%% Get the list of plug-in modules from rebar.config. These Modules = AnyDirModules ++ DirModules,
%% modules may participate in preprocess and postprocess.
{ok, PluginModules} = plugin_modules(Config),
PluginPredirs = acc_modules(PluginModules, preprocess, %% Invoke 'preprocess' on the modules -- this yields a list of other
Config, ModuleSetFile), %% directories that should be processed _before_ the current one.
Predirs = acc_modules(Modules, preprocess, Config, ModuleSetFile),
AllPredirs = Predirs ++ PluginPredirs, %% Get the list of plug-in modules from rebar.config. These
%% modules may participate in preprocess and postprocess.
{ok, PluginModules} = plugin_modules(Config),
?DEBUG("Predirs: ~p\n", [AllPredirs]), PluginPredirs = acc_modules(PluginModules, preprocess,
DirSet2 = process_each(AllPredirs, Command, Config,
ModuleSetFile, DirSet),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
ok = file:set_cwd(Dir),
%% Check that this directory is not on the skip list
case is_skip_dir(Dir) of
true ->
%% Do not execute the command on the directory, as some
%% module as requested a skip on it.
?INFO("Skipping ~s in ~s\n", [Command, Dir]);
false ->
%% Execute any before_command plugins on this directory
execute_pre(Command, PluginModules,
Config, ModuleSetFile), Config, ModuleSetFile),
%% Execute the current command on this directory AllPredirs = Predirs ++ PluginPredirs,
execute(Command, Modules ++ PluginModules,
Config, ModuleSetFile),
%% Execute any after_command plugins on this directory ?DEBUG("Predirs: ~p\n", [AllPredirs]),
execute_post(Command, PluginModules, DirSet2 = process_each(AllPredirs, Command, Config,
Config, ModuleSetFile) ModuleSetFile, DirSet),
end,
%% Mark the current directory as processed %% Make sure the CWD is reset properly; processing the dirs may have
DirSet3 = sets:add_element(Dir, DirSet2), %% caused it to change
ok = file:set_cwd(Dir),
%% Invoke 'postprocess' on the modules. This yields a list of other %% Check that this directory is not on the skip list
%% directories that should be processed _after_ the current one. case is_skip_dir(Dir) of
Postdirs = acc_modules(Modules ++ PluginModules, postprocess, true ->
Config, ModuleSetFile), %% Do not execute the command on the directory, as some
?DEBUG("Postdirs: ~p\n", [Postdirs]), %% module as requested a skip on it.
DirSet4 = process_each(Postdirs, Command, Config, ?INFO("Skipping ~s in ~s\n", [Command, Dir]);
ModuleSetFile, DirSet3),
%% Make sure the CWD is reset properly; processing the dirs may have false ->
%% caused it to change %% Execute any before_command plugins on this directory
ok = file:set_cwd(Dir), execute_pre(Command, PluginModules,
Config, ModuleSetFile),
%% Once we're all done processing, reset the code path to whatever %% Execute the current command on this directory
%% the parent initialized it to execute(Command, Modules ++ PluginModules,
restore_code_path(CurrentCodePath), Config, ModuleSetFile),
%% Return the updated dirset as our result %% Execute any after_command plugins on this directory
DirSet4 execute_post(Command, PluginModules,
end. Config, ModuleSetFile)
end,
%% Mark the current directory as processed
DirSet3 = sets:add_element(Dir, DirSet2),
%% Invoke 'postprocess' on the modules. This yields a list of other
%% directories that should be processed _after_ the current one.
Postdirs = acc_modules(Modules ++ PluginModules, postprocess,
Config, ModuleSetFile),
?DEBUG("Postdirs: ~p\n", [Postdirs]),
DirSet4 = process_each(Postdirs, Command, Config,
ModuleSetFile, DirSet3),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
ok = file:set_cwd(Dir),
%% Once we're all done processing, reset the code path to whatever
%% the parent initialized it to
restore_code_path(CurrentCodePath),
%% Return the updated dirset as our result
DirSet4.
maybe_load_local_config(Dir, ParentConfig) -> maybe_load_local_config(Dir, ParentConfig) ->
%% We need to ensure we don't overwrite custom %% We need to ensure we don't overwrite custom
@ -274,9 +304,7 @@ execute(Command, Modules, Config, ModuleFile) ->
Dir = rebar_utils:get_cwd(), Dir = rebar_utils:get_cwd(),
?CONSOLE("==> ~s (~s)\n", [filename:basename(Dir), Command]), ?CONSOLE("==> ~s (~s)\n", [filename:basename(Dir), Command]),
%% Increment the count of operations, since some module increment_operations(),
%% responds to this command
erlang:put(operations, erlang:get(operations) + 1),
%% Check for and get command specific environments %% Check for and get command specific environments
Env = setup_envs(Config, Modules), Env = setup_envs(Config, Modules),
@ -300,6 +328,11 @@ execute(Command, Modules, Config, ModuleFile) ->
end end
end. end.
%% Increment the count of operations, since some module
%% responds to this command
increment_operations() ->
erlang:put(operations, erlang:get(operations) + 1).
update_code_path(Config) -> update_code_path(Config) ->
case rebar_config:get_local(Config, lib_dirs, []) of case rebar_config:get_local(Config, lib_dirs, []) of

View file

@ -46,20 +46,7 @@
%% =================================================================== %% ===================================================================
ct(Config, File) -> ct(Config, File) ->
case rebar_config:get_global(app, undefined) of run_test_if_present("test", Config, File).
undefined ->
%% No app parameter specified, run everything..
run_test_if_present("test", Config, File);
Apps ->
TargetApps = [list_to_atom(A) || A <- string:tokens(Apps, ",")],
ThisApp = rebar_app_utils:app_name(File),
case lists:member(ThisApp, TargetApps) of
true ->
run_test_if_present("test", Config, File);
false ->
?DEBUG("Skipping common_test on app: ~p\n", [ThisApp])
end
end.
%% =================================================================== %% ===================================================================
%% Internal functions %% Internal functions

View file

@ -63,40 +63,7 @@
%% Public API %% Public API
%% =================================================================== %% ===================================================================
eunit(Config, AppFile) -> eunit(Config, _AppFile) ->
%% Check for app global parameter; this is a comma-delimited list
%% of apps on which we want to run eunit
case rebar_config:get_global(app, undefined) of
undefined ->
%% No app parameter specified, check the skip list..
case rebar_config:get_global(skip_app, undefined) of
undefined ->
%% no skip list, run everything..
ok;
SkipApps ->
TargetApps = [list_to_atom(A) ||
A <- string:tokens(SkipApps, ",")],
ThisApp = rebar_app_utils:app_name(AppFile),
case lists:member(ThisApp, TargetApps) of
false ->
ok;
true ->
?DEBUG("Skipping eunit on app: ~p\n", [ThisApp]),
throw(ok)
end
end;
Apps ->
TargetApps = [list_to_atom(A) || A <- string:tokens(Apps, ",")],
ThisApp = rebar_app_utils:app_name(AppFile),
case lists:member(ThisApp, TargetApps) of
true ->
ok;
false ->
?DEBUG("Skipping eunit on app: ~p\n", [ThisApp]),
throw(ok)
end
end,
%% Make sure ?EUNIT_DIR/ and ebin/ directory exists (tack on dummy module) %% Make sure ?EUNIT_DIR/ and ebin/ directory exists (tack on dummy module)
ok = filelib:ensure_dir(eunit_dir() ++ "/foo"), ok = filelib:ensure_dir(eunit_dir() ++ "/foo"),
ok = filelib:ensure_dir(ebin_dir() ++ "/foo"), ok = filelib:ensure_dir(ebin_dir() ++ "/foo"),

View file

@ -56,7 +56,6 @@ get_cwd() ->
{ok, Dir} = file:get_cwd(), {ok, Dir} = file:get_cwd(),
Dir. Dir.
is_arch(ArchRegex) -> is_arch(ArchRegex) ->
case re:run(get_arch(), ArchRegex, [{capture, none}]) of case re:run(get_arch(), ArchRegex, [{capture, none}]) of
match -> match ->

View file

@ -40,17 +40,7 @@
%% Public API %% Public API
%% =================================================================== %% ===================================================================
xref(Config, _X) -> xref(Config, _) ->
case rebar_app_utils:is_skipped_app() of
true -> ok;
false -> xref0(Config, _X)
end.
%% ===================================================================
%% Internal functions
%% ===================================================================
xref0(Config, _) ->
%% Spin up xref %% Spin up xref
{ok, _} = xref:start(xref), {ok, _} = xref:start(xref),
ok = xref:set_library_path(xref, code_path()), ok = xref:set_library_path(xref, code_path()),
@ -100,6 +90,10 @@ xref0(Config, _) ->
?FAIL ?FAIL
end. end.
%% ===================================================================
%% Internal functions
%% ===================================================================
check_exports_not_used() -> check_exports_not_used() ->
{ok, UnusedExports0} = xref:analyze(xref, exports_not_used), {ok, UnusedExports0} = xref:analyze(xref, exports_not_used),
UnusedExports = filter_away_ignored(UnusedExports0), UnusedExports = filter_away_ignored(UnusedExports0),