Current section

Files

Jump to
rebar3_hex src rebar3_hex.erl
Raw

src/rebar3_hex.erl

%% @private
-module(rebar3_hex).
-export([ init/1
, get_args/1
, gather_opts/2
, get_required/2
, task_args/1
, task_state/1
, task_state/2
, repo_opt/0
, help_opt/0
]).
-export([to_atom/1, to_list/1, to_binary/1]).
-type task() :: #{raw_opts := proplists:proplist(),
raw_args := list(),
args := map(),
repo := map(),
apps := [rebar_app_info:t()],
state := rebar_state:t(),
multi_app := boolean()
}.
-export_type([task/0]).
init(State) ->
lists:foldl(fun provider_init/2, {ok, State}, [rebar3_hex_user,
rebar3_hex_build,
rebar3_hex_cut,
rebar3_hex_owner,
rebar3_hex_organization,
rebar3_hex_search,
rebar3_hex_retire,
rebar3_hex_publish]).
provider_init(Module, {ok, State}) ->
Module:init(State).
gather_opts(Targets, State) ->
{Args, _} = rebar_state:command_parsed_args(State),
lists:foldl(fun(T, Acc) ->
case proplists:get_value(T, Args, undefined) of
undefined ->
Acc;
V ->
maps:put(T, V, Acc)
end
end, #{}, Targets).
get_required(Key, Args) ->
case proplists:get_value(Key, Args) of
undefined ->
{error, {required, Key}};
Value ->
Value
end.
task_args(State) ->
{Opts, _Args} = rebar_state:command_parsed_args(State),
case proplists:get_value(task, Opts, undefined) of
undefined ->
{undefined, Opts};
Task ->
{Task, proplists:delete(task, Opts)}
end.
%% TODO: A current limitation of rebar3_hex:task_state/1 is it returns strings.
%% This will need to be adjusted to return binaries. For now, we return the opts and args
%% as returned from rebar_state:command_parsed_args/1 as raw_args and raw_opts.
-spec task_state(rebar_state:t()) -> {ok, task()} | {error, term()}.
task_state(State) ->
case rebar3_hex_config:repo(State) of
{ok, Repo} ->
{ok, task_state(State, Repo)};
Err ->
Err
end.
-spec task_state(rebar_state:t(), map()) -> task().
task_state(State, Repo) ->
{Opts0, Args0} = rebar_state:command_parsed_args(State),
Opts = get_args(State),
CurrentTask = maps:get(task, Opts, undefined),
Opts1 = Opts#{task => CurrentTask},
case rebar_state:project_apps(State) of
[] ->
#{raw_opts => Opts0, raw_args => Args0, args => Opts1, repo => Repo, state => State, multi_app => false, apps => []};
[_App] = Apps ->
#{raw_opts => Opts0, raw_args => Args0, args => Opts1, repo => Repo, state => State, multi_app => false, apps => Apps};
[_|_] = Apps ->
#{raw_opts => Opts0, raw_args => Args0, args => Opts1, repo => Repo, state => State, multi_app => true, apps => Apps}
end.
-spec get_args(rebar_state:t()) -> map().
get_args(State) ->
{Opts, Args} = rebar_state:command_parsed_args(State),
Opts1 = lists:foldl(fun (Arg, Acc) ->
case is_atom(Arg) of
true ->
[{Arg, true} | Acc];
_ ->
case Arg of
{task, Task} ->
[{task, list_to_atom(Task)} | Acc];
_ ->
[Arg | Acc]
end
end
end,
[],
Opts),
Opts2 = lists:foldl(fun (Arg, Acc) ->
case is_atom(Arg) of
true ->
[{Arg, true} | Acc];
_ ->
[{list_to_atom(Arg), true} | Acc]
end
end,
Opts1,
Args),
maps:from_list(Opts2).
help_opt() ->
{help, $h, "help", undefined, "Help"}.
repo_opt() ->
{repo, $r, "repo", string, "Repository to use for this command."}.
to_binary(A) when is_atom(A) -> atom_to_binary(A, unicode);
to_binary(Str) -> unicode:characters_to_binary(Str).
to_list(A) when is_atom(A) -> atom_to_list(A);
to_list(B) when is_binary(B) -> unicode:characters_to_list(B);
to_list(I) when is_integer(I) -> integer_to_list(I);
to_list(Str) -> unicode:characters_to_list(Str).
to_atom(B) when is_binary(B) -> binary_to_atom(B, utf8);
to_atom(Str) when is_list(Str) -> list_to_atom(Str);
to_atom(A) when is_atom(A) -> A.