aboutsummaryrefslogtreecommitdiffstats
path: root/src/rcl_state.erl
diff options
context:
space:
mode:
authorEric <[email protected]>2012-09-12 16:27:41 -0500
committerEric <[email protected]>2012-09-12 16:27:41 -0500
commit2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb (patch)
tree6356c02752681f522fae2d843d0a97151e6af7bf /src/rcl_state.erl
parent152a385e6cc6de064e2a0f1b1ef3061826598180 (diff)
downloadrelx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.tar.gz
relx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.tar.bz2
relx-2311bc5cbe06dcf2cb03d9b0a93392e1d9095bbb.zip
support OTP App discovery in the system
Diffstat (limited to 'src/rcl_state.erl')
-rw-r--r--src/rcl_state.erl120
1 files changed, 104 insertions, 16 deletions
diff --git a/src/rcl_state.erl b/src/rcl_state.erl
index 1b25ce3..c399b42 100644
--- a/src/rcl_state.erl
+++ b/src/rcl_state.erl
@@ -29,24 +29,47 @@
lib_dirs/1,
goals/1,
config_files/1,
+ providers/1,
+ providers/2,
+ add_release/2,
+ get_release/3,
+ releases/1,
+ default_release/1,
+ default_release/3,
+ available_apps/1,
+ available_apps/2,
format/1,
format/2]).
+
-export_type([t/0,
+ app_descriptor/0,
+ releases/0,
cmd_args/0]).
--record(?MODULE, {log :: rcl_log:t(),
+-record(state_t, {log :: rcl_log:t(),
output_dir :: file:name(),
lib_dirs=[] :: [file:name()],
config_files=[] :: [file:filename()],
- goals=[] :: [depsolver:constraint()]}).
+ goals=[] :: [depsolver:constraint()],
+ providers = [] :: [rcl_provider:t()],
+ available_apps = [] :: [app_descriptor()],
+ default_release :: {rcl_release:name(), rcl_release:vsn()},
+ releases :: ec_dictionary:dictionary({ReleaseName::atom(),
+ ReleaseVsn::string()},
+ rcl_release:t())}).
%%============================================================================
%% types
%%============================================================================
+-type app_descriptor() :: {rcl_release:app_name(), rcl_release:app_vsn(), file:name()}.
+
+-type releases() :: ec_dictionary:dictionary({rcl_release:name(),
+ rcl_release:vsn()},
+ rcl_release:t()).
-type cmd_args() :: proplists:proplist().
--opaque t() :: record(?MODULE).
+-opaque t() :: record(state_t).
%%============================================================================
%% API
@@ -54,40 +77,84 @@
%% @doc Create a new 'log level' for the system
-spec new(proplists:proplist(), [file:filename()]) -> t().
new(PropList, Targets) when erlang:is_list(PropList) ->
- #?MODULE{log = proplists:get_value(log, PropList, rcl_log:new(error)),
- output_dir=proplists:get_value(output_dir, PropList, ""),
- lib_dirs=proplists:get_value(lib_dirs, PropList, []),
- config_files=Targets,
- goals=proplists:get_value(goals, PropList, [])}.
+ State0 =
+ #state_t{log = proplists:get_value(log, PropList, rcl_log:new(error)),
+ output_dir=proplists:get_value(output_dir, PropList, ""),
+ lib_dirs=get_lib_dirs(proplists:get_value(lib_dirs, PropList, [])),
+ config_files=Targets,
+ goals=proplists:get_value(goals, PropList, []),
+ providers = [],
+ releases=ec_dictionary:new(ec_dict)},
+ create_logic_providers(State0).
%% @doc get the current log state for the system
-spec log(t()) -> rcl_log:t().
-log(#?MODULE{log=LogState}) ->
+log(#state_t{log=LogState}) ->
LogState.
-spec output_dir(t()) -> file:name().
-output_dir(#?MODULE{output_dir=OutDir}) ->
+output_dir(#state_t{output_dir=OutDir}) ->
OutDir.
-spec lib_dirs(t()) -> [file:name()].
-lib_dirs(#?MODULE{lib_dirs=LibDir}) ->
+lib_dirs(#state_t{lib_dirs=LibDir}) ->
LibDir.
-spec goals(t()) -> [depsolver:constraints()].
-goals(#?MODULE{goals=TS}) ->
+goals(#state_t{goals=TS}) ->
TS.
-spec config_files(t()) -> [file:filename()].
-config_files(#?MODULE{config_files=ConfigFiles}) ->
+config_files(#state_t{config_files=ConfigFiles}) ->
ConfigFiles.
+-spec providers(t()) -> [rcl_provider:t()].
+providers(#state_t{providers=Providers}) ->
+ Providers.
+
+-spec providers(t(), [rcl_provider:t()]) -> t().
+providers(M, NewProviders) ->
+ M#state_t{providers=NewProviders}.
+
+-spec add_release(t(), rcl_release:t()) -> t().
+add_release(M=#state_t{releases=Releases}, Release) ->
+ M#state_t{releases=ec_dictionary:add({rcl_release:name(Release),
+ rcl_release:vsn(Release)},
+ Release,
+ Releases)}.
+
+-spec get_release(t(), rcl_release:name(), rcl_release:vsn()) -> rcl_release:t().
+get_release(#state_t{releases=Releases}, Name, Vsn) ->
+ ec_dictionary:get({Name, Vsn}, Releases).
+
+-spec releases(t()) -> releases().
+releases(#state_t{releases=Releases}) ->
+ Releases.
+
+-spec default_release(t()) -> {rcl_release:name(), rcl_release:vsn()}.
+default_release(#state_t{default_release=Def}) ->
+ Def.
+
+-spec default_release(t(), rcl_release:name(), rcl_release:vsn()) -> t().
+default_release(M, Name, Vsn) ->
+ M#state_t{default_release={Name, Vsn}}.
+
+-spec available_apps(t()) -> [app_descriptor()].
+available_apps(#state_t{available_apps=Apps}) ->
+ Apps.
+
+-spec available_apps(t(), [app_descriptor()]) -> t().
+available_apps(M, NewApps) ->
+ M#state_t{available_apps=NewApps}.
+
-spec format(t()) -> iolist().
format(Mod) ->
format(Mod, 0).
-spec format(t(), non_neg_integer()) -> iolist().
-format(#?MODULE{log=LogState, output_dir=OutDir, lib_dirs=LibDirs,
- goals=Goals, config_files=ConfigFiles},
+format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs,
+ goals=Goals, config_files=ConfigFiles,
+ providers=Providers},
Indent) ->
[rcl_util:indent(Indent),
<<"state:\n">>,
@@ -98,7 +165,28 @@ format(#?MODULE{log=LogState, output_dir=OutDir, lib_dirs=LibDirs,
[[rcl_util:indent(Indent + 2), depsolver:format_constraint(Goal), ",\n"] || Goal <- Goals],
rcl_util:indent(Indent + 1), "output_dir: ", OutDir, "\n",
rcl_util:indent(Indent + 1), "lib_dirs: \n",
- [[rcl_util:indent(Indent + 2), LibDir, ",\n"] || LibDir <- LibDirs]].
+ [[rcl_util:indent(Indent + 2), LibDir, ",\n"] || LibDir <- LibDirs],
+ rcl_util:indent(Indent + 1), "providers: \n",
+ [[rcl_util:indent(Indent + 2), rcl_provider:format(Provider), ",\n"] || Provider <- Providers]].
+
+%%%===================================================================
+%%% Internal Functions
+%%%===================================================================
+-spec get_lib_dirs([file:name()]) -> [file:name()].
+get_lib_dirs(CmdDirs) ->
+ case os:getenv("ERL_LIBS") of
+ false ->
+ CmdDirs;
+ EnvString ->
+ [Lib || Lib <- re:split(EnvString, ":|;"),
+ filelib:is_dir(Lib)] ++ CmdDirs
+ end.
+
+-spec create_logic_providers(t()) -> t().
+create_logic_providers(State0) ->
+ {ConfigProvider, {ok, State1}} = rcl_provider:new(rcl_prv_config, State0),
+ {DiscoveryProvider, {ok, State2}} = rcl_provider:new(rcl_prv_discover, State1),
+ State2#state_t{providers=[ConfigProvider, DiscoveryProvider]}.
%%%===================================================================
%%% Test Functions