From 0516b405ccb98febcf94a8e94000f4a633569f59 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 15 Jun 2014 19:18:14 -0500 Subject: provider task dependencies --- src/rlx_state.erl | 113 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 49 deletions(-) (limited to 'src/rlx_state.erl') diff --git a/src/rlx_state.erl b/src/rlx_state.erl index 267d9fe..71b96f3 100644 --- a/src/rlx_state.erl +++ b/src/rlx_state.erl @@ -44,6 +44,10 @@ cli_args/2, providers/1, providers/2, + add_provider/2, + prepend_hook/3, + append_hook/3, + hooks/2, vm_args/1, vm_args/2, sys_config/1, @@ -91,7 +95,7 @@ config_file=[] :: file:filename() | undefined, cli_args=[] :: proplists:proplist(), goals=[] :: [rlx_depsolver:constraint()], - providers=[] :: [rlx_provider:t()], + providers=[] :: [providers:t()], available_apps=[] :: [rlx_app_info:t()], default_configured_release :: {rlx_release:name() | undefined, rlx_release:vsn() |undefined} | undefined, vm_args :: file:filename() | undefined, @@ -122,11 +126,11 @@ %%============================================================================ %% API %%============================================================================ --spec new(string(), undefined | [atom()]) -> t(). +-spec new(string(), undefined | [atom()]) -> t() | relx:error(). new(Config, Targets) -> new(Config, [], Targets). --spec new(string(), proplists:proplist(), undefined | [atom()]) -> t(). +-spec new(string(), proplists:proplist(), undefined | [atom()]) -> t() | relx:error(). new(Config, CommandLineConfig, undefined) -> new(Config, CommandLineConfig, [release]); new(Config, CommandLineConfig, Targets) @@ -151,6 +155,7 @@ new(Config, CommandLineConfig, Targets) State1 = rlx_state:put(State0, default_libs, true), State2 = rlx_state:put(State1, system_libs, undefined), State3 = rlx_state:put(State2, overlay_vars, []), + create_logic_providers(State3). %% @doc the actions targeted for this system @@ -227,7 +232,7 @@ cli_args(#state_t{cli_args=CliArgs}) -> cli_args(State, CliArgs) -> State#state_t{cli_args=CliArgs}. --spec providers(t()) -> [rlx_provider:t()]. +-spec providers(t()) -> [providers:t()]. providers(#state_t{providers=Providers}) -> Providers. @@ -255,10 +260,14 @@ root_dir(#state_t{root_dir=RootDir}) -> root_dir(State, RootDir) -> State#state_t{root_dir=filename:absname(RootDir)}. --spec providers(t(), [rlx_provider:t()]) -> t(). +-spec providers(t(), [providers:t()]) -> t(). providers(M, NewProviders) -> M#state_t{providers=NewProviders}. +-spec add_provider(t(), providers:t()) -> t(). +add_provider(M=#state_t{providers=Providers}, Provider) -> + M#state_t{providers=[Provider | Providers]}. + -spec add_configured_release(t(), rlx_release:t()) -> t(). add_configured_release(M=#state_t{configured_releases=Releases}, Release) -> M#state_t{configured_releases=ec_dictionary:add({rlx_release:name(Release), @@ -390,55 +399,61 @@ format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs, rlx_util:indent(Indent + 2), "lib_dirs: \n", [[rlx_util:indent(Indent + 3), LibDir, ",\n"] || LibDir <- LibDirs], rlx_util:indent(Indent + 2), "providers: \n", - [[rlx_util:indent(Indent + 3), rlx_provider:format(Provider), ",\n"] || Provider <- Providers], + [[rlx_util:indent(Indent + 3), providers:format(Provider), ",\n"] || Provider <- Providers], rlx_util:indent(Indent + 2), "provider config values: \n", [[rlx_util:indent(Indent + 3), io_lib:format("~p", [Value]), ",\n"] || Value <- Values1]]. -%%%=================================================================== -%%% Internal Functions -%%%=================================================================== - --spec create_logic_providers(t()) -> t(). -create_logic_providers(State0) -> - {ConfigProvider, {ok, State1}} = rlx_provider:new(rlx_prv_config, State0), - {DiscoveryProvider, {ok, State2}} = rlx_provider:new(rlx_prv_discover, State1), - {ReleaseProvider, {ok, State3}} = rlx_provider:new(rlx_prv_release, State2), - {OverlayProvider, {ok, State4}} = rlx_provider:new(rlx_prv_overlay, State3), - {ActionProviders, State5} = add_providers([release, relup, tar], State4), - State5#state_t{providers=[ConfigProvider, DiscoveryProvider, - ReleaseProvider, OverlayProvider | ActionProviders]}. - -add_providers(Actions, State) -> - add_providers(Actions, [], State). - -add_providers([], Providers, State) -> - {lists:reverse(Providers), State}; -add_providers([Action | T], Providers, State) -> - case lists:member(Action, actions(State)) of - true -> - {Provider, {ok, State1}} = new_provider(Action, State), - add_providers(T, [Provider | Providers], State1); - false -> - add_providers(T, Providers, State) +prepend_hook(State=#state_t{providers=_Providers}, Target, Hook) -> + {Providers1, State1} = add_hook(pre, Target, Hook, State), + State1#state_t{providers=Providers1}. + +append_hook(State=#state_t{providers=_Providers}, Target, Hook) -> + {Providers1, State1} = add_hook(post, Target, Hook, State), + State1#state_t{providers=Providers1}. + +-spec hooks(t(), atom()) -> {[providers:t()], [providers:t()]}. +hooks(_State=#state_t{providers=Providers}, Target) -> + Provider = providers:get_provider(Target, Providers), + providers:hooks(Provider). + +%% =================================================================== +%% Internal functions +%% =================================================================== + +add_hook(Which, Target, Hook, State) -> + {ok, State1} = providers:new(Hook, State), + Providers1 = providers(State1), + HookProvider = providers:get_provider_by_module(Hook, Providers1), + Provider = providers:get_provider(Target, Providers1), + Hooks = providers:hooks(Provider), + NewHooks = add_hook(Which, Hooks, HookProvider), + NewProvider = providers:hooks(Provider, NewHooks), + {[NewProvider | lists:delete(Provider, Providers1)], State1}. + +add_hook(pre, {PreHooks, PostHooks}, Hook) -> + {[Hook | PreHooks], PostHooks}; +add_hook(post, {PreHooks, PostHooks}, Hook) -> + {PreHooks, [Hook | PostHooks]}. + +-spec create_logic_providers(t()) -> t() | relx:error(). +create_logic_providers(State) -> + create_all(State, [rlx_prv_discover, + rlx_prv_overlay, + rlx_prv_release, + rlx_prv_assembler, + rlx_prv_relup, + rlx_prv_archive]). + +create_all(State, []) -> + State; +create_all(State, [Module | Rest]) -> + case providers:new(Module, State) of + {ok, State1} -> + create_all(State1, Rest); + Error -> + Error end. -new_provider(release, State) -> - rlx_provider:new(rlx_prv_assembler, State); -new_provider(relup, State) -> - rlx_provider:new(rlx_prv_relup, State); -new_provider(tar, State) -> - rlx_provider:new(rlx_prv_archive, State). - %%%=================================================================== %%% Test Functions %%%=================================================================== - --ifndef(NOTEST). --include_lib("eunit/include/eunit.hrl"). - -new_test() -> - LogState = ec_cmd_log:new(error), - RCLState = new("", [{log, LogState}], [release]), - ?assertMatch(LogState, log(RCLState)). - --endif. -- cgit v1.2.3