Packages

Elixir Module and Struct Interoperability for Erlang

Current section

Files

Jump to
exat src exat_rebar3_plugin.erl
Raw

src/exat_rebar3_plugin.erl

-module(exat_rebar3_plugin).
-export([init/1, do/1, format_error/1]).
-define(PROVIDER, exat).
-define(DEPS, [compile]).
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider = providers:create([
{name, ?PROVIDER}, % The 'user friendly' name of the task
{module, ?MODULE}, % The module implementation of the task
{bare, true}, % The task can be run by the user, always true
{deps, ?DEPS}, % The list of dependencies
{example, "rebar3 exat"}, % How to use the plugin
{opts, []}, % list of options understood by the plugin
{short_desc, "A rebar plugin"},
{desc, "A rebar plugin"}
]),
{ok, rebar_state:add_provider(State, Provider)}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
ErlOpts = rebar_state:get(State, erl_opts, []),
ExatOpts = proplists:get_value(exat_opts, ErlOpts, #{}),
Apps = case rebar_state:current_app(State) of
undefined ->
rebar_state:project_apps(State);
AppInfo ->
[AppInfo]
end,
[begin
%Opts = rebar_app_info:opts(AppInfo),
%InDir = rebar_app_info:out_dir(AppInfo),
%BaseDir = filename:join(InDir, "exat_protos"),
OutDir = rebar_app_info:ebin_dir(AppInfo),
AppName = rebar_app_info:name(AppInfo),
BaseDir = filename:join(maps:get(output_path, ExatOpts, "./"), "exat"),
rebar_api:info("Compiling Erlang Protocols for app '~s'", [AppName]),
R = compile_protos(BaseDir, OutDir, ExatOpts),
rebar_api:debug(" Result ~p", [R]),
R
end || AppInfo <- Apps],
{ok, State}.
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
%% private api
compile_protos(BaseDir, OutDir, ExatOpts) ->
[compile_proto(BaseDir, ProtoName, OutDir, ExatOpts) ||
ProtoName <- list_dirs(BaseDir)].
compile_proto(BaseDir, ProtoName, OutDir, ExatOpts) ->
rebar_api:info(" Compiling Erlang Protocol '~s'", [ProtoName]),
ModAst = exat_compiler:compile(BaseDir, ProtoName, ExatOpts),
exat_compiler:ast_to_beam_file(ModAst, OutDir).
list_dirs(BaseDir) ->
case file:list_dir(BaseDir) of
{ok, Filenames} ->
[Filename ||
Filename <- Filenames,
filelib:is_dir(filename:join(BaseDir, Filename))];
{error, enoent} ->
[]
end.