From 781d4d76ac89d7184214e44523a720e23de781bc Mon Sep 17 00:00:00 2001 From: Pavel Khusainov Date: Wed, 29 Jul 2015 09:56:29 +0300 Subject: Possibility for plugins to create custom actions/tasks Before this commit user side provider wasn't able to create custom action. Now we're parsing actions/targets in `rlx_cmd_args` we didn't check them, just converting to atoms. In order to display error message about wrong action, we have to add another check in `relx:run_providers` function. --- src/relx.erl | 54 ++++++++++++++++++++++++++++++++++++---------------- src/rlx_cmd_args.erl | 46 +++++++++++++------------------------------- src/rlx_state.erl | 2 +- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/src/relx.erl b/src/relx.erl index eb3b969..d2dd797 100644 --- a/src/relx.erl +++ b/src/relx.erl @@ -224,6 +224,8 @@ format_error({opt_parse, {invalid_option, Opt}}) -> io_lib:format("invalid option ~s~n", [Opt]); format_error({opt_parse, Arg}) -> io_lib:format("~p~n", [Arg]); +format_error({invalid_action, Action}) -> + io_lib:format("Invalid action specified: ~p~n", [Action]); format_error({error, {relx, Reason}}) -> format_error(Reason); format_error({error, {Module, Reason}}) -> @@ -248,27 +250,47 @@ run_relx_process(State) -> run_providers(State0) -> case rlx_config:do(State0) of {ok, State1} -> - Actions = rlx_state:actions(State0), - + Actions = rlx_state:actions(State1), AllProviders = rlx_state:providers(State1), - TargetProviders = lists:flatmap(fun(Target) -> - providers:get_target_providers(Target, AllProviders) - end, Actions), - Providers1 = lists:map(fun(P) -> - providers:get_provider(P, AllProviders) - end, TargetProviders), - - %% Unique Sort Providers - Providers2 = providers:process_deps(Providers1, AllProviders), - - RootDir = rlx_state:root_dir(State1), - ok = file:set_cwd(RootDir), - Result = lists:foldl(fun run_provider/2, {ok, State1}, Providers2), - handle_output(State1, rlx_state:caller(State1), Result); + case check_actions_correctness(Actions, AllProviders) of + ok -> + run_providers_for_actions(Actions, State1); + Err -> + Err + end; Err -> Err end. +check_actions_correctness(Actions, Providers) -> + lists:foldl(fun(Action, ok) -> + case providers:get_provider(Action, Providers) of + not_found -> + ?RLX_ERROR({invalid_action, Action}); + _ -> + ok + end; + (_Action, Error) -> + Error + end, ok, Actions). + +run_providers_for_actions(Actions, State) -> + AllProviders = rlx_state:providers(State), + TargetProviders = lists:flatmap(fun(Target) -> + providers:get_target_providers(Target, AllProviders) + end, Actions), + Providers1 = lists:map(fun(P) -> + providers:get_provider(P, AllProviders) + end, TargetProviders), + + %% Unique Sort Providers + Providers2 = providers:process_deps(Providers1, AllProviders), + + RootDir = rlx_state:root_dir(State), + ok = file:set_cwd(RootDir), + Result = lists:foldl(fun run_provider/2, {ok, State}, Providers2), + handle_output(State, rlx_state:caller(State), Result). + handle_output(State, command_line, E={error, _}) -> report_error(State, E), init:stop(127); diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl index 309282e..b64c05d 100644 --- a/src/rlx_cmd_args.erl +++ b/src/rlx_cmd_args.erl @@ -33,19 +33,14 @@ {ok, {rlx_state:t(), [string()]}} | relx:error(). args2state(Opts, Targets) -> - case convert_targets(Targets) of - {ok, AtomizedTargets} -> - case run_creates(Opts) of - Error = {error, _} -> - Error; - {ok, CommandLineConfig} -> - RelName = rlx_util:to_atom(proplists:get_value(relname, Opts, undefined)), - RelVsn = proplists:get_value(relvsn, Opts, undefined), - handle_config(Opts, AtomizedTargets, - [{default_release, {RelName, RelVsn}} | CommandLineConfig]) - end; - Error -> - Error + case run_creates(Opts) of + Error = {error, _} -> + Error; + {ok, CommandLineConfig} -> + RelName = rlx_util:to_atom(proplists:get_value(relname, Opts, undefined)), + RelVsn = proplists:get_value(relvsn, Opts, undefined), + handle_config(Opts, convert_targets(Targets), + [{default_release, {RelName, RelVsn}} | CommandLineConfig]) end. -spec format_error(Reason::term()) -> iolist(). @@ -80,9 +75,7 @@ format_error({not_directory, Dir}) -> io_lib:format("Library directory does not exist: ~s", [Dir]); format_error({invalid_log_level, LogLevel}) -> io_lib:format("Invalid log level specified -V ~p, log level must be in the" - " range 0..3", [LogLevel]); -format_error({invalid_target, Target}) -> - io_lib:format("Invalid action specified: ~s", [Target]). + " range 0..3", [LogLevel]). %%%=================================================================== %%% Internal Functions @@ -102,24 +95,11 @@ handle_config(Opts, Targets, CommandLineConfig) -> end end. --spec convert_targets([string()]) -> {ok, [rlx_state:action()]} | relx:error(). +-spec convert_targets([string()]) -> [rlx_state:action()]. +convert_targets([]) -> + [release]; convert_targets(Targets) -> - convert_targets(Targets, []). - --spec convert_targets([string()], [rlx_state:action()]) -> - {ok, [rlx_state:action()]} | relx:error(). -convert_targets([], []) -> - {ok, [release]}; -convert_targets([], Acc) -> - {ok, lists:reverse(Acc)}; -convert_targets(["release" | T], Acc) -> - convert_targets(T, [release | Acc]); -convert_targets(["relup" | T], Acc) -> - convert_targets(T, [relup | Acc]); -convert_targets(["tar" | T], Acc) -> - convert_targets(T, [tar | Acc]); -convert_targets([Target | _T], _Acc) -> - ?RLX_ERROR({invalid_target, Target}). + lists:map(fun list_to_atom/1, Targets). -spec validate_config(file:filename() | list() | undefined) -> {ok, file:filename() | list() | undefined} | relx:error(). diff --git a/src/rlx_state.erl b/src/rlx_state.erl index 01bc07c..42cd730 100644 --- a/src/rlx_state.erl +++ b/src/rlx_state.erl @@ -125,7 +125,7 @@ rlx_release:t()). -type cmd_args() :: proplists:proplist(). -type caller() :: command_line | api. --type action() :: release | relup | tar. +-type action() :: atom(). -opaque t() :: #state_t{}. -- cgit v1.2.3