From f74f15b95c7dd6b27cd415909cf644977ebb88c1 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 3 Nov 2014 20:47:43 -0600 Subject: split release and app discovery into two separate providers --- src/rlx_prv_app_discover.erl | 125 +++++++++++++++++++++++++++++++++++++++++++ src/rlx_prv_rel_discover.erl | 97 +++++++++++++++++++++++++++++++++ src/rlx_prv_release.erl | 6 +-- src/rlx_prv_relup.erl | 2 +- 4 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 src/rlx_prv_app_discover.erl create mode 100644 src/rlx_prv_rel_discover.erl diff --git a/src/rlx_prv_app_discover.erl b/src/rlx_prv_app_discover.erl new file mode 100644 index 0000000..154908c --- /dev/null +++ b/src/rlx_prv_app_discover.erl @@ -0,0 +1,125 @@ +%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*- +%%% Copyright 2012 Erlware, LLC. All Rights Reserved. +%%% +%%% This file is provided to you under the Apache License, +%%% Version 2.0 (the "License"); you may not use this file +%%% except in compliance with the License. You may obtain +%%% a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, +%%% software distributed under the License is distributed on an +%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%%% KIND, either express or implied. See the License for the +%%% specific language governing permissions and limitations +%%% under the License. +%%%--------------------------------------------------------------------------- +%%% @author Eric Merritt +%%% @copyright (C) 2012 Erlware, LLC. +%%% +%%% @doc This provider uses the lib_dir setting of the state. It searches the +%%% Lib Dirs looking for all OTP Applications that are available. When it finds +%%% those OTP Applications it loads the information about them and adds them to +%%% the state of available apps. This implements the provider behaviour. +-module(rlx_prv_app_discover). + +-behaviour(provider). + +-export([init/1, + do/1, + format_error/2]). + +-include("relx.hrl"). + +-define(PROVIDER, app_discover). +-define(DEPS, []). + +%%============================================================================ +%% API +%%============================================================================ + +-spec init(rlx_state:t()) -> {ok, rlx_state:t()}. +init(State) -> + State1 = rlx_state:add_provider(State, providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {bare, false}, + {deps, ?DEPS}, + {example, "build"}, + {short_desc, ""}, + {desc, ""}, + {opts, []}])), + {ok, State1}. + +%% @doc recursively dig down into the library directories specified in the state +%% looking for OTP Applications +-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error(). +do(State0) -> + LibDirs = get_lib_dirs(State0), + case rlx_app_discovery:do(State0, LibDirs) of + {ok, AppMeta} -> + State1 = rlx_state:available_apps(State0, AppMeta), + {ok, State1}; + Error -> + Error + end. + +%% @doc this is here to comply with the signature. However, we do not actually +%% produce any errors and so simply return an empty string. +-spec format_error(any(), rlx_state:t()) -> iolist(). +format_error(_, _) -> + "". + +%%%=================================================================== +%%% Internal Functions +%%%=================================================================== + +get_lib_dirs(State) -> + LibDirs0 = rlx_state:lib_dirs(State), + case rlx_state:get(State, default_libs, true) of + false -> + LibDirs0; + true -> + lists:flatten([LibDirs0, + add_common_project_dirs(State), + add_system_lib_dir(State)]) + end. + +-spec add_common_project_dirs(rlx_state:t()) -> [file:name()]. +add_common_project_dirs(State) -> + %% Check to see if there is a rebar.config. If so then look for a deps + %% dir. If both are there then we add that to the lib dirs. + case rlx_state:get(State, disable_project_subdirs, false) of + true -> + []; + false -> + Root = rlx_state:root_dir(State), + Apps = filename:join(Root, "apps"), + Lib = filename:join(Root, "lib"), + Deps = filename:join(Root, "deps"), + Rebar3Deps = filename:join(Root, "_deps"), + Ebin = filename:join(Root, "ebin"), + lists:foldl(fun(Dir, LibDirs) -> + case ec_file:exists(Dir) of + true -> + [erlang:iolist_to_binary(Dir) | LibDirs]; + false -> + LibDirs + end + end, [], [Rebar3Deps, Deps, Lib, Apps, Ebin]) + end. + +-spec add_system_lib_dir(rlx_state:t()) -> [file:name()]. +add_system_lib_dir(State) -> + ExcludeSystem = rlx_state:get(State, discover_exclude_system, false), + case rlx_state:get(State, system_libs, undefined) of + undefined -> + case ExcludeSystem of + true -> + []; + false -> + erlang:iolist_to_binary(code:lib_dir()) + end; + SystemLibs -> + erlang:iolist_to_binary(SystemLibs) + end. diff --git a/src/rlx_prv_rel_discover.erl b/src/rlx_prv_rel_discover.erl new file mode 100644 index 0000000..8b6fd88 --- /dev/null +++ b/src/rlx_prv_rel_discover.erl @@ -0,0 +1,97 @@ +%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*- +%%% Copyright 2012 Erlware, LLC. All Rights Reserved. +%%% +%%% This file is provided to you under the Apache License, +%%% Version 2.0 (the "License"); you may not use this file +%%% except in compliance with the License. You may obtain +%%% a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, +%%% software distributed under the License is distributed on an +%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%%% KIND, either express or implied. See the License for the +%%% specific language governing permissions and limitations +%%% under the License. +%%%--------------------------------------------------------------------------- +%%% @author Eric Merritt +%%% @copyright (C) 2012 Erlware, LLC. +%%% +-module(rlx_prv_rel_discover). +-behaviour(provider). + +-export([init/1, + do/1, + format_error/2]). + +-include("relx.hrl"). + +-define(PROVIDER, rel_discover). +-define(DEPS, [app_discover]). + +%%============================================================================ +%% API +%%============================================================================ + +-spec init(rlx_state:t()) -> {ok, rlx_state:t()}. +init(State) -> + State1 = rlx_state:add_provider(State, providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {bare, false}, + {deps, ?DEPS}, + {example, "build"}, + {short_desc, ""}, + {desc, ""}, + {opts, []}])), + {ok, State1}. + +-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error(). +do(State0) -> + LibDirs = get_lib_dirs(State0), + AppMeta = rlx_state:available_apps(State0), + case rlx_rel_discovery:do(State0, LibDirs, AppMeta) of + {ok, Releases} -> + {ok, rlx_state:realized_releases(State0, lists:foldl(fun add/2, + ec_dictionary:new(ec_dict), + Releases))}; + Error -> + Error + end. + +-spec format_error(any(), rlx_state:t()) -> iolist(). +format_error(_, _) -> + "". + +%%%=================================================================== +%%% Internal Functions +%%%=================================================================== +%% @doc only add the release if its not documented in the system +add(Rel, Dict) -> + RelName = rlx_release:name(Rel), + RelVsn = rlx_release:vsn(Rel), + ec_dictionary:add({RelName, RelVsn}, Rel, Dict). + +get_lib_dirs(State) -> + LibDirs0 = rlx_state:lib_dirs(State), + case rlx_state:get(State, default_libs, true) of + false -> + LibDirs0; + true -> + lists:flatten([LibDirs0, + add_release_output_dir(State)]) + end. + +add_release_output_dir(State) -> + case rlx_state:get(State, disable_discover_release_output, false) of + true -> + []; + false -> + Output = erlang:iolist_to_binary(rlx_state:base_output_dir(State)), + case ec_file:exists(erlang:binary_to_list(Output)) of + true -> + Output; + false -> + [] + end + end. diff --git a/src/rlx_prv_release.erl b/src/rlx_prv_release.erl index bd5acc4..02a9758 100644 --- a/src/rlx_prv_release.erl +++ b/src/rlx_prv_release.erl @@ -18,10 +18,6 @@ %%% @author Eric Merritt %%% @copyright (C) 2012 Erlware, LLC. %%% -%%% @doc This provider uses the lib_dir setting of the state. It searches the -%%% Lib Dirs looking for all OTP Applications that are available. When it finds -%%% those OTP Applications it loads the information about them and adds them to -%%% the state of available apps. This implements the provider behaviour. -module(rlx_prv_release). -behaviour(provider). @@ -33,7 +29,7 @@ -include("relx.hrl"). -define(PROVIDER, resolve_release). --define(DEPS, [discover]). +-define(DEPS, [app_discover]). %%============================================================================ %% API diff --git a/src/rlx_prv_relup.erl b/src/rlx_prv_relup.erl index df6f831..0888c0c 100644 --- a/src/rlx_prv_relup.erl +++ b/src/rlx_prv_relup.erl @@ -31,7 +31,7 @@ -include("relx.hrl"). -define(PROVIDER, relup). --define(DEPS, [release]). +-define(DEPS, [rel_discover, release]). %%============================================================================ %% API -- cgit v1.2.3