diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar3.erl | 2 | ||||
-rw-r--r-- | src/rebar_app_discover.erl | 121 | ||||
-rw-r--r-- | src/rebar_app_info.erl | 13 | ||||
-rw-r--r-- | src/rebar_config.erl | 10 | ||||
-rw-r--r-- | src/rebar_prv_clean.erl | 3 | ||||
-rw-r--r-- | src/rebar_prv_plugins.erl | 11 |
6 files changed, 114 insertions, 46 deletions
diff --git a/src/rebar3.erl b/src/rebar3.erl index 56bf3e8..5c593cc 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -176,7 +176,7 @@ init_config() -> Verbosity = log_level(), ok = rebar_log:init(command_line, Verbosity), - Config = rebar_config:consult(), + Config = rebar_config:consult_root(), Config1 = rebar_config:merge_locks(Config, rebar_config:consult_lock_file(?LOCK_FILE)), %% If $HOME/.config/rebar3/rebar.config exists load and use as global config diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index fd55960..db74cd3 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -7,8 +7,10 @@ find_unbuilt_apps/1, find_apps/1, find_apps/2, + find_apps/3, find_app/2, - find_app/3]). + find_app/3, + find_app/4]). -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). @@ -20,7 +22,9 @@ do(State, LibDirs) -> BaseDir = rebar_state:dir(State), 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), DepsDir = rebar_dir:deps_dir(State), CurrentProfiles = rebar_state:current_profiles(State), @@ -179,32 +183,44 @@ reset_hooks(Opts) -> rebar_opts:set(OptsAcc, Key, []) end, Opts, [post_hooks, pre_hooks, provider_hooks, artifacts]). -%% @doc find the directories for all apps --spec all_app_dirs([file:name()]) -> [file:name()]. +%% @private find the directories for all apps, while detecting their source dirs +%% Returns the app dir with the respective src_dirs for them, in that order, +%% for every app found. +-spec all_app_dirs([file:name()]) -> [{file:name(), [file:name()]}]. all_app_dirs(LibDirs) -> lists:flatmap(fun(LibDir) -> - app_dirs(LibDir) + SrcDirs = find_config_src(LibDir, ["src"]), + app_dirs(LibDir, SrcDirs) end, LibDirs). -%% @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"]), +%% @private find the directories for all apps based on their source dirs +%% Returns the app dir with the respective src_dirs for them, in that order, +%% for every app found. +-spec all_app_dirs([file:name()], [file:name()]) -> [{file:name(), [file:name()]}]. +all_app_dirs(LibDirs, SrcDirs) -> + lists:flatmap(fun(LibDir) -> app_dirs(LibDir, SrcDirs) end, LibDirs). + +%% @private find the directories based on the library directories. +%% Returns the app dir with the respective src_dirs for them, in that order, +%% for every app found. +%% +%% The function returns the src directories since they might have been +%% detected in a top-level loop and we want to skip further detection +%% starting now. +-spec app_dirs([file:name()], [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) -> - Files = filelib:wildcard(ec_cnv:to_list(Path)), - [app_dir(File) || File <- Files] ++ Acc - end, [], [Path1, Path2, Path3])). + Files = filelib:wildcard(ec_cnv:to_list(Path)), + [{app_dir(File), SrcDirs} + || File <- Files] ++ Acc + end, [], [EbinPath | Paths])). %% @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()]. @@ -222,16 +238,32 @@ find_apps(LibDirs) -> %% app info records. -spec find_apps([file:filename_all()], valid | invalid | all) -> [rebar_app_info:t()]. find_apps(LibDirs, Validate) -> - rebar_utils:filtermap(fun(AppDir) -> - find_app(AppDir, Validate) - end, all_app_dirs(LibDirs)). + rebar_utils:filtermap( + fun({AppDir, AppSrcDirs}) -> + find_app(rebar_app_info:new(), AppDir, AppSrcDirs, Validate) + end, + all_app_dirs(LibDirs) + ). + +%% @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, AppSrcDirs}) -> + find_app(rebar_app_info:new(), AppDir, AppSrcDirs, Validate) + end, + all_app_dirs(LibDirs, SrcDirs) + ). %% @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 %% app info record. -spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false. find_app(AppDir, Validate) -> - find_app(rebar_app_info:new(), AppDir, Validate). + SrcDirs = find_config_src(AppDir, ["src"]), + find_app(rebar_app_info:new(), AppDir, SrcDirs, Validate). %% @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 @@ -239,9 +271,29 @@ find_app(AppDir, Validate) -> -spec find_app(rebar_app_info:t(), file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false. find_app(AppInfo, AppDir, Validate) -> + %% if no src dir is passed, figure it out from the app info, with a default + %% of src/ + AppOpts = rebar_app_info:opts(AppInfo), + SrcDirs = rebar_dir:src_dirs(AppOpts, ["src"]), + find_app(AppInfo, AppDir, SrcDirs, 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"])), - 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). %% @doc find the directory that an appfile has @@ -358,3 +410,16 @@ enable(State, AppInfo) -> -spec to_atom(binary()) -> atom(). to_atom(Bin) -> list_to_atom(binary_to_list(Bin)). + +%% @private when looking for unknown apps, it's possible they have a +%% rebar.config file specifying non-standard src_dirs. Check for a +%% possible config file and extract src_dirs from it. +find_config_src(AppDir, Default) -> + case rebar_config:consult(AppDir) of + [] -> + Default; + Terms -> + %% TODO: handle profiles I guess, but we don't have that info + proplists:get_value(src_dirs, Terms, Default) + end. + diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index fdaadb8..62ec6dd 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -248,13 +248,12 @@ set(AppInfo=#app_info_t{opts=Opts}, Key, Value) -> %% @doc finds the .app.src file for an app, if any. -spec app_file_src(t()) -> file:filename_all() | undefined. -app_file_src(#app_info_t{app_file_src=undefined, dir=Dir, name=Name}) -> - AppFileSrc = filename:join([ec_cnv:to_list(Dir), "src", ec_cnv:to_list(Name)++".app.src"]), - case filelib:is_file(AppFileSrc) of - true -> - AppFileSrc; - false -> - undefined +app_file_src(#app_info_t{app_file_src=undefined, dir=Dir, name=Name, opts=Opts}) -> + CandidatePaths = [filename:join([ec_cnv:to_list(Dir), Src, ec_cnv:to_list(Name)++".app.src"]) + || Src <- rebar_opts:get(Opts, src_dirs, ["src"])], + case lists:dropwhile(fun(Path) -> not filelib:is_file(Path) end, CandidatePaths) of + [] -> undefined; + [AppFileSrc|_] -> AppFileSrc end; app_file_src(#app_info_t{app_file_src=AppFileSrc}) -> ec_cnv:to_list(AppFileSrc). diff --git a/src/rebar_config.erl b/src/rebar_config.erl index 97e27ab..82ff0d9 100644 --- a/src/rebar_config.erl +++ b/src/rebar_config.erl @@ -26,7 +26,7 @@ %% ------------------------------------------------------------------- -module(rebar_config). --export([consult/0 +-export([consult_root/0 ,consult/1 ,consult_app_file/1 ,consult_file/1 @@ -46,15 +46,15 @@ %% Public API %% =================================================================== -%% @doc reads the default config file. --spec consult() -> [any()]. -consult() -> +%% @doc reads the default config file at the top of a full project +-spec consult_root() -> [any()]. +consult_root() -> consult_file(config_file()). %% @doc reads the default config file in a given directory. -spec consult(file:name()) -> [any()]. consult(Dir) -> - consult_file(filename:join(Dir, config_file())). + consult_file(filename:join(Dir, ?DEFAULT_CONFIG_FILE)). %% @doc reads a given app file, including the `.script' variations, %% if any can be found. diff --git a/src/rebar_prv_clean.erl b/src/rebar_prv_clean.erl index 8f31fdd..d185f75 100644 --- a/src/rebar_prv_clean.erl +++ b/src/rebar_prv_clean.erl @@ -44,7 +44,8 @@ do(State) -> case All of true -> DepsDir = rebar_dir:deps_dir(State1), - AllApps = rebar_app_discover:find_apps([filename:join(DepsDir, "*")], all), + DepsDirs = filelib:wildcard(filename:join(DepsDir, "*")), + AllApps = rebar_app_discover:find_apps(DepsDirs, all), clean_apps(State1, Providers, AllApps); false -> ProjectApps = rebar_state:project_apps(State1), diff --git a/src/rebar_prv_plugins.erl b/src/rebar_prv_plugins.erl index 7e6b88e..c76dae1 100644 --- a/src/rebar_prv_plugins.erl +++ b/src/rebar_prv_plugins.erl @@ -34,14 +34,17 @@ do(State) -> GlobalConfigFile = rebar_dir:global_config(), GlobalConfig = rebar_state:new(rebar_config:consult_file(GlobalConfigFile)), GlobalPlugins = rebar_state:get(GlobalConfig, plugins, []), + GlobalSrcDirs = rebar_state:get(GlobalConfig, src_dirs, ["src"]), GlobalPluginsDir = filename:join([rebar_dir:global_cache_dir(rebar_state:opts(State)), "plugins", "*"]), - GlobalApps = rebar_app_discover:find_apps([GlobalPluginsDir], all), + GlobalApps = rebar_app_discover:find_apps([GlobalPluginsDir], GlobalSrcDirs, all), display_plugins("Global plugins", GlobalApps, GlobalPlugins), + RebarOpts = rebar_state:opts(State), + SrcDirs = rebar_dir:src_dirs(RebarOpts, ["src"]), Plugins = rebar_state:get(State, plugins, []), - PluginsDir = filename:join(rebar_dir:plugins_dir(State), "*"), - CheckoutsDir = filename:join(rebar_dir:checkouts_dir(State), "*"), - Apps = rebar_app_discover:find_apps([CheckoutsDir, PluginsDir], all), + PluginsDirs = filelib:wildcard(filename:join(rebar_dir:plugins_dir(State), "*")), + CheckoutsDirs = filelib:wildcard(filename:join(rebar_dir:checkouts_dir(State), "*")), + Apps = rebar_app_discover:find_apps(CheckoutsDirs++PluginsDirs, SrcDirs, all), display_plugins("Local plugins", Apps, Plugins), {ok, State}. |