aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Khusainov <[email protected]>2015-07-29 09:56:29 +0300
committerPavel Khusainov <[email protected]>2015-07-29 09:56:29 +0300
commit781d4d76ac89d7184214e44523a720e23de781bc (patch)
tree5aac813bace96fdcff1c4873414377bbbb40c05c
parentc67a6b7b4265b9c28fcbc785125c7538ed9b2b8d (diff)
downloadrelx-781d4d76ac89d7184214e44523a720e23de781bc.tar.gz
relx-781d4d76ac89d7184214e44523a720e23de781bc.tar.bz2
relx-781d4d76ac89d7184214e44523a720e23de781bc.zip
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.
-rw-r--r--src/relx.erl54
-rw-r--r--src/rlx_cmd_args.erl46
-rw-r--r--src/rlx_state.erl2
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{}.