diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar_git_resource.erl | 67 | ||||
-rw-r--r-- | src/rebar_pkg_resource.erl | 6 | ||||
-rw-r--r-- | src/rebar_resource.erl | 8 | ||||
-rw-r--r-- | src/rebar_utils.erl | 23 |
4 files changed, 90 insertions, 14 deletions
diff --git a/src/rebar_git_resource.erl b/src/rebar_git_resource.erl index 444163e..a6b60d5 100644 --- a/src/rebar_git_resource.erl +++ b/src/rebar_git_resource.erl @@ -6,7 +6,8 @@ -export([lock/2 ,download/2 - ,needs_update/2]). + ,needs_update/2 + ,make_vsn/1]). -include("rebar.hrl"). @@ -79,3 +80,67 @@ download(Dir, {git, Url, Rev}) -> rebar_utils:sh(?FMT("git clone -n ~s ~s", [Url, filename:basename(Dir)]), [{cd, filename:dirname(Dir)}]), rebar_utils:sh(?FMT("git checkout -q ~s", [Rev]), [{cd, Dir}]). + +make_vsn(Dir) -> + Cwd = file:get_cwd(), + try + ok = file:set_cwd(Dir), + {Vsn, RawRef, RawCount} = collect_default_refcount(), + {plain, build_vsn_string(Vsn, RawRef, RawCount)} + after + file:set_cwd(Cwd) + end. + +%% Internal functions + +collect_default_refcount() -> + %% Get the tag timestamp and minimal ref from the system. The + %% timestamp is really important from an ordering perspective. + RawRef = os:cmd("git log -n 1 --pretty=format:'%h\n' "), + + {Tag, TagVsn} = parse_tags(), + RawCount = + case Tag of + undefined -> + os:cmd("git rev-list HEAD | wc -l"); + _ -> + get_patch_count(Tag) + end, + {TagVsn, RawRef, RawCount}. + +build_vsn_string(Vsn, RawRef, RawCount) -> + %% Cleanup the tag and the Ref information. Basically leading 'v's and + %% whitespace needs to go away. + RefTag = case RawRef of + undefined -> + ""; + RawRef -> + [".ref", re:replace(RawRef, "\\s", "", [global])] + end, + Count = erlang:iolist_to_binary(re:replace(RawCount, "\\s", "", [global])), + + %% Create the valid [semver](http://semver.org) version from the tag + case Count of + <<"0">> -> + erlang:binary_to_list(erlang:iolist_to_binary(Vsn)); + _ -> + erlang:binary_to_list(erlang:iolist_to_binary([Vsn, "+build.", + Count, RefTag])) + end. + +get_patch_count(RawRef) -> + Ref = re:replace(RawRef, "\\s", "", [global]), + Cmd = io_lib:format("git rev-list ~s..HEAD | wc -l", + [Ref]), + os:cmd(Cmd). + +parse_tags() -> + first_valid_tag(os:cmd("git log --oneline --decorate | fgrep \"tag: \" -1000")). + +first_valid_tag(Line) -> + case re:run(Line, "(\\(|\\s)tag:\\s(v([^,\\)]+))", [{capture, [2, 3], list}]) of + {match,[Tag, Vsn]} -> + {Tag, Vsn}; + nomatch -> + {undefined, "0.0.0"} + end. diff --git a/src/rebar_pkg_resource.erl b/src/rebar_pkg_resource.erl index 1590458..5cd6fc8 100644 --- a/src/rebar_pkg_resource.erl +++ b/src/rebar_pkg_resource.erl @@ -6,7 +6,8 @@ -export([lock/2 ,download/2 - ,needs_update/2]). + ,needs_update/2 + ,make_vsn/1]). -include("rebar.hrl"). @@ -26,3 +27,6 @@ download(Dir, {pkg, _Name, _Vsn, Url}) -> TmpFile = filename:join(Dir, "package.tar.gz"), {ok, saved_to_file} = httpc:request(get, {binary_to_list(Url), []}, [], [{stream, TmpFile}]), {tarball, TmpFile}. + +make_vsn(_) -> + {error, "Replacing version of type pkg not supported."}. diff --git a/src/rebar_resource.erl b/src/rebar_resource.erl index f0490f8..04b8d73 100644 --- a/src/rebar_resource.erl +++ b/src/rebar_resource.erl @@ -24,16 +24,20 @@ behaviour_info(callbacks) -> [{lock, 2}, {download, 2}, - {needs_update,2}]; + {needs_update,2}, + {make_vsn, 1}]; behaviour_info(_) -> undefined. -else. --callback lock(file:filename_all(), tuple()) -> rebar_resource:resource(). +-callback lock(file:filename_all(), tuple()) -> + rebar_resource:resource(). -callback download(file:filename_all(), tuple()) -> {tarball, file:filename_all()} | {ok, any()} | {error, any()}. -callback needs_update(file:filename_all(), tuple()) -> {tarball, file:filename_all()} | {ok, any()} | {error, any()}. +-callback make_vsn(file:filename_all()) -> + {plain, string()} | {error, string()}. -endif. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 347b02a..4815ad2 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -438,13 +438,15 @@ escript_foldl(Fun, Acc, File) -> end. vcs_vsn_1(Vcs, Dir) -> - case vcs_vsn_cmd(Vcs) of + case vcs_vsn_cmd(Vcs, Dir) of {plain, VsnString} -> VsnString; {cmd, CmdString} -> vcs_vsn_invoke(CmdString, Dir); unknown -> ?ABORT("vcs_vsn: Unknown vsn format: ~p\n", [Vcs]); + {error, Reason} -> + ?ABORT("vcs_vsn: ~s\n", [Reason]); Cmd -> %% If there is a valid VCS directory in the application directory, %% use that version info @@ -471,15 +473,16 @@ vcs_vsn_1(Vcs, Dir) -> end end. -vcs_vsn_cmd(git) -> "git describe --always --tags"; -vcs_vsn_cmd(p4) -> "echo #head"; -vcs_vsn_cmd(hg) -> "hg identify -i"; -vcs_vsn_cmd(bzr) -> "bzr revno"; -vcs_vsn_cmd(svn) -> "svnversion"; -vcs_vsn_cmd(fossil) -> "fossil info"; -vcs_vsn_cmd({cmd, _Cmd}=Custom) -> Custom; -vcs_vsn_cmd(Version) when is_list(Version) -> {plain, Version}; -vcs_vsn_cmd(_) -> unknown. +vcs_vsn_cmd(VCS, Dir) when VCS =:= git ; VCS =:= "git" -> + rebar_git_resource:make_vsn(Dir); +vcs_vsn_cmd(VCS, Dir) when VCS =:= pkg ; VCS =:= "pkg" -> + rebar_pkg_resource:make_vsn(Dir); +vcs_vsn_cmd({cmd, _Cmd}=Custom, _) -> + Custom; +vcs_vsn_cmd(Version, _) when is_list(Version) -> + {plain, Version}; +vcs_vsn_cmd(_, _) -> + unknown. vcs_vsn_invoke(Cmd, Dir) -> {ok, VsnString} = rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, false}]), |