Allow creation of refs
This commit is contained in:
@@ -128,6 +128,7 @@ static ErlNifFunc geef_funcs[] =
|
||||
{"reference_resolve", 1, geef_reference_resolve},
|
||||
{"reference_target", 1, geef_reference_target},
|
||||
{"reference_type", 1, geef_reference_type},
|
||||
{"reference_create", 5, geef_reference_create},
|
||||
{"oid_fmt", 1, geef_oid_fmt},
|
||||
{"oid_parse", 1, geef_oid_parse},
|
||||
{"object_lookup", 2, geef_object_lookup},
|
||||
|
||||
@@ -246,3 +246,58 @@ geef_reference_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||
|
||||
return term_type;
|
||||
}
|
||||
|
||||
ERL_NIF_TERM
|
||||
geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
geef_repository *repo;
|
||||
geef_ref *ref;
|
||||
ErlNifBinary name, target;
|
||||
ERL_NIF_TERM term_ref;
|
||||
int error, force;
|
||||
const char *pname, *ptarget;
|
||||
|
||||
if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo))
|
||||
return enif_make_badarg(env);
|
||||
|
||||
if (!enif_inspect_iolist_as_binary(env, argv[1], &name))
|
||||
return enif_make_badarg(env);
|
||||
|
||||
if (!enif_inspect_iolist_as_binary(env, argv[3], &target))
|
||||
return enif_make_badarg(env);
|
||||
|
||||
/* Allocate the extra byte for the NUL terminator */
|
||||
if (!enif_realloc_binary(&name, name.size + 1))
|
||||
return atoms.error;
|
||||
|
||||
name.data[name.size-1] = '\0';
|
||||
|
||||
ref = enif_alloc_resource(geef_ref_type, sizeof(geef_ref));
|
||||
|
||||
force = enif_is_identical(argv[4], atoms.true);
|
||||
|
||||
pname = (const char *) name.data;
|
||||
if (enif_is_identical(argv[2], atoms.oid)) {
|
||||
const git_oid *oid = (const git_oid *) target.data;
|
||||
error = git_reference_create(&ref->ref, repo->repo, pname, oid, force);
|
||||
} else if (enif_is_identical(argv[2], atoms.symbolic)) {
|
||||
/* Allocate the extra byte for the NUL terminator */
|
||||
if (!enif_realloc_binary(&target, target.size + 1))
|
||||
return atoms.error;
|
||||
|
||||
target.data[target.size - 1] = '\0';
|
||||
ptarget = (const char *) target.data;
|
||||
error = git_reference_symbolic_create(&ref->ref, repo->repo, pname, ptarget, force);
|
||||
} else {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if (error < 0)
|
||||
return geef_error(env);
|
||||
|
||||
term_ref = enif_make_resource(env, ref);
|
||||
enif_release_resource(ref);
|
||||
|
||||
return enif_make_tuple2(env, atoms.ok, term_ref);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ ERL_NIF_TERM geef_reference_lookup(ErlNifEnv *env, int argc, const ERL_NIF_TERM
|
||||
ERL_NIF_TERM geef_reference_resolve(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||
ERL_NIF_TERM geef_reference_target(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||
ERL_NIF_TERM geef_reference_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||
ERL_NIF_TERM geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||
|
||||
void geef_ref_free(ErlNifEnv *env, void *cd);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% NIF functions, not to be used directly.
|
||||
|
||||
-module(geef_nif).
|
||||
-export([reference_list/1,
|
||||
-export([reference_list/1, reference_create/5,
|
||||
reference_to_id/2, reference_glob/2, reference_lookup/2, reference_resolve/1,
|
||||
reference_target/1, reference_type/1, odb_object_exists/2, odb_write/3]).
|
||||
|
||||
@@ -60,6 +60,9 @@ repository_discover(_Path) ->
|
||||
reference_list(_Repo) ->
|
||||
nif_error(?LINE).
|
||||
|
||||
reference_create(_Repo, _Refname, _Type, _Target, _Force) ->
|
||||
?NIF_FN.
|
||||
|
||||
reference_to_id(_Repo, _Refname) ->
|
||||
nif_error(?LINE).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-module(geef_ref).
|
||||
|
||||
-export([lookup/2, resolve/1, target/1, name_to_id/2]).
|
||||
-export([lookup/2, resolve/1, target/1, name_to_id/2, create/4]).
|
||||
|
||||
-include("geef_records.hrl").
|
||||
|
||||
@@ -16,6 +16,12 @@ new(Handle) ->
|
||||
end,
|
||||
#ref{handle=Handle, type=Type, target=Target}.
|
||||
|
||||
-spec create(pid(), iolist(), oid() | binary(), boolean()) -> {ok, ref()} | {error, term()}
|
||||
.
|
||||
create(Repo, Refname, Target, Force) ->
|
||||
{ok, Ref} = geef_repo:create_reference(Repo, Refname, Target, Force),
|
||||
{ok, new(Ref)}.
|
||||
|
||||
-spec lookup(pid(), iolist()) -> {ok, ref()} | {error, term()}.
|
||||
lookup(Repo, Refname) ->
|
||||
case geef_repo:lookup_reference(Repo, Refname) of
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
%% API
|
||||
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1,
|
||||
lookup_object/2, lookup_reference/2, revwalk/1, stop/1, handle/1]).
|
||||
lookup_object/2, lookup_reference/2, create_reference/4, revwalk/1, stop/1, handle/1]).
|
||||
|
||||
-include("geef_records.hrl").
|
||||
-record(state, {handle}).
|
||||
@@ -85,6 +85,10 @@ lookup_object(Pid, Oid) ->
|
||||
lookup_reference(Pid, Name) ->
|
||||
gen_server:call(Pid, {lookup_reference, Name}).
|
||||
|
||||
%% @private
|
||||
create_reference(Pid, Name, Target, Force) ->
|
||||
gen_server:call(Pid, {create_reference, Name, Target, Force}).
|
||||
|
||||
%% @doc Create a revision walker for the given repository.
|
||||
revwalk(Pid) ->
|
||||
gen_server:call(Pid, revwalk).
|
||||
@@ -127,6 +131,9 @@ handle_call({lookup_object, Oid}, _From, State = #state{handle=Handle}) ->
|
||||
handle_call({lookup_reference, Name}, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef_nif:reference_lookup(Handle, Name),
|
||||
{reply, Reply, State};
|
||||
handle_call({create_reference, Name, Target, Force}, _From, State = #state{handle=Handle}) ->
|
||||
Reply = handle_create_reference(Handle, Name, Target, Force),
|
||||
{reply, Reply, State};
|
||||
handle_call(stop, _From, State) ->
|
||||
{stop, normal, ok, State};
|
||||
handle_call(revwalk, _From, State = #state{handle=Handle}) ->
|
||||
@@ -182,3 +189,8 @@ handle_revwalk(Handle) ->
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
handle_create_reference(Repo, Refname, #oid{oid=Oid}, Force) ->
|
||||
geef_nif:reference_create(Repo, Refname, oid, Oid, Force);
|
||||
handle_create_reference(Repo, Refname, Target, Force) ->
|
||||
geef_nif:reference_create(Repo, Refname, symbolic, Target, Force).
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
repo_test_() ->
|
||||
{foreach, fun start/0, fun stop/1, [fun bare_test/1, fun odb_write_test/1]}.
|
||||
{foreach, fun start/0, fun stop/1, [fun bare_test/1, fun odb_write_test/1, fun create_ref_test/1]}.
|
||||
|
||||
start() ->
|
||||
{A, B, C} = now(),
|
||||
@@ -22,5 +22,15 @@ odb_write_test(Repo) ->
|
||||
Expected = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"),
|
||||
[?_assertEqual(Actual, Expected)].
|
||||
|
||||
create_ref_test(Repo) ->
|
||||
odb_write_test(Repo),
|
||||
Id = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"),
|
||||
{ok, _} = geef_ref:create(Repo, "refs/heads/branch", Id, true),
|
||||
{ok, _} = geef_ref:create(Repo, "refs/heads/other", "refs/heads/branch", true),
|
||||
{ok, Ref0} = geef_ref:lookup(Repo, "refs/heads/branch"),
|
||||
{ok, Ref1} = geef_ref:lookup(Repo, "refs/heads/other"),
|
||||
[?_assertEqual(geef_ref:target(Ref0), Id),
|
||||
?_assertEqual(geef_ref:target(Ref1), <<"refs/heads/branch">>)].
|
||||
|
||||
stop(Repo) ->
|
||||
geef_repo:stop(Repo).
|
||||
|
||||
Reference in New Issue
Block a user