Current section
Files
Jump to
Current section
Files
src/rebar3_git_vsn.erl
%% @copyright 2016 Hinagiku Soranoba All Rights Reserved.
%%
%% @doc Provider for generate the version from git.
-module(rebar3_git_vsn).
-behaviour(provider).
%%----------------------------------------------------------------------------------------------------------------------
%% 'provider' Callback APIs
%%----------------------------------------------------------------------------------------------------------------------
-export([init/1, do/1, format_error/1]).
%%----------------------------------------------------------------------------------------------------------------------
%% Macros
%%----------------------------------------------------------------------------------------------------------------------
-define(DEBUG(Format, Args), rebar_api:debug("[~s] "++Format, [?MODULE | Args])).
-define(INFO(Format, Args), rebar_api:info( "[~s] "++Format, [?MODULE | Args])).
-define(ERROR(Format, Args), rebar_api:error("[~s] "++Format, [?MODULE | Args])).
%%----------------------------------------------------------------------------------------------------------------------
%% 'provider' Callback Functions
%%----------------------------------------------------------------------------------------------------------------------
%% @private
init(State) ->
Provider = providers:create([{name, git_vsn},
{module, ?MODULE},
{bare, true},
{deps, []},
{short_desc, "Generate the version from git"}
]),
{ok, rebar_state:add_provider(State, Provider)}.
%% @private
do(State) ->
CurrentApp = rebar_state:current_app(State),
ProjectApps = rebar_state:project_apps(State),
GitVsnOpts = rebar_state:get(State, git_vsn, []),
Key = proplists:get_value(env_key, GitVsnOpts, git_vsn),
Opt = proplists:get_value(describe_opt, GitVsnOpts, ""),
DoSeparate = proplists:get_value(separate, GitVsnOpts, false),
Dir = rebar_app_info:dir(CurrentApp),
case filelib:is_dir(GitPath = filename:join(Dir, ".git")) of
true ->
Vsn0 = git_describe(Dir, Opt),
Vsn = case DoSeparate andalso lists:prefix(git_describe(Dir, "--tags --long --abbrev=1"), Vsn0) of
true ->
[Hash, Count | Rest] = lists:reverse(string:tokens(Vsn0, [$-])),
{string:join(lists:reverse(Rest), "-"), Count, Hash};
false ->
Vsn0
end,
lists:foreach(fun(App) ->
?INFO("write ~s.app : {~p, ~p}", [rebar_app_info:name(App), Key, Vsn]),
AppFile = rebar_app_info:app_file(App),
{ok, [{application, AppName, AppKeys0}]} = file:consult(AppFile),
Env0 = proplists:get_value(env, AppKeys0),
Env = lists:keystore(Key, 1, Env0, {Key, Vsn}),
AppKeys = lists:keystore(env, 1, AppKeys0, {env, Env}),
AppData = io_lib:format("~p.\n", [{application, AppName, AppKeys}]),
rebar_file_utils:write_file_if_contents_differ(AppFile, AppData)
end, [CurrentApp | ProjectApps]);
false ->
?DEBUG("~s doesn't exist", [GitPath]),
ok
end,
{ok, State}.
%% @private
format_error(Reason) ->
io_lib:format("~p", [Reason]).
%%----------------------------------------------------------------------------------------------------------------------
%% Internal Functions
%%----------------------------------------------------------------------------------------------------------------------
-spec git_describe(file:filename_all(), string()) -> string().
git_describe(Dir, Opt) ->
{ok, Ret} = rebar_utils:sh("git describe --always " ++ Opt, [{cd, Dir}]),
string:strip(Ret, both, $\n).