Refactoring core logic in preparation for dependency mgmt; breaking out sub_dir determination into dedicated module

This commit is contained in:
Dave Smith 2009-12-25 23:19:09 -07:00
parent ef67a3da3e
commit 2f64f0e6b2
3 changed files with 100 additions and 35 deletions

View file

@ -3,9 +3,10 @@
{vsn, "2"}, {vsn, "2"},
{modules, [ rebar, {modules, [ rebar,
rebar_app_utils, rebar_app_utils,
rebar_config, rebar_config,
rebar_core, rebar_core,
rebar_ct, rebar_ct,
rebar_deps,
rebar_erlc_compiler, rebar_erlc_compiler,
rebar_escripter, rebar_escripter,
rebar_eunit, rebar_eunit,
@ -19,6 +20,7 @@
rebar_port_compiler, rebar_port_compiler,
rebar_rel_utils, rebar_rel_utils,
rebar_reltool, rebar_reltool,
rebar_subdirs,
rebar_utils ]}, rebar_utils ]},
{registered, []}, {registered, []},
{applications, [kernel, {applications, [kernel,
@ -28,18 +30,29 @@
%% Default log level %% Default log level
{log_level, error}, {log_level, error},
%% Processing modules %% any_dir processing modules
{any_dir_modules, [
rebar_subdirs,
rebar_deps
]},
%% Dir specific processing modules
{modules, [ {modules, [
{app_dir, [ rebar_protobuffs_compiler, {app_dir, [
rebar_erlc_compiler, rebar_protobuffs_compiler,
rebar_lfe_compiler, rebar_erlc_compiler,
rebar_erlydtl_compiler, rebar_lfe_compiler,
rebar_port_compiler, rebar_erlydtl_compiler,
rebar_otp_app, rebar_port_compiler,
rebar_ct, rebar_otp_app,
rebar_eunit, rebar_ct,
rebar_escripter]}, rebar_eunit,
{rel_dir, [ rebar_reltool ]} rebar_escripter
]},
{rel_dir, [
rebar_reltool
]}
]} ]}
]} ]}
]}. ]}.

View file

@ -30,6 +30,7 @@
-include("rebar.hrl"). -include("rebar.hrl").
-ifndef(BUILD_TIME). -ifndef(BUILD_TIME).
-define(BUILD_TIME, "undefined"). -define(BUILD_TIME, "undefined").
-endif. -endif.
@ -92,35 +93,33 @@ filter_flags([Item | Rest], Commands) ->
process_dir(Dir, ParentConfig, Commands) -> process_dir(Dir, ParentConfig, Commands) ->
ok = file:set_cwd(Dir), ok = file:set_cwd(Dir),
Config = rebar_config:new(ParentConfig), Config = rebar_config:new(ParentConfig),
%% Save the current code path and then update it with %% Save the current code path and then update it with
%% lib_dirs. Children inherit parents code path, but we %% lib_dirs. Children inherit parents code path, but we
%% also want to ensure that we restore everything to pristine %% also want to ensure that we restore everything to pristine
%% condition after processing this child %% condition after processing this child
CurrentCodePath = update_code_path(Config), CurrentCodePath = update_code_path(Config),
%% If there are any subdirs specified, process those first...
case rebar_config:get(Config, sub_dirs, []) of
[] ->
ok;
Subdirs ->
%% Edge case: config is inherited, EXCEPT for sub_dir directives -- filter those out
FilteredConfig = rebar_config:delete(Config, sub_dirs),
[process_dir(filename:join(Dir, Subdir), FilteredConfig, Commands) ||
Subdir <- Subdirs],
ok = file:set_cwd(Dir)
end,
%% Get the list of processing modules and check each one against %% Get the list of processing modules and check each one against
%% 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),
case choose_module_set(AvailModuleSets, Dir) of {DirModules, ModuleSetFile} = choose_module_set(AvailModuleSets, Dir),
{ok, Modules, ModuleSetFile} ->
apply_commands(Commands, Modules, Config, ModuleSetFile); %% Get the list of modules for "any dir". This is a catch-all list of modules
none -> %% that are processed in addion to modules associated with this directory
ok %5 type. These any_dir modules are processed FIRST.
end, {ok, AnyDirModules} = application:get_env(rebar, any_dir_modules),
Modules = AnyDirModules ++ DirModules,
%% Give the modules a chance to tweak config and indicate if there
%% are any other dirs that might need processing first.
{UpdatedConfig, Dirs} = acc_modules(select_modules(Modules, preprocess, []),
preprocess, Config, ModuleSetFile, []),
[process_dir(D, UpdatedConfig, Commands) || D <- Dirs],
%% Finally, process the current working directory
apply_commands(Commands, Modules, UpdatedConfig, ModuleSetFile),
%% Once we're all done processing, reset the code path to whatever %% Once we're all done processing, reset the code path to whatever
%% the parent initialized it to %% the parent initialized it to
@ -128,15 +127,15 @@ process_dir(Dir, ParentConfig, Commands) ->
ok. ok.
%% %%
%% Give a list of module sets from rebar.app and a directory, find %% Given a list of module sets from rebar.app and a directory, find
%% the appropriate subset of modules for this directory %% the appropriate subset of modules for this directory
%% %%
choose_module_set([], _Dir) -> choose_module_set([], _Dir) ->
none; {[], undefined};
choose_module_set([{Fn, Modules} | Rest], Dir) -> choose_module_set([{Fn, Modules} | Rest], Dir) ->
case ?MODULE:Fn(Dir) of case ?MODULE:Fn(Dir) of
{true, File} -> {true, File} ->
{ok, Modules, File}; {Modules, File};
false -> false ->
choose_module_set(Rest, Dir) choose_module_set(Rest, Dir)
end. end.
@ -228,4 +227,13 @@ run_modules([Module | Rest], Command, Config, File) ->
{error, Reason} {error, Reason}
end. end.
acc_modules([], _Command, Config, _File, Acc) ->
{Config, Acc};
acc_modules([Module | Rest], Command, Config, File, Acc) ->
case Module:Command(Config, File) of
{ok, NewConfig, Result} when is_list(Result) ->
List = Result;
{ok, NewConfig, Result} ->
List = [Result]
end,
acc_modules(Rest, Command, NewConfig, File, List ++ Acc).

44
src/rebar_subdirs.erl Normal file
View file

@ -0,0 +1,44 @@
%% -------------------------------------------------------------------
%%
%% rebar: Erlang Build Tools
%%
%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
%%
%% Permission is hereby granted, free of charge, to any person obtaining a copy
%% of this software and associated documentation files (the "Software"), to deal
%% in the Software without restriction, including without limitation the rights
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%% copies of the Software, and to permit persons to whom the Software is
%% furnished to do so, subject to the following conditions:
%%
%% The above copyright notice and this permission notice shall be included in
%% all copies or substantial portions of the Software.
%%
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%% THE SOFTWARE.
%% -------------------------------------------------------------------
-module(rebar_subdirs).
-include("rebar.hrl").
-export([preprocess/2]).
%% ===================================================================
%% Public API
%% ===================================================================
preprocess(Config, _) ->
%% Get the list of subdirs specified in the config (if any).
Cwd = rebar_utils:get_cwd(),
Subdirs = [filename:join(Cwd, Dir) || Dir <- rebar_config:get(Config, sub_dirs, [])],
%% Filter out the subdirs from the config so that processing in the
%% subdirs doesn't try to reprocess
Config2 = rebar_config:delete(Config, sub_dirs),
{ok, Config2, Subdirs}.