Packages
rebar3_gpb_plugin
1.3.2
3.0.1
3.0.0
2.23.8
2.23.7
2.23.6
2.23.5
2.23.4
2.23.3
2.23.2
2.23.1
2.23.0
2.22.7
2.22.6
2.22.5
2.22.4
2.22.3
2.22.2
2.22.1
2.22.0
2.21.0
2.20.3
2.20.2
2.20.1
2.20.0
2.19.1
2.19.0
2.18.1
2.18.0
2.17.2
2.17.1
2.17.0
2.16.1
2.16.0
2.15.0
2.14.0
2.13.2
2.13.1
2.13.0
2.12.5
2.12.4
2.12.3
2.12.2
2.12.1
2.12.0
2.11.3
2.11.2
2.11.1
2.11.0
2.10.0
2.9.0
2.8.2
2.8.0
2.7.0
2.6.1
2.6.0
2.5.1
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.4
2.3.3
2.3.2
2.3.1
2.3.0
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.1
2.1.0
2.0.1
2.0.0
1.12.1
1.12.0
1.11.8
1.11.7
1.11.6
1.11.5
1.11.4
1.11.3
1.11.2
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.2
1.9.1
1.9.0
1.8.2
1.8.1
1.8.0
1.7.3
1.7.2
1.7.1
1.7.0
1.6.1
1.6.0
1.5.2
1.5.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.0.1
A rebar3 gpb plugin for compiling .proto files
Current section
Files
Jump to
Current section
Files
src/rebar3_gpb_compiler.erl
-module(rebar3_gpb_compiler).
-export([compile/1,
clean/1]).
-define(DEFAULT_PROTO_DIR, "proto").
-define(DEFAULT_OUT_ERL_DIR, "src").
-define(DEFAULT_OUT_HRL_DIR, "include").
-define(DEFAULT_MODULE_SUFFIX, "").
%% ===================================================================
%% Public API
%% ===================================================================
-spec compile(rebar_app_info:t()) -> ok.
compile(AppInfo) ->
AppDir = rebar_app_info:dir(AppInfo),
AppOutDir = rebar_app_info:out_dir(AppInfo),
Opts = rebar_app_info:opts(AppInfo),
{ok, GpbOpts0} = dict:find(gpb_opts, Opts),
ModuleNameSuffix = proplists:get_value(module_name_suffix, GpbOpts0, ?DEFAULT_MODULE_SUFFIX),
SourceDir = filename:join([AppDir,
proplists:get_value(i, GpbOpts0,
?DEFAULT_PROTO_DIR)]),
TargetErlDir = filename:join([AppOutDir,
proplists:get_value(o_erl, GpbOpts0,
?DEFAULT_OUT_ERL_DIR)]),
TargetHrlDir = filename:join([AppOutDir,
proplists:get_value(o_hrl, GpbOpts0,
?DEFAULT_OUT_HRL_DIR)]),
rebar_api:debug("reading proto files from ~p, generating \"~s.erl\" to ~p and \"~s.hrl\" to ~p",
[SourceDir, ModuleNameSuffix, TargetErlDir, ModuleNameSuffix, TargetHrlDir]),
rebar_api:debug("making sure that target erl dir ~p exists", [TargetErlDir]),
ok = ensure_dir(TargetErlDir),
rebar_api:debug("making sure that target hrl dir ~p exists", [TargetHrlDir]),
ok = ensure_dir(TargetHrlDir),
%% set the full path for the output directories
GpbOpts = default_include_opts(SourceDir,
target_erl_opt(TargetErlDir,
target_hrl_opt(TargetHrlDir, GpbOpts0))),
rebar_base_compiler:run(Opts, [],
SourceDir, ".proto",
TargetErlDir, ModuleNameSuffix ++ ".erl",
fun(Source, Target, Config) ->
compile(Source, Target, GpbOpts, Config)
end).
-spec clean(rebar_app_info:t()) -> ok.
clean(AppInfo) ->
AppDir = rebar_app_info:dir(AppInfo),
AppOutDir = rebar_app_info:out_dir(AppInfo),
Opts = rebar_app_info:opts(AppInfo),
{ok, GpbOpts} = dict:find(gpb_opts, Opts),
ModuleNameSuffix = proplists:get_value(module_name_suffix, GpbOpts, ?DEFAULT_MODULE_SUFFIX),
SourceDir = filename:join([AppDir,
proplists:get_value(i, GpbOpts, ?DEFAULT_PROTO_DIR)]),
TargetErlDir = filename:join([AppOutDir,
proplists:get_value(o_erl, GpbOpts,
?DEFAULT_OUT_ERL_DIR)]),
TargetHrlDir = filename:join([AppOutDir,
proplists:get_value(o_hrl, GpbOpts,
?DEFAULT_OUT_HRL_DIR)]),
ProtoFiles = rebar_utils:find_files(SourceDir, ".*\.proto\$"),
GeneratedRootFiles = [filename:rootname(filename:basename(ProtoFile)) ++
ModuleNameSuffix || ProtoFile <- ProtoFiles],
GeneratedErlFiles = [filename:join([TargetErlDir, F ++ ".erl"]) ||
F <- GeneratedRootFiles],
GeneratedHrlFiles = [filename:join([TargetHrlDir, F ++ ".hrl"]) ||
F <- GeneratedRootFiles],
rebar_api:debug("deleting [~p, ~p]",
[GeneratedErlFiles, GeneratedHrlFiles]),
rebar_file_utils:delete_each(GeneratedErlFiles ++ GeneratedHrlFiles).
%% ===================================================================
%% Private API
%% ===================================================================
-spec compile(string(), string(), proplists:proplist(), term()) -> ok.
compile(Source, _Target, GpbOpts, _Config) ->
rebar_api:debug("gpb opts: ~p", [GpbOpts]),
case gpb_compile:file(filename:basename(Source), GpbOpts) of
ok ->
ok;
{error, Reason} ->
ReasonStr = gpb_compile:format_error(Reason),
rebar_utils:abort("failed to compile ~s: ~s~n", [Source, ReasonStr])
end.
-spec ensure_dir(filelib:dirname()) -> 'ok' | {error, Reason::file:posix()}.
ensure_dir(OutDir) ->
%% Make sure that ebin/ exists and is on the path
case filelib:ensure_dir(filename:join(OutDir, "dummy.beam")) of
ok -> ok;
{error, eexist} ->
rebar_utils:abort("unable to ensure dir ~p, is it maybe a broken symlink?",
[OutDir]);
{error, Reason} -> {error, Reason}
end.
-spec default_include_opts(string(), proplists:proplist()) -> proplists:proplist().
default_include_opts(SourceDir, Opts) ->
Opts ++ [{i, SourceDir}].
-spec target_erl_opt(string(), proplists:proplist()) -> proplists:proplist().
target_erl_opt(Dir, Opts) ->
lists:keystore(o_erl, 1, Opts, {o_erl, Dir}).
-spec target_hrl_opt(string(), proplists:proplist()) -> proplists:proplist().
target_hrl_opt(Dir, Opts) ->
lists:keystore(o_hrl, 1, Opts, {o_hrl, Dir}).