summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar.erl38
-rw-r--r--src/rebar_config.erl4
-rw-r--r--src/rebar_core.erl198
-rw-r--r--src/rebar_erlc_compiler.erl21
-rw-r--r--src/rebar_file_utils.erl6
-rw-r--r--src/rebar_metacmds.erl56
-rw-r--r--src/rebar_qc.erl5
-rw-r--r--src/rebar_require_vsn.erl5
-rw-r--r--src/rebar_templater.erl3
-rw-r--r--src/rebar_utils.erl8
10 files changed, 239 insertions, 105 deletions
diff --git a/src/rebar.erl b/src/rebar.erl
index 36a7b36..d5d6c77 100644
--- a/src/rebar.erl
+++ b/src/rebar.erl
@@ -206,8 +206,19 @@ help() ->
" ~p~n"
" ~p~n"
" ~p~n"
- " ~p~n",
+ " ~p~n"
+ " ~p~n"
+ " ~p~n"
+ " ~p~n"
+ " ~p~n"
+ "Core command line options:~n"
+ " apps=app1,app2 (specify apps to process)~n"
+ " skip_apps=app1,app2 (specify apps to skip)~n",
[
+ {recursive_cmds, []},
+ {require_erts_vsn, ".*"},
+ {require_otp_vsn, ".*"},
+ {require_min_otp_vsn, ".*"},
{lib_dirs, []},
{sub_dirs, ["dir1", "dir2"]},
{plugins, [plugin1, plugin2]},
@@ -254,19 +265,23 @@ save_options(Config, {Options, NonOptArgs}) ->
Config3 = rebar_config:set_xconf(Config2, keep_going,
proplists:get_bool(keep_going, Options)),
+ %% Setup flag to enable recursive application of commands
+ Config4 = rebar_config:set_xconf(Config3, recursive,
+ proplists:get_bool(recursive, Options)),
+
%% Set global variables based on getopt options
- Config4 = set_global_flag(Config3, Options, force),
- Config5 = case proplists:get_value(jobs, Options, ?DEFAULT_JOBS) of
+ Config5 = set_global_flag(Config4, Options, force),
+ Config6 = case proplists:get_value(jobs, Options, ?DEFAULT_JOBS) of
?DEFAULT_JOBS ->
- Config4;
+ Config5;
Jobs ->
- rebar_config:set_global(Config4, jobs, Jobs)
+ rebar_config:set_global(Config5, jobs, Jobs)
end,
%% Filter all the flags (i.e. strings of form key=value) from the
%% command line arguments. What's left will be the commands to run.
- {Config6, RawCmds} = filter_flags(Config5, NonOptArgs, []),
- {Config6, unabbreviate_command_names(RawCmds)}.
+ {Config7, RawCmds} = filter_flags(Config6, NonOptArgs, []),
+ {Config7, unabbreviate_command_names(RawCmds)}.
%%
%% set log level based on getopt option
@@ -358,6 +373,9 @@ list-templates List available templates
doc Generate Erlang program documentation
+prepare-deps Run 'rebar -r get-deps compile'
+refresh-deps Run 'rebar -r update-deps compile'
+
check-deps Display to be fetched dependencies
get-deps Fetch dependencies
update-deps Update fetched dependencies
@@ -420,7 +438,9 @@ option_spec_list() ->
{config, $C, "config", string, "Rebar config file to use"},
{profile, $p, "profile", undefined, "Profile this run of rebar"},
{keep_going, $k, "keep-going", undefined,
- "Keep running after a command fails"}
+ "Keep running after a command fails"},
+ {recursive, $r, "recursive", boolean,
+ "Apply commands to subdirs and dependencies"}
].
%%
@@ -469,7 +489,9 @@ command_names() ->
"help",
"list-deps",
"list-templates",
+ "prepare-deps",
"qc",
+ "refresh-deps",
"update-deps",
"overlay",
"shell",
diff --git a/src/rebar_config.erl b/src/rebar_config.erl
index 9b58d4f..10c6483 100644
--- a/src/rebar_config.erl
+++ b/src/rebar_config.erl
@@ -31,6 +31,7 @@
get_all/2,
set/3,
set_global/3, get_global/3,
+ is_recursive/1,
save_env/3, get_env/2, reset_envs/1,
set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1,
clean_config/2,
@@ -109,6 +110,9 @@ get_global(Config, Key, Default) ->
Value
end.
+is_recursive(Config) ->
+ get_xconf(Config, recursive, false).
+
consult_file(File) ->
case filename:extension(File) of
".script" ->
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index 4efc978..3a4f205 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -88,7 +88,7 @@ process_commands([Command | Rest], ParentConfig) ->
%% path from inside a subdirectory.
true = rebar_utils:expand_code_path(),
{ParentConfig2, _DirSet} = process_dir(rebar_utils:get_cwd(),
- ParentConfig1, Command,
+ Command, ParentConfig1,
sets:new()),
case get_operations(ParentConfig2) of
Operations ->
@@ -117,71 +117,110 @@ process_commands([Command | Rest], ParentConfig) ->
end,
process_commands(Rest, ParentConfig4).
-process_dir(Dir, ParentConfig, Command, DirSet) ->
+process_dir(Dir, Command, ParentConfig, DirSet) ->
case filelib:is_dir(Dir) of
false ->
?WARN("Skipping non-existent sub-dir: ~p\n", [Dir]),
{ParentConfig, DirSet};
-
true ->
+ WouldCd = would_cd_into_dir(Dir, Command, ParentConfig),
ok = file:set_cwd(Dir),
Config = maybe_load_local_config(Dir, ParentConfig),
%% Save the current code path and then update it with
- %% lib_dirs. Children inherit parents code path, but we
- %% also want to ensure that we restore everything to pristine
+ %% lib_dirs. Children inherit parents code path, but we also
+ %% want to ensure that we restore everything to pristine
%% condition after processing this child
CurrentCodePath = update_code_path(Config),
- %% 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
- %% to process this dir.
+ %% 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 to process this dir.
{ok, AvailModuleSets} = application:get_env(rebar, modules),
ModuleSet = choose_module_set(AvailModuleSets, Dir),
- skip_or_process_dir(ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet)
+ skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
end.
-skip_or_process_dir({[], undefined}=ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
- process_dir1(Dir, Command, DirSet, Config, CurrentCodePath, ModuleSet);
-skip_or_process_dir({_, ModuleSetFile}=ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
- case lists:suffix(".app.src", ModuleSetFile)
- orelse lists:suffix(".app", ModuleSetFile) of
+would_cd_into_dir(Dir, Command, Config) ->
+ case would_cd_into_dir1(Dir, Command, Config) of
+ true ->
+ would_cd;
+ false ->
+ would_not_cd
+ end.
+
+would_cd_into_dir1(Dir, Command, Config) ->
+ rebar_utils:processing_base_dir(Config, Dir) orelse
+ rebar_config:is_recursive(Config) orelse
+ is_recursive_command(Command, Config) orelse
+ is_generate_in_rel_dir(Command, Dir).
+
+%% Check whether the command is part of the built-in (or extended via
+%% rebar.config) list of default-recursive commands.
+is_recursive_command(Command, Config) ->
+ {ok, AppCmds} = application:get_env(rebar, recursive_cmds),
+ ConfCmds = rebar_config:get_local(Config, recursive_cmds, []),
+ RecursiveCmds = AppCmds ++ ConfCmds,
+ lists:member(Command, RecursiveCmds).
+
+%% If the directory we're about to process contains
+%% reltool.config[.script] and the command to be applied is
+%% 'generate', then it's safe to process. We do this to retain the
+%% behavior of specifying {sub_dirs, ["rel"]} and have "rebar generate"
+%% pick up rel/reltool.config[.script]. Without this workaround you'd
+%% have to run "rebar -r generate" (which you don't want to do if you
+%% have deps or other sub_dirs) or "cd rel && rebar generate".
+is_generate_in_rel_dir(generate, Dir) ->
+ case rebar_rel_utils:is_rel_dir(Dir) of
+ {true, _} ->
+ true;
+ false ->
+ false
+ end;
+is_generate_in_rel_dir(_, _) ->
+ false.
+
+skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ {[], undefined}=ModuleSet, WouldCd) ->
+ process_dir1(Dir, Command, Config, DirSet, CurrentCodePath, ModuleSet,
+ WouldCd);
+skip_or_process_dir(Dir, Command, Config, DirSet, CurrentCodePath,
+ {_, File}=ModuleSet, WouldCd) ->
+ case lists:suffix(".app.src", File)
+ orelse lists:suffix(".app", File) of
true ->
%% .app or .app.src file, check if is_skipped_app
- skip_or_process_dir1(ModuleSetFile, ModuleSet,
- Config, CurrentCodePath, Dir,
- Command, DirSet);
+ skip_or_process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd, File);
false ->
%% not an app dir, no need to consider apps=/skip_apps=
- process_dir1(Dir, Command, DirSet, Config,
- CurrentCodePath, ModuleSet)
+ process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
end.
-skip_or_process_dir1(AppFile, ModuleSet, Config, CurrentCodePath,
- Dir, Command, DirSet) ->
+skip_or_process_dir1(Dir, Command, Config, DirSet, CurrentCodePath, ModuleSet,
+ WouldCd, AppFile) ->
case rebar_app_utils:is_skipped_app(Config, AppFile) of
{Config1, {true, _SkippedApp}} when Command == 'update-deps' ->
%% update-deps does its own app skipping. Unfortunately there's no
%% way to signal this to rebar_core, so we have to explicitly do it
%% here... Otherwise if you use app=, it'll skip the toplevel
%% directory and nothing will be updated.
- process_dir1(Dir, Command, DirSet, Config1,
- CurrentCodePath, ModuleSet);
+ process_dir1(Dir, Command, Config1, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd);
{Config1, {true, SkippedApp}} ->
?DEBUG("Skipping app: ~p~n", [SkippedApp]),
- Config2 = increment_operations(Config1),
- {Config2, DirSet};
+ {increment_operations(Config1), DirSet};
{Config1, false} ->
- process_dir1(Dir, Command, DirSet, Config1,
- CurrentCodePath, ModuleSet)
+ process_dir1(Dir, Command, Config1, DirSet, CurrentCodePath,
+ ModuleSet, WouldCd)
end.
-process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
- {DirModules, ModuleSetFile}) ->
+process_dir1(Dir, Command, Config, DirSet, CurrentCodePath,
+ {DirModules, File}, WouldCd) ->
Config0 = rebar_config:set_xconf(Config, current_command, Command),
+
%% 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
@@ -192,8 +231,7 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Invoke 'preprocess' on the modules -- this yields a list of other
%% directories that should be processed _before_ the current one.
- {Config1, Predirs} = acc_modules(Modules, preprocess, Config0,
- ModuleSetFile),
+ {Config1, Predirs} = acc_modules(Modules, preprocess, Config0, File),
%% Remember associated pre-dirs (used for plugin lookup)
PredirsAssoc = remember_cwd_predirs(Dir, Predirs),
@@ -201,55 +239,33 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Get the list of plug-in modules from rebar.config. These
%% modules may participate in preprocess and postprocess.
{ok, PluginModules} = plugin_modules(Config1, PredirsAssoc),
+ AllModules = Modules ++ PluginModules,
- {Config2, PluginPredirs} = acc_modules(PluginModules, preprocess,
- Config1, ModuleSetFile),
+ {Config2, PluginPredirs} = acc_modules(PluginModules, preprocess, Config1,
+ File),
AllPredirs = Predirs ++ PluginPredirs,
?DEBUG("Predirs: ~p\n", [AllPredirs]),
- {Config3, DirSet2} = process_each(AllPredirs, Command, Config2,
- ModuleSetFile, DirSet),
+ {Config3, DirSet2} = process_each(AllPredirs, Command, Config2, DirSet,
+ File),
%% 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
- Config7 = case rebar_config:is_skip_dir(Config3, Dir) of
- true ->
- %% Do not execute the command on the directory, as some
- %% module has requested a skip on it.
- ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
- Config3;
-
- false ->
- %% Check for and get command specific environments
- {Config4, Env} = setup_envs(Config3, Modules),
-
- %% Execute any before_command plugins on this directory
- Config5 = execute_pre(Command, PluginModules,
- Config4, ModuleSetFile, Env),
-
- %% Execute the current command on this directory
- Config6 = execute(Command, Modules ++ PluginModules,
- Config5, ModuleSetFile, Env),
-
- %% Execute any after_command plugins on this directory
- execute_post(Command, PluginModules,
- Config6, ModuleSetFile, Env)
- end,
+ %% Maybe apply command to Dir
+ Config4 = maybe_execute(Dir, Command, Config3, Modules, PluginModules,
+ AllModules, File, WouldCd),
%% 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.
- {Config8, Postdirs} = acc_modules(Modules ++ PluginModules, postprocess,
- Config7, ModuleSetFile),
+ {Config5, Postdirs} = acc_modules(AllModules, postprocess, Config4, File),
?DEBUG("Postdirs: ~p\n", [Postdirs]),
- Res = process_each(Postdirs, Command, Config8,
- ModuleSetFile, DirSet3),
+ Res = process_each(Postdirs, Command, Config5, DirSet3, File),
%% Make sure the CWD is reset properly; processing the dirs may have
%% caused it to change
@@ -262,6 +278,33 @@ process_dir1(Dir, Command, DirSet, Config, CurrentCodePath,
%% Return the updated {config, dirset} as result
Res.
+maybe_execute(Dir, Command, Config, Modules, PluginModules, AllModules, File,
+ would_cd) ->
+ %% Check that this directory is not on the skip list
+ case rebar_config:is_skip_dir(Config, Dir) of
+ true ->
+ %% Do not execute the command on the directory, as some
+ %% module has requested a skip on it.
+ ?INFO("Skipping ~s in ~s\n", [Command, Dir]),
+ Config;
+
+ false ->
+ %% Check for and get command specific environments
+ {Config1, Env} = setup_envs(Config, Modules),
+
+ %% Execute any before_command plugins on this directory
+ Config2 = execute_pre(Command, PluginModules, Config1, File, Env),
+
+ %% Execute the current command on this directory
+ Config3 = execute(Command, AllModules, Config2, File, Env),
+
+ %% Execute any after_command plugins on this directory
+ execute_post(Command, PluginModules, Config3, File, Env)
+ end;
+maybe_execute(_Dir, _Command, Config, _Modules, _PluginModules, _AllModules,
+ _File, would_not_cd) ->
+ Config.
+
remember_cwd_predirs(Cwd, Predirs) ->
Store = fun(Dir, Dict) ->
case dict:find(Dir, Dict) of
@@ -292,21 +335,21 @@ maybe_load_local_config(Dir, ParentConfig) ->
%% Given a list of directories and a set of previously processed directories,
%% process each one we haven't seen yet
%%
-process_each([], _Command, Config, _ModuleSetFile, DirSet) ->
+process_each([], _Command, Config, DirSet, _File) ->
%% reset cached (setup_env) envs
Config1 = rebar_config:reset_envs(Config),
{Config1, DirSet};
-process_each([Dir | Rest], Command, Config, ModuleSetFile, DirSet) ->
+process_each([Dir | Rest], Command, Config, DirSet, File) ->
case sets:is_element(Dir, DirSet) of
true ->
?DEBUG("Skipping ~s; already processed!\n", [Dir]),
- process_each(Rest, Command, Config, ModuleSetFile, DirSet);
+ process_each(Rest, Command, Config, DirSet, File);
false ->
- {Config1, DirSet2} = process_dir(Dir, Config, Command, DirSet),
+ {Config1, DirSet2} = process_dir(Dir, Command, Config, DirSet),
Config2 = rebar_config:clean_config(Config, Config1),
%% reset cached (setup_env) envs
Config3 = rebar_config:reset_envs(Config2),
- process_each(Rest, Command, Config3, ModuleSetFile, DirSet2)
+ process_each(Rest, Command, Config3, DirSet2, File)
end.
%%
@@ -340,20 +383,21 @@ execute_post(Command, Modules, Config, ModuleFile, Env) ->
execute_plugin_hook(Hook, Command, Modules, Config, ModuleFile, Env) ->
HookFunction = list_to_atom(Hook ++ atom_to_list(Command)),
- execute(HookFunction, Modules, Config, ModuleFile, Env).
+ execute(HookFunction, hook, Modules, Config, ModuleFile, Env).
%%
%% Execute a command across all applicable modules
%%
execute(Command, Modules, Config, ModuleFile, Env) ->
+ execute(Command, not_a_hook, Modules, Config, ModuleFile, Env).
+
+execute(Command, Type, Modules, Config, ModuleFile, Env) ->
case select_modules(Modules, Command, []) of
[] ->
- Cmd = atom_to_list(Command),
- case lists:prefix("pre_", Cmd)
- orelse lists:prefix("post_", Cmd) of
- true ->
+ case Type of
+ hook ->
ok;
- false ->
+ not_a_hook ->
?WARN("'~p' command does not apply to directory ~s\n",
[Command, rebar_utils:get_cwd()])
end,
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 75d47fb..b797137 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -134,12 +134,13 @@ test_compile(Config, Cmd, OutDir) ->
%% Obtain all the test modules for inclusion in the compile stage.
TestErls = rebar_utils:find_files("test", ".*\\.erl\$"),
+ ErlOpts = rebar_utils:erl_opts(Config),
+ {Config1, ErlOpts1} = test_compile_config_and_opts(Config, ErlOpts, Cmd),
+
%% Copy source files to eunit dir for cover in case they are not directly
%% in src but in a subdirectory of src. Cover only looks in cwd and ../src
%% for source files. Also copy files from src_dirs.
- ErlOpts = rebar_utils:erl_opts(Config),
-
- SrcDirs = rebar_utils:src_dirs(proplists:append_values(src_dirs, ErlOpts)),
+ SrcDirs = rebar_utils:src_dirs(proplists:append_values(src_dirs, ErlOpts1)),
SrcErls = lists:foldl(
fun(Dir, Acc) ->
Files = rebar_utils:find_files(Dir, ".*\\.erl\$"),
@@ -172,8 +173,7 @@ test_compile(Config, Cmd, OutDir) ->
%% Compile erlang code to OutDir, using a tweaked config
%% with appropriate defines for eunit, and include all the test modules
%% as well.
- ok = doterl_compile(test_compile_config(Config, ErlOpts, Cmd),
- OutDir, TestErls, ErlOpts),
+ ok = doterl_compile(Config1, OutDir, TestErls, ErlOpts1),
{ok, SrcErls}.
@@ -217,21 +217,22 @@ info_help(Description) ->
{yrl_first_files, []}
]).
-test_compile_config(Config, ErlOpts, Cmd) ->
+test_compile_config_and_opts(Config, ErlOpts, Cmd) ->
{Config1, TriqOpts} = triq_opts(Config),
{Config2, PropErOpts} = proper_opts(Config1),
{Config3, EqcOpts} = eqc_opts(Config2),
OptsAtom = list_to_atom(Cmd ++ "_compile_opts"),
- EunitOpts = rebar_config:get_list(Config3, OptsAtom, []),
+ TestOpts = rebar_config:get_list(Config3, OptsAtom, []),
Opts0 = [{d, 'TEST'}] ++
- ErlOpts ++ EunitOpts ++ TriqOpts ++ PropErOpts ++ EqcOpts,
+ ErlOpts ++ TestOpts ++ TriqOpts ++ PropErOpts ++ EqcOpts,
Opts = [O || O <- Opts0, O =/= no_debug_info],
Config4 = rebar_config:set(Config3, erl_opts, Opts),
FirstFilesAtom = list_to_atom(Cmd ++ "_first_files"),
FirstErls = rebar_config:get_list(Config4, FirstFilesAtom, []),
- rebar_config:set(Config4, erl_first_files, FirstErls).
+ Config5 = rebar_config:set(Config4, erl_first_files, FirstErls),
+ {Config5, Opts}.
triq_opts(Config) ->
{NewConfig, IsAvail} = is_lib_avail(Config, is_triq_avail, triq,
@@ -538,7 +539,7 @@ internal_erl_compile(Config, Source, OutDir, ErlOpts, G) ->
%% Determine the target name and includes list by inspecting the source file
Module = filename:basename(Source, ".erl"),
Parents = get_parents(G, Source),
- log_files(?FMT("~s depends on", [Source]), Parents),
+ log_files(?FMT("Dependencies of ~s", [Source]), Parents),
%% Construct the target filename
Target = filename:join([OutDir | string:tokens(Module, ".")]) ++ ".beam",
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl
index fcd9c5e..9ddbf27 100644
--- a/src/rebar_file_utils.erl
+++ b/src/rebar_file_utils.erl
@@ -46,7 +46,7 @@ rm_rf(Target) ->
{unix, _} ->
EscTarget = escape_spaces(Target),
{ok, []} = rebar_utils:sh(?FMT("rm -rf ~s", [EscTarget]),
- [{use_stdout, false}, return_on_error]),
+ [{use_stdout, false}, abort_on_error]),
ok;
{win32, _} ->
Filelist = filelib:wildcard(Target),
@@ -67,7 +67,7 @@ cp_r(Sources, Dest) ->
SourceStr = string:join(EscSources, " "),
{ok, []} = rebar_utils:sh(?FMT("cp -R ~s \"~s\"",
[SourceStr, Dest]),
- [{use_stdout, false}, return_on_error]),
+ [{use_stdout, false}, abort_on_error]),
ok;
{win32, _} ->
lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources),
@@ -81,7 +81,7 @@ mv(Source, Dest) ->
EscSource = escape_spaces(Source),
EscDest = escape_spaces(Dest),
{ok, []} = rebar_utils:sh(?FMT("mv ~s ~s", [EscSource, EscDest]),
- [{use_stdout, false}, return_on_error]),
+ [{use_stdout, false}, abort_on_error]),
ok;
{win32, _} ->
{ok, R} = rebar_utils:sh(
diff --git a/src/rebar_metacmds.erl b/src/rebar_metacmds.erl
new file mode 100644
index 0000000..6e223bd
--- /dev/null
+++ b/src/rebar_metacmds.erl
@@ -0,0 +1,56 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% rebar: Erlang Build Tools
+%%
+%% Copyright (c) 2013-2014 Tuncer Ayaz
+%%
+%% 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_metacmds).
+
+-export(['prepare-deps'/2,
+ 'refresh-deps'/2]).
+
+%% for internal use only
+-export([info/2]).
+
+-include("rebar.hrl").
+
+%% ===================================================================
+%% Public API
+%% ===================================================================
+'prepare-deps'(Config, _AppFile) ->
+ rebar:run(enable_recursion(Config), ["get-deps", "compile"]).
+
+'refresh-deps'(Config, _AppFile) ->
+ rebar:run(enable_recursion(Config), ["update-deps", "compile"]).
+
+%% ===================================================================
+%% Internal functions
+%% ===================================================================
+
+info(help, 'prepare-deps') ->
+ ?CONSOLE("Meta command to run 'rebar -r get-deps compile'.~n", []);
+info(help, 'refresh-deps') ->
+ ?CONSOLE("Meta command to run 'rebar -r update-deps compile'.~n", []).
+
+enable_recursion(Config) ->
+ rebar_config:set_xconf(Config, recursive, true).
diff --git a/src/rebar_qc.erl b/src/rebar_qc.erl
index 99d37a2..1976722 100644
--- a/src/rebar_qc.erl
+++ b/src/rebar_qc.erl
@@ -73,7 +73,10 @@ info(help, qc) ->
[
{qc_compile_opts, []},
{qc_first_files, []}
- ]).
+ ]);
+info(help, clean) ->
+ Description = ?FMT("Delete QuickCheck test dir (~s)", [?QC_DIR]),
+ ?CONSOLE("~s.~n", [Description]).
-define(TRIQ_MOD, triq).
-define(EQC_MOD, eqc).
diff --git a/src/rebar_require_vsn.erl b/src/rebar_require_vsn.erl
index 385f55c..af805c8 100644
--- a/src/rebar_require_vsn.erl
+++ b/src/rebar_require_vsn.erl
@@ -34,7 +34,8 @@
eunit/2]).
%% for internal use only
--export([info/2]).
+-export([info/2,
+ version_tuple/2]).
%% ===================================================================
%% Public API
@@ -110,7 +111,7 @@ check_versions(Config) ->
end.
version_tuple(OtpRelease, Type) ->
- case re:run(OtpRelease, "R(\\d+)B?-?(\\d+)?", [{capture, all, list}]) of
+ case re:run(OtpRelease, "R?(\\d+)B?-?(\\d+)?", [{capture, all, list}]) of
{match, [_Full, Maj, Min]} ->
{list_to_integer(Maj), list_to_integer(Min)};
{match, [_Full, Maj]} ->
diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl
index 43bb8da..fef4627 100644
--- a/src/rebar_templater.erl
+++ b/src/rebar_templater.erl
@@ -245,7 +245,8 @@ find_disk_templates(Config) ->
HomeFiles = rebar_utils:find_files(filename:join([os:getenv("HOME"),
".rebar", "templates"]),
?TEMPLATE_RE),
- LocalFiles = rebar_utils:find_files(".", ?TEMPLATE_RE),
+ Recursive = rebar_config:is_recursive(Config),
+ LocalFiles = rebar_utils:find_files(".", ?TEMPLATE_RE, Recursive),
[{file, F} || F <- OtherTemplates ++ HomeFiles ++ LocalFiles].
find_other_templates(Config) ->
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index 2d227b6..517ac33 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -316,7 +316,8 @@ processing_base_dir(Config) ->
processing_base_dir(Config, Cwd).
processing_base_dir(Config, Dir) ->
- Dir =:= base_dir(Config).
+ AbsDir = filename:absname(Dir),
+ AbsDir =:= base_dir(Config).
%% ====================================================================
%% Internal functions
@@ -398,8 +399,9 @@ log_msg_and_abort(Message) ->
-spec log_and_abort(string(), {integer(), string()}) -> no_return().
log_and_abort(Command, {Rc, Output}) ->
- ?ABORT("~s failed with error: ~w and output:~n~s~n",
- [Command, Rc, Output]).
+ ?ABORT("sh(~s)~n"
+ "failed with return code ~w and the following output:~n"
+ "~s~n", [Command, Rc, Output]).
sh_loop(Port, Fun, Acc) ->
receive