diff options
author | Siri Hansen <siri@erlang.org> | 2016-11-18 17:42:39 +0100 |
---|---|---|
committer | Siri Hansen <siri@erlang.org> | 2016-11-21 14:41:21 +0100 |
commit | 44fabbbf9173bc97365ccb3c7d28d1bc8503c28d (patch) | |
tree | 9e47d9be89f1e153b3ab9dfcd5223223e1e9f8c6 /src | |
parent | 17e2356038fdc48eab830cf2719ef8e2e3e1748e (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.erl | 60 | ||||
-rw-r--r-- | src/rebar_erlc_compiler.erl | 53 | ||||
-rw-r--r-- | src/rebar_prv_eunit.erl | 2 |
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; |