From 5a58c7dc317674dff20e267baecdb3414af516ff Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 18 Sep 2012 10:03:49 -0700 Subject: support arbitrary data in configs (per provider state) --- src/rcl_prv_config.erl | 23 +++++++++++++++++------ src/rcl_state.erl | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/rcl_prv_config.erl b/src/rcl_prv_config.erl index 6036097..3b92a3b 100644 --- a/src/rcl_prv_config.erl +++ b/src/rcl_prv_config.erl @@ -12,7 +12,7 @@ %% API -export([init/1, do/1, - format/1]). + format_error/1]). %%%=================================================================== @@ -24,15 +24,18 @@ init(State) -> {ok, State}. -%% @doc -%% +%% @doc parse all the configs currently specified in the state, +%% populating the state as a result. -spec do(rcl_state:t()) ->{ok, rcl_state:t()} | {error, Reason::term()}. do(State) -> ConfigFiles = rcl_state:config_files(State), lists:foldl(fun load_config/2, {ok, State}, ConfigFiles). -format({error, {consult, Reason}}) -> - file:format_error(Reason). +-spec format_error({error, Reason::term()}) -> iolist(). +format_error({error, {consult, Reason}}) -> + file:format_error(Reason); +format_error({error, {invalid_term, Term}}) -> + io_lib:format("Invalid term in config file: ~p", [Term]). %%%=================================================================== %%% Internal Functions @@ -51,6 +54,8 @@ load_config(ConfigFile, {ok, State}) -> ok = file:set_cwd(CurrentCwd), Result. +load_terms({default_release, RelName, RelVsn}, {ok, State}) -> + {ok, rcl_state:default_release(State, RelName, RelVsn)}; load_terms({paths, Paths}, {ok, State}) -> code:add_pathsa([filename:absname(Path) || Path <- Paths]), {ok, State}; @@ -88,7 +93,13 @@ load_terms({release, {RelName, Vsn}, {erts, ErtsVsn}, E; {ok, Release1} -> {ok, rcl_state:add_release(State, Release1)} - end. + end; +load_terms({Name, Value}, {ok, State}) + when erlang:is_atom(Name) -> + {ok, rcl_state:put(State, Name, Value)}; +load_terms(InvalidTerm, _) -> + {error, {invalid_term, InvalidTerm}}. + gen_providers(Providers, State) -> lists:foldl(fun(ProviderName, {Providers1, {ok, State1}}) -> diff --git a/src/rcl_state.erl b/src/rcl_state.erl index c399b42..d16eadf 100644 --- a/src/rcl_state.erl +++ b/src/rcl_state.erl @@ -38,6 +38,9 @@ default_release/3, available_apps/1, available_apps/2, + get/2, + get/3, + put/3, format/1, format/2]). @@ -57,7 +60,9 @@ default_release :: {rcl_release:name(), rcl_release:vsn()}, releases :: ec_dictionary:dictionary({ReleaseName::atom(), ReleaseVsn::string()}, - rcl_release:t())}). + rcl_release:t()), + config_values :: ec_dictionary:dictionary(Key::atom(), + Value::term())}). %%============================================================================ %% types @@ -84,7 +89,8 @@ new(PropList, Targets) when erlang:is_list(PropList) -> config_files=Targets, goals=proplists:get_value(goals, PropList, []), providers = [], - releases=ec_dictionary:new(ec_dict)}, + releases=ec_dictionary:new(ec_dict), + config_values=ec_dictionary:new(ec_dict)}, create_logic_providers(State0). %% @doc get the current log state for the system @@ -147,6 +153,26 @@ available_apps(#state_t{available_apps=Apps}) -> available_apps(M, NewApps) -> M#state_t{available_apps=NewApps}. +-spec get(t(), atom()) -> term(). +get(#state_t{config_values=Config}, Key) + when erlang:is_atom(Key) -> + ec_dictionary:get(Key, Config). + +-spec get(t(), atom(), DefaultValue::term()) -> term(). +get(#state_t{config_values=Config}, Key, DefaultValue) + when erlang:is_atom(Key) -> + try + ec_dictionary:get(Key, Config) + catch + throw:not_found -> + DefaultValue + end. + +-spec put(t(), atom(), term()) ->t(). +put(M=#state_t{config_values=Config}, Key, Value) + when erlang:is_atom(Key) -> + M#state_t{config_values=ec_dictionary:add(Key, Value, Config)}. + -spec format(t()) -> iolist(). format(Mod) -> format(Mod, 0). @@ -167,7 +193,9 @@ format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs, rcl_util:indent(Indent + 1), "lib_dirs: \n", [[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]]. + [[rcl_util:indent(Indent + 2), rcl_provider:format(Provider), ",\n"] || Provider <- Providers], + rcl_util:indent(Indent + 1), "provider config values: \n", + [[rcl_util:indent(Indent + 2), io_lib:format("~p", [Value]), ",\n"] || Value <- Values1]]. %%%=================================================================== %%% Internal Functions @@ -186,7 +214,8 @@ get_lib_dirs(CmdDirs) -> 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]}. + {ReleaseProvider, {ok, State3}} = rcl_provider:new(rcl_prv_release, State2), + State3#state_t{providers=[ConfigProvider, DiscoveryProvider, ReleaseProvider]}. %%%=================================================================== %%% Test Functions -- cgit v1.2.3