Browse Source

Add respect for src_dirs option in app_discover

This lets people who use custom directories layout without leaving the
.app.src in src/ to still see their app build.
pull/1486/head
Fred Hebert 8 years ago
parent
commit
c64c88f262
2 changed files with 90 additions and 32 deletions
  1. +52
    -29
      src/rebar_app_discover.erl
  2. +38
    -3
      test/rebar_src_dirs_SUITE.erl

+ 52
- 29
src/rebar_app_discover.erl View File

@ -7,8 +7,10 @@
find_unbuilt_apps/1, find_unbuilt_apps/1,
find_apps/1, find_apps/1,
find_apps/2, find_apps/2,
find_apps/3,
find_app/2, find_app/2,
find_app/3]).
find_app/3,
find_app/4]).
-include("rebar.hrl"). -include("rebar.hrl").
-include_lib("providers/include/providers.hrl"). -include_lib("providers/include/providers.hrl").
@ -20,7 +22,9 @@
do(State, LibDirs) -> do(State, LibDirs) ->
BaseDir = rebar_state:dir(State), BaseDir = rebar_state:dir(State),
Dirs = [filename:join(BaseDir, LibDir) || LibDir <- LibDirs], Dirs = [filename:join(BaseDir, LibDir) || LibDir <- LibDirs],
Apps = find_apps(Dirs, all),
RebarOpts = rebar_state:opts(State),
SrcDirs = rebar_dir:src_dirs(RebarOpts, ["src"]),
Apps = find_apps(Dirs, SrcDirs, all),
ProjectDeps = rebar_state:deps_names(State), ProjectDeps = rebar_state:deps_names(State),
DepsDir = rebar_dir:deps_dir(State), DepsDir = rebar_dir:deps_dir(State),
CurrentProfiles = rebar_state:current_profiles(State), CurrentProfiles = rebar_state:current_profiles(State),
@ -179,32 +183,25 @@ reset_hooks(Opts) ->
rebar_opts:set(OptsAcc, Key, []) rebar_opts:set(OptsAcc, Key, [])
end, Opts, [post_hooks, pre_hooks, provider_hooks, artifacts]). end, Opts, [post_hooks, pre_hooks, provider_hooks, artifacts]).
%% @doc find the directories for all apps
-spec all_app_dirs([file:name()]) -> [file:name()].
all_app_dirs(LibDirs) ->
lists:flatmap(fun(LibDir) ->
app_dirs(LibDir)
end, LibDirs).
%% @doc find the directories for all apps based on their source dirs
-spec all_app_dirs([file:name()], [file:name()]) -> [file:name()].
all_app_dirs(LibDirs, SrcDirs) ->
lists:flatmap(fun(LibDir) -> app_dirs(LibDir, SrcDirs) end, LibDirs).
%% @doc find the directories based on the library directories %% @doc find the directories based on the library directories
-spec app_dirs([file:name()]) -> [file:name()].
app_dirs(LibDir) ->
Path1 = filename:join([LibDir,
"src",
"*.app.src"]),
Path2 = filename:join([LibDir,
"src",
"*.app.src.script"]),
Path3 = filename:join([LibDir,
"ebin",
"*.app"]),
-spec app_dirs([file:name()], [file:name()]) -> [file:name()].
app_dirs(LibDir, SrcDirs) ->
Paths = lists:append([
[filename:join([LibDir, SrcDir, "*.app.src"]),
filename:join([LibDir, SrcDir, "*.app.src.script"])]
|| SrcDir <- SrcDirs
]),
EbinPath = filename:join([LibDir, "ebin", "*.app"]),
lists:usort(lists:foldl(fun(Path, Acc) -> lists:usort(lists:foldl(fun(Path, Acc) ->
Files = filelib:wildcard(ec_cnv:to_list(Path)), Files = filelib:wildcard(ec_cnv:to_list(Path)),
[app_dir(File) || File <- Files] ++ Acc [app_dir(File) || File <- Files] ++ Acc
end, [], [Path1, Path2, Path3])).
end, [], [EbinPath | Paths])).
%% @doc find all apps that haven't been built in a list of directories %% @doc find all apps that haven't been built in a list of directories
-spec find_unbuilt_apps([file:filename_all()]) -> [rebar_app_info:t()]. -spec find_unbuilt_apps([file:filename_all()]) -> [rebar_app_info:t()].
@ -215,23 +212,33 @@ find_unbuilt_apps(LibDirs) ->
%% Returns all the related app info records. %% Returns all the related app info records.
-spec find_apps([file:filename_all()]) -> [rebar_app_info:t()]. -spec find_apps([file:filename_all()]) -> [rebar_app_info:t()].
find_apps(LibDirs) -> find_apps(LibDirs) ->
find_apps(LibDirs, valid).
find_apps(LibDirs, ["src"], valid).
%% @doc for each directory passed, find all apps according %% @doc for each directory passed, find all apps according
%% to the validity rule passed in. Returns all the related %% to the validity rule passed in. Returns all the related
%% app info records. %% app info records.
-spec find_apps([file:filename_all()], valid | invalid | all) -> [rebar_app_info:t()]. -spec find_apps([file:filename_all()], valid | invalid | all) -> [rebar_app_info:t()].
find_apps(LibDirs, Validate) -> find_apps(LibDirs, Validate) ->
rebar_utils:filtermap(fun(AppDir) ->
find_app(AppDir, Validate)
end, all_app_dirs(LibDirs)).
find_apps(LibDirs, ["src"], Validate).
%% @doc for each directory passed, with the configured source directories,
%% find all apps according to the validity rule passed in.
%% Returns all the related app info records.
-spec find_apps([file:filename_all()], [file:filename_all()], valid | invalid | all) -> [rebar_app_info:t()].
find_apps(LibDirs, SrcDirs, Validate) ->
rebar_utils:filtermap(
fun(AppDir) ->
find_app(rebar_app_info:new(), AppDir, SrcDirs, Validate)
end,
all_app_dirs(LibDirs, SrcDirs)
).
%% @doc check that a given app in a directory is there, and whether it's %% @doc check that a given app in a directory is there, and whether it's
%% valid or not based on the second argument. Returns the related %% valid or not based on the second argument. Returns the related
%% app info record. %% app info record.
-spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false. -spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false.
find_app(AppDir, Validate) -> find_app(AppDir, Validate) ->
find_app(rebar_app_info:new(), AppDir, Validate).
find_app(rebar_app_info:new(), AppDir, ["src"], Validate).
%% @doc check that a given app in a directory is there, and whether it's %% @doc check that a given app in a directory is there, and whether it's
%% valid or not based on the second argument. Returns the related %% valid or not based on the second argument. Returns the related
@ -239,9 +246,25 @@ find_app(AppDir, Validate) ->
-spec find_app(rebar_app_info:t(), file:filename_all(), valid | invalid | all) -> -spec find_app(rebar_app_info:t(), file:filename_all(), valid | invalid | all) ->
{true, rebar_app_info:t()} | false. {true, rebar_app_info:t()} | false.
find_app(AppInfo, AppDir, Validate) -> find_app(AppInfo, AppDir, Validate) ->
find_app(AppInfo, AppDir, ["src"], Validate).
%% @doc check that a given app in a directory is there, and whether it's
%% valid or not based on the second argument. The third argument includes
%% the directories where source files can be located. Returns the related
%% app info record.
-spec find_app(rebar_app_info:t(), file:filename_all(),
[file:filename_all()], valid | invalid | all) ->
{true, rebar_app_info:t()} | false.
find_app(AppInfo, AppDir, SrcDirs, Validate) ->
AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])), AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])),
AppSrcFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])),
AppSrcScriptFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src.script"])),
AppSrcFile = lists:append(
[filelib:wildcard(filename:join([AppDir, SrcDir, "*.app.src"]))
|| SrcDir <- SrcDirs]
),
AppSrcScriptFile = lists:append(
[filelib:wildcard(filename:join([AppDir, SrcDir, "*.app.src.script"]))
|| SrcDir <- SrcDirs]
),
try_handle_app_file(AppInfo, AppFile, AppDir, AppSrcFile, AppSrcScriptFile, Validate). try_handle_app_file(AppInfo, AppFile, AppDir, AppSrcFile, AppSrcScriptFile, Validate).
%% @doc find the directory that an appfile has %% @doc find the directory that an appfile has

