Merge pull request #52 from ericbmerritt/git-vsn-additions
Suppport a vsn signature with a git implementation
This commit is contained in:
commit
888be01dfe
3 changed files with 146 additions and 1 deletions
|
@ -5,7 +5,7 @@
|
||||||
{git, "https://github.com/erlware/rebar_vsn_plugin.git",
|
{git, "https://github.com/erlware/rebar_vsn_plugin.git",
|
||||||
{branch, "master"}}}]}.
|
{branch, "master"}}}]}.
|
||||||
|
|
||||||
{erl_first_files, ["ec_dictionary"]}.
|
{erl_first_files, ["ec_dictionary", "ec_vsn"]}.
|
||||||
|
|
||||||
%% Compiler Options ============================================================
|
%% Compiler Options ============================================================
|
||||||
{erl_opts,
|
{erl_opts,
|
||||||
|
|
79
src/ec_git_vsn.erl
Normal file
79
src/ec_git_vsn.erl
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
%%% vi:ts=4 sw=4 et
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
||||||
|
%%% @copyright 2011 Erlware, LLC.
|
||||||
|
%%% @doc
|
||||||
|
%%% This provides an implementation of the ec_vsn for git. That is
|
||||||
|
%%% it is capable of returning a semver for a git repository
|
||||||
|
%%% see ec_vsn
|
||||||
|
%%% see ec_semver
|
||||||
|
%%% @end
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(ec_git_vsn).
|
||||||
|
|
||||||
|
-behaviour(ec_vsn).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([new/0,
|
||||||
|
vsn/1]).
|
||||||
|
|
||||||
|
-export_type([t/0]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Types
|
||||||
|
%%%===================================================================
|
||||||
|
%% This should be opaque, but that kills dialyzer so for now we export it
|
||||||
|
%% however you should not rely on the internal representation here
|
||||||
|
-type t() :: {}.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
-spec new() -> t().
|
||||||
|
new() ->
|
||||||
|
{}.
|
||||||
|
|
||||||
|
-spec vsn(t()) -> {ok, string()} | {error, Reason::any()}.
|
||||||
|
vsn(_Data) ->
|
||||||
|
Result = do_cmd("git describe --tags --always"),
|
||||||
|
case re:split(Result, "-") of
|
||||||
|
[Vsn, Count, RefTag] ->
|
||||||
|
erlang:iolist_to_binary([strip_leading_v(Vsn),
|
||||||
|
<<"+build.">>,
|
||||||
|
Count,
|
||||||
|
<<".ref.">>,
|
||||||
|
RefTag]);
|
||||||
|
[VsnOrRefTag] ->
|
||||||
|
case re:run(VsnOrRefTag, "^[0-9a-fA-F]+$") of
|
||||||
|
{match, _} ->
|
||||||
|
find_vsn_from_start_of_branch(VsnOrRefTag);
|
||||||
|
nomatch ->
|
||||||
|
strip_leading_v(VsnOrRefTag)
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
{error, {invalid_result, Result}}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal Functions
|
||||||
|
%%%===================================================================
|
||||||
|
-spec strip_leading_v(string()) -> string().
|
||||||
|
strip_leading_v(Vsn) ->
|
||||||
|
case re:run(Vsn, "v?(.+)", [{capture, [1], binary}]) of
|
||||||
|
{match, [NVsn]} ->
|
||||||
|
NVsn;
|
||||||
|
_ ->
|
||||||
|
Vsn
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec find_vsn_from_start_of_branch(string()) -> string().
|
||||||
|
find_vsn_from_start_of_branch(RefTag) ->
|
||||||
|
Count = do_cmd("git rev-list HEAD --count"),
|
||||||
|
erlang:iolist_to_binary("0.0.0+build.", Count, ".ref.", RefTag).
|
||||||
|
|
||||||
|
do_cmd(Cmd) ->
|
||||||
|
trim_whitespace(os:cmd(Cmd)).
|
||||||
|
|
||||||
|
trim_whitespace(Input) ->
|
||||||
|
re:replace(Input, "\\s+", "", [global]).
|
66
src/ec_vsn.erl
Normal file
66
src/ec_vsn.erl
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
%%% vi:ts=4 sw=4 et
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
||||||
|
%%% @copyright 2014 Erlware, LLC.
|
||||||
|
%%% @doc
|
||||||
|
%%% Provides a signature to manage returning semver formatted versions
|
||||||
|
%%% from various version control repositories.
|
||||||
|
%%%
|
||||||
|
%%% This interface is a member of the Erlware Commons Library.
|
||||||
|
%%% @end
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(ec_vsn).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([new/1,
|
||||||
|
vsn/1]).
|
||||||
|
|
||||||
|
-export_type([t/0]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Types
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
-record(t, {callback, data}).
|
||||||
|
|
||||||
|
%% This should be opaque, but that kills dialyzer so for now we export it
|
||||||
|
%% however you should not rely on the internal representation here
|
||||||
|
-type t() :: #t{}.
|
||||||
|
|
||||||
|
-ifdef(have_callback_support).
|
||||||
|
|
||||||
|
-callback new() -> any().
|
||||||
|
-callback vsn(any()) -> {ok, string()} | {error, Reason::any()}.
|
||||||
|
|
||||||
|
-else.
|
||||||
|
|
||||||
|
%% In the case where R14 or lower is being used to compile the system
|
||||||
|
%% we need to export a behaviour info
|
||||||
|
-export([behaviour_info/1]).
|
||||||
|
-spec behaviour_info(atom()) -> [{atom(), arity()}] | undefined.
|
||||||
|
behaviour_info(callbacks) ->
|
||||||
|
[{new, 0},
|
||||||
|
{vsn, 1}];
|
||||||
|
behaviour_info(_Other) ->
|
||||||
|
undefined.
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
%% @doc create a new dictionary object from the specified module. The
|
||||||
|
%% module should implement the dictionary behaviour.
|
||||||
|
%%
|
||||||
|
%% @param ModuleName The module name.
|
||||||
|
-spec new(module()) -> t().
|
||||||
|
new(ModuleName) when erlang:is_atom(ModuleName) ->
|
||||||
|
#t{callback = ModuleName, data = ModuleName:new()}.
|
||||||
|
|
||||||
|
%% @doc Return the semver or an error depending on what is possible
|
||||||
|
%% with this implementation in this directory.
|
||||||
|
%%
|
||||||
|
%% @param The dictionary object
|
||||||
|
-spec vsn(t()) -> {ok, string()} | {error, Reason::any()}.
|
||||||
|
vsn(#t{callback = Mod, data = Data}) ->
|
||||||
|
Mod:vsn(Data).
|
Loading…
Add table
Add a link
Reference in a new issue