summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSiri Hansen <siri@erlang.org>2016-11-18 17:42:39 +0100
committerSiri Hansen <siri@erlang.org>2016-11-21 14:41:21 +0100
commit44fabbbf9173bc97365ccb3c7d28d1bc8503c28d (patch)
tree9e47d9be89f1e153b3ab9dfcd5223223e1e9f8c6 /src
parent17e2356038fdc48eab830cf2719ef8e2e3e1748e (diff)
Add 'recursive' option
The option {recursive,boolean()} can now be set pr directory in 'src_dirs' and 'extra_src_dirs', and on top level in the new 'erlc_compiler' option. Example config: {erlc_compiler,[{recursive,false}]}. {src_dirs,[{"src",[{recursive,true}]}]}. This will cause recursive compilation within the "src" directory, but not in any other directoires.
Diffstat (limited to 'src')
-rw-r--r--src/rebar_dir.erl60
-rw-r--r--src/rebar_erlc_compiler.erl53
-rw-r--r--src/rebar_prv_eunit.erl2
3 files changed, 82 insertions, 33 deletions
diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl
index 1ec58d4..79a1c7f 100644
--- a/src/rebar_dir.erl
+++ b/src/rebar_dir.erl
@@ -22,6 +22,7 @@
processing_base_dir/2,
make_relative_path/2,
src_dirs/1, src_dirs/2,
+ src_dir_opts/2, recursive/2,
extra_src_dirs/1, extra_src_dirs/2,
all_src_dirs/1, all_src_dirs/3,
retarget_path/2]).
@@ -160,28 +161,43 @@ do_make_relative_path(Source, Target) ->
Base = lists:duplicate(max(length(Target) - 1, 0), ".."),
filename:join(Base ++ Source).
+%%%-----------------------------------------------------------------
+%%% 'src_dirs' and 'extra_src_dirs' can be configured with options
+%%% like this:
+%%%
+%%% {src_dirs,[{"foo",[{recursive,false}]}]}
+%%% {extra_src_dirs,[{"bar",[recursive]}]} (equivalent to {recursive,true})
+%%%
+%%% src_dirs/1,2 and extra_src_dirs/1,2 return only the list of
+%%% directories for the 'src_dirs' and 'extra_src_dirs' options
+%%% respectively, while src_dirs_opts/2 return the options list for
+%%% the given directory, no matter if it is configured as 'src_dirs' or
+%%% 'extra_src_dirs'.
+%%%
-spec src_dirs(rebar_dict()) -> list(file:filename_all()).
src_dirs(Opts) -> src_dirs(Opts, []).
-spec src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()).
src_dirs(Opts, Default) ->
- ErlOpts = rebar_opts:erl_opts(Opts),
- Vs = proplists:get_all_values(src_dirs, ErlOpts),
- case lists:append([rebar_opts:get(Opts, src_dirs, []) | Vs]) of
- [] -> Default;
- Dirs -> lists:usort(Dirs)
- end.
+ src_dirs(src_dirs, Opts, Default).
-spec extra_src_dirs(rebar_dict()) -> list(file:filename_all()).
extra_src_dirs(Opts) -> extra_src_dirs(Opts, []).
-spec extra_src_dirs(rebar_dict(), list(file:filename_all())) -> list(file:filename_all()).
extra_src_dirs(Opts, Default) ->
+ src_dirs(extra_src_dirs, Opts, Default).
+
+src_dirs(Type, Opts, Default) ->
+ lists:usort([case D0 of {D,_} -> D; _ -> D0 end ||
+ D0 <- raw_src_dirs(Type,Opts,Default)]).
+
+raw_src_dirs(Type, Opts, Default) ->
ErlOpts = rebar_opts:erl_opts(Opts),
- Vs = proplists:get_all_values(extra_src_dirs, ErlOpts),
- case lists:append([rebar_opts:get(Opts, extra_src_dirs, []) | Vs]) of
+ Vs = proplists:get_all_values(Type, ErlOpts),
+ case lists:append([rebar_opts:get(Opts, Type, []) | Vs]) of
[] -> Default;
- Dirs -> lists:usort(Dirs)
+ Dirs -> Dirs
end.
-spec all_src_dirs(rebar_dict()) -> list(file:filename_all()).
@@ -192,6 +208,32 @@ all_src_dirs(Opts) -> all_src_dirs(Opts, [], []).
all_src_dirs(Opts, SrcDefault, ExtraDefault) ->
lists:usort(src_dirs(Opts, SrcDefault) ++ extra_src_dirs(Opts, ExtraDefault)).
+%%%-----------------------------------------------------------------
+%%% Return the list of options for the given src directory
+%%% If the same option is given multiple times for a directory in the
+%%% config, the priority order is: first occurence of 'src_dirs'
+%%% followed by first occurence of 'extra_src_dirs'.
+-spec src_dir_opts(rebar_dict(), file:filename_all()) -> [{atom(),term()}].
+src_dir_opts(Opts, Dir) ->
+ RawSrcDirs = raw_src_dirs(src_dirs, Opts, []),
+ RawExtraSrcDirs = raw_src_dirs(extra_src_dirs, Opts, []),
+ AllOpts = [Opt || {D,Opt} <- RawSrcDirs++RawExtraSrcDirs,
+ D==Dir],
+ lists:ukeysort(1,proplists:unfold(lists:append(AllOpts))).
+
+%%%-----------------------------------------------------------------
+%%% Return the value of the 'recursive' option for the given directory.
+%%% If not given, the value of 'recursive' in the 'erlc_compiler'
+%%% options is used, and finally the default is 'true'.
+-spec recursive(rebar_dict(), file:filename_all()) -> boolean().
+recursive(Opts, Dir) ->
+ DirOpts = src_dir_opts(Opts, Dir),
+ Default = proplists:get_value(recursive,
+ rebar_opts:get(Opts, erlc_compiler, []),
+ true),
+ R = proplists:get_value(recursive, DirOpts, Default),
+ R.
+
%% given a path if that path is an ancestor of an app dir return the path relative to that
%% apps outdir. if the path is not an ancestor to any app dirs but is an ancestor of the
%% project root return the path relative to the project base_dir. if it is not an ancestor
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 97235aa..325bb4f 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -47,10 +47,6 @@
-type compile_opts() :: [compile_opt()].
-type compile_opt() :: {recursive, boolean()}.
--record(compile_opts, {
- recursive = true
-}).
-
-define(DEFAULT_OUTDIR, "ebin").
-define(RE_PREFIX, "^[^._]").
@@ -99,21 +95,25 @@ compile(AppInfo, CompileOpts) when element(1, AppInfo) == app_info_t ->
Dir = ec_cnv:to_list(rebar_app_info:out_dir(AppInfo)),
RebarOpts = rebar_app_info:opts(AppInfo),
+ SrcOpts = [check_last_mod,
+ {recursive, dir_recursive(RebarOpts, "src", CompileOpts)}],
+ MibsOpts = [check_last_mod,
+ {recursive, dir_recursive(RebarOpts, "mibs", CompileOpts)}],
rebar_base_compiler:run(RebarOpts,
check_files([filename:join(Dir, File)
|| File <- rebar_opts:get(RebarOpts, xrl_first_files, [])]),
filename:join(Dir, "src"), ".xrl", filename:join(Dir, "src"), ".erl",
- fun compile_xrl/3),
+ fun compile_xrl/3, SrcOpts),
rebar_base_compiler:run(RebarOpts,
check_files([filename:join(Dir, File)
|| File <- rebar_opts:get(RebarOpts, yrl_first_files, [])]),
filename:join(Dir, "src"), ".yrl", filename:join(Dir, "src"), ".erl",
- fun compile_yrl/3),
+ fun compile_yrl/3, SrcOpts),
rebar_base_compiler:run(RebarOpts,
check_files([filename:join(Dir, File)
|| File <- rebar_opts:get(RebarOpts, mib_first_files, [])]),
filename:join(Dir, "mibs"), ".mib", filename:join([Dir, "priv", "mibs"]), ".bin",
- compile_mib(AppInfo)),
+ compile_mib(AppInfo), MibsOpts),
SrcDirs = lists:map(fun(SrcDir) -> filename:join(Dir, SrcDir) end,
rebar_dir:src_dirs(RebarOpts, ["src"])),
@@ -182,13 +182,10 @@ compile_dir(RebarOpts, BaseDir, Dir, Opts) ->
compile_opts()) -> ok.
compile_dirs(State, BaseDir, Dirs, OutDir, CompileOpts) when element(1, State) == state_t ->
compile_dirs(rebar_state:opts(State), BaseDir, Dirs, OutDir, CompileOpts);
-compile_dirs(RebarOpts, BaseDir, SrcDirs, OutDir, Opts) ->
- CompileOpts = parse_opts(Opts),
-
+compile_dirs(RebarOpts, BaseDir, SrcDirs, OutDir, CompileOpts) ->
ErlOpts = rebar_opts:erl_opts(RebarOpts),
?DEBUG("erlopts ~p", [ErlOpts]),
- Recursive = CompileOpts#compile_opts.recursive,
- AllErlFiles = gather_src(SrcDirs, Recursive),
+ AllErlFiles = gather_src(RebarOpts, BaseDir, SrcDirs, CompileOpts),
?DEBUG("files to compile ~p", [AllErlFiles]),
%% Make sure that outdir is on the path
@@ -266,12 +263,22 @@ clean_dirs(AppDir, [Dir|Rest]) ->
%% Internal functions
%% ===================================================================
-gather_src(Dirs, Recursive) ->
- gather_src(Dirs, [], Recursive).
-
-gather_src([], Srcs, _Recursive) -> Srcs;
-gather_src([Dir|Rest], Srcs, Recursive) ->
- gather_src(Rest, Srcs ++ rebar_utils:find_files(Dir, ?RE_PREFIX".*\\.erl\$", Recursive), Recursive).
+gather_src(Opts, BaseDir, Dirs, CompileOpts) ->
+ gather_src(Opts, filename:split(BaseDir), Dirs, [], CompileOpts).
+
+gather_src(_Opts, _BaseDirParts, [], Srcs, _CompileOpts) -> Srcs;
+gather_src(Opts, BaseDirParts, [Dir|Rest], Srcs, CompileOpts) ->
+ DirParts = filename:split(Dir),
+ RelDir = case lists:prefix(BaseDirParts,DirParts) of
+ true ->
+ case lists:nthtail(length(BaseDirParts),DirParts) of
+ [] -> ".";
+ RestParts -> filename:join(RestParts)
+ end;
+ false -> Dir
+ end,
+ DirRecursive = dir_recursive(Opts, RelDir, CompileOpts),
+ gather_src(Opts, BaseDirParts, Rest, Srcs ++ rebar_utils:find_files(Dir, ?RE_PREFIX".*\\.erl\$", DirRecursive), CompileOpts).
%% Get files which need to be compiled first, i.e. those specified in erl_first_files
%% and parse_transform options. Also produce specific erl_opts for these first
@@ -758,8 +765,8 @@ include_abs_dirs(ErlOpts, BaseDir) ->
InclDirs = ["include"|proplists:get_all_values(i, ErlOpts)],
lists:map(fun(Incl) -> filename:join([BaseDir, Incl]) end, InclDirs).
-parse_opts(Opts) -> parse_opts(Opts, #compile_opts{}).
-
-parse_opts([], CompileOpts) -> CompileOpts;
-parse_opts([{recursive, Recursive}|Rest], CompileOpts) when Recursive == true; Recursive == false ->
- parse_opts(Rest, CompileOpts#compile_opts{recursive = Recursive}).
+dir_recursive(Opts, Dir, CompileOpts) when is_list(CompileOpts) ->
+ case proplists:get_value(recursive,CompileOpts) of
+ undefined -> rebar_dir:recursive(Opts, Dir);
+ Recursive -> Recursive
+ end.
diff --git a/src/rebar_prv_eunit.erl b/src/rebar_prv_eunit.erl
index e85ab4c..0908ec9 100644
--- a/src/rebar_prv_eunit.erl
+++ b/src/rebar_prv_eunit.erl
@@ -310,7 +310,7 @@ maybe_inject_test_dir(State, AppAcc, [], Dir) ->
inject_test_dir(Opts, Dir) ->
%% append specified test targets to app defined `extra_src_dirs`
- ExtraSrcDirs = rebar_dir:extra_src_dirs(Opts),
+ ExtraSrcDirs = rebar_opts:get(Opts, extra_src_dirs, []),
rebar_opts:set(Opts, extra_src_dirs, ExtraSrcDirs ++ [Dir]).
compile({error, _} = Error) -> Error;