+ 38
- 3
test/rebar_src_dirs_SUITE.erl View File

@ -11,6 +11,7 @@
src_dirs_in_erl_opts/1, src_dirs_in_erl_opts/1,
extra_src_dirs_in_erl_opts/1, extra_src_dirs_in_erl_opts/1,
src_dirs_at_root_and_in_erl_opts/1, src_dirs_at_root_and_in_erl_opts/1,
dupe_src_dirs_at_root_and_in_erl_opts/1,
extra_src_dirs_at_root_and_in_erl_opts/1, extra_src_dirs_at_root_and_in_erl_opts/1,
build_basic_app/1, build_basic_app/1,
build_multi_apps/1, build_multi_apps/1,
@ -35,7 +36,9 @@ end_per_testcase(_, _Config) -> ok.
all() -> all() ->
[src_dirs_at_root, extra_src_dirs_at_root, [src_dirs_at_root, extra_src_dirs_at_root,
src_dirs_in_erl_opts, extra_src_dirs_in_erl_opts, src_dirs_in_erl_opts, extra_src_dirs_in_erl_opts,
src_dirs_at_root_and_in_erl_opts, extra_src_dirs_at_root_and_in_erl_opts,
src_dirs_at_root_and_in_erl_opts,
dupe_src_dirs_at_root_and_in_erl_opts,
extra_src_dirs_at_root_and_in_erl_opts,
build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra]. build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra].
src_dirs_at_root(Config) -> src_dirs_at_root(Config) ->
@ -93,15 +96,47 @@ extra_src_dirs_in_erl_opts(Config) ->
src_dirs_at_root_and_in_erl_opts(Config) -> src_dirs_at_root_and_in_erl_opts(Config) ->
AppDir = ?config(apps, Config), AppDir = ?config(apps, Config),
Name = rebar_test_utils:create_random_name("app1_"),
Name = rebar_test_utils:create_random_name("src_dirs_root_erlopts_"),
Vsn = rebar_test_utils:create_random_vsn(), Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, {src_dirs, ["baz", "qux"]}], RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, {src_dirs, ["baz", "qux"]}],
%% move the .app.src file to one of the subdirs, out of src/
filelib:ensure_dir(filename:join([AppDir, "qux", "fake"])),
rebar_file_utils:mv(filename:join([AppDir, "src", Name ++ ".app.src"]),
filename:join([AppDir, "qux", Name ++ ".app.src"])),
{ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []).
["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []),
rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"],
{ok, [{app, Name}]}),
ok.
dupe_src_dirs_at_root_and_in_erl_opts(Config) ->
AppDir = ?config(apps, Config),
Name = rebar_test_utils:create_random_name("dupe_src_dirs_root_erlopts_"),
Vsn = rebar_test_utils:create_random_vsn(),
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, {src_dirs, ["baz", "qux"]}],
%% move the .app.src file to one of the subdirs, out of src/
filelib:ensure_dir(filename:join([AppDir, "qux", "fake"])),
filelib:ensure_dir(filename:join([AppDir, "foo", "fake"])),
Src1 = filename:join([AppDir, "qux", Name ++ ".app.src"]),
Src2 = filename:join([AppDir, "foo", Name ++ ".app.src"]),
rebar_file_utils:mv(filename:join([AppDir, "src", Name ++ ".app.src"]),
Src1),
%% Then copy it over to create a conflict with dupes
file:copy(Src1, Src2),
{error, {rebar_prv_app_discovery, {multiple_app_files, [Src2, Src1]}}} =
rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
ok.
extra_src_dirs_at_root_and_in_erl_opts(Config) -> extra_src_dirs_at_root_and_in_erl_opts(Config) ->
AppDir = ?config(apps, Config), AppDir = ?config(apps, Config),

Loading…
Cancel
Save