From 21464aeecec65cff4e8d82158b7f9a2ebcda2034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 5 Sep 2013 15:11:32 +0200 Subject: [PATCH] Wrap git_revparse_single --- c_src/geef.c | 2 ++ c_src/object.c | 1 - c_src/revparse.c | 48 +++++++++++++++++++++++++++++++++++++++++++ c_src/revparse.h | 8 ++++++++ lib/geef/revparse.ex | 17 +++++++++++++++ src/geef_nif.erl | 4 ++++ src/geef_revparse.erl | 15 ++++++++++++++ test/repo_test.erl | 8 +++++++- 8 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 c_src/revparse.c create mode 100644 c_src/revparse.h create mode 100644 lib/geef/revparse.ex create mode 100644 src/geef_revparse.erl diff --git a/c_src/geef.c b/c_src/geef.c index b54fb66..800cb24 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -11,6 +11,7 @@ #include "revwalk.h" #include "index.h" #include "signature.h" +#include "revparse.h" #include "geef.h" #include #include @@ -186,6 +187,7 @@ static ErlNifFunc geef_funcs[] = {"index_read_tree", 2, geef_index_read_tree}, {"signature_new", 2, geef_signature_new}, {"signature_new", 3, geef_signature_new}, + {"revparse_single", 2, geef_revparse_single}, }; ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload) diff --git a/c_src/object.c b/c_src/object.c index b90f064..b040d5c 100644 --- a/c_src/object.c +++ b/c_src/object.c @@ -71,7 +71,6 @@ geef_object_lookup(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return geef_error(env); } - term_obj = enif_make_resource(env, obj); enif_release_resource(obj); diff --git a/c_src/revparse.c b/c_src/revparse.c new file mode 100644 index 0000000..8be0911 --- /dev/null +++ b/c_src/revparse.c @@ -0,0 +1,48 @@ +#include +#include "geef.h" +#include "repository.h" +#include "oid.h" +#include "object.h" +#include "revparse.h" + +ERL_NIF_TERM +geef_revparse_single(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + ErlNifBinary bin, id; + geef_repository *repo; + geef_object *obj; + ERL_NIF_TERM type, term_obj; + + 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], &bin)) + return enif_make_badarg(env); + + if (geef_terminate_binary(&bin) < 0) + return geef_oom(env); + + obj = enif_alloc_resource(geef_object_type, sizeof(geef_object)); + if (!obj) + return geef_oom(env); + + if (git_revparse_single(&obj->obj, repo->repo, (char *) bin.data) < 0) { + enif_release_binary(&bin); + enif_release_resource(obj); + return geef_error(env); + } + + type = geef_object_type2atom(git_object_type(obj->obj)); + + if (geef_oid_bin(&id, git_object_id(obj->obj)) < 0) + return geef_oom(env); + + + term_obj = enif_make_resource(env, obj); + enif_release_resource(obj); + + obj->repo = repo; + enif_keep_resource(repo); + + return enif_make_tuple4(env, atoms.ok, term_obj, type, enif_make_binary(env, &id)); +} diff --git a/c_src/revparse.h b/c_src/revparse.h new file mode 100644 index 0000000..77afa0e --- /dev/null +++ b/c_src/revparse.h @@ -0,0 +1,8 @@ +#ifndef GEEF_REVPARSE_H +#define GEEF_REVPARSE_H + +#include "erl_nif.h" + +ERL_NIF_TERM geef_revparse_single(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +#endif diff --git a/lib/geef/revparse.ex b/lib/geef/revparse.ex new file mode 100644 index 0000000..0613b97 --- /dev/null +++ b/lib/geef/revparse.ex @@ -0,0 +1,17 @@ +defmodule Geef.Revparse do + import Geef + use Geef + + @spec single(pid, iolist) :: {:ok, Object.t} | {:error, term} + def single(repo, str) do + case :geef_revparse.single(repo, str) do + {:ok, obj} -> + {:ok, Object.from_erl(obj)} + error -> error + end + end + + @spec single!(pid, iolist) :: {:ok, Object.t} + def single!(repo, str), do: single(repo, str) |> assert_ok + +end \ No newline at end of file diff --git a/src/geef_nif.erl b/src/geef_nif.erl index a87ad81..c38ab15 100644 --- a/src/geef_nif.erl +++ b/src/geef_nif.erl @@ -178,6 +178,10 @@ signature_new(_Name, _Email) -> signature_new(_Name, _Email, _Time) -> ?NIF_FN. +-spec revparse_single(term(), iolist()) -> {ok, term(), atom(), geef_oid:oid()} | {error, term()}. +revparse_single(_Handle, _Str) -> + ?NIF_FN. + nif_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). diff --git a/src/geef_revparse.erl b/src/geef_revparse.erl new file mode 100644 index 0000000..99927d3 --- /dev/null +++ b/src/geef_revparse.erl @@ -0,0 +1,15 @@ +-module(geef_revparse). + +-include("geef_records.hrl"). + +-export([single/2]). + +-spec single(pid(), iolist()) -> {ok, geef_obj:object()} | {error, term()}. +single(Repo, Str) -> + RepoHandle = geef_repo:handle(Repo), + case geef_nif:revparse_single(RepoHandle, Str) of + {ok, ObjHandle, Type, Id} -> + {ok, #geef_object{type=Type, id=Id, handle=ObjHandle}}; + Error = {error, _} -> + Error + end. diff --git a/test/repo_test.erl b/test/repo_test.erl index 2d06ad0..f2c0221 100644 --- a/test/repo_test.erl +++ b/test/repo_test.erl @@ -6,7 +6,7 @@ repo_test_() -> {foreach, fun start/0, fun stop/1, [fun bare_test/1, fun odb_write_test/1, fun ref_test/1, fun index_add_test/1, - fun ref_iter_test/1]}. + fun ref_iter_test/1, fun revparse_test/1]}. start() -> {A, B, C} = now(), @@ -25,6 +25,12 @@ odb_write_test(Repo) -> Expected = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"), [?_assertEqual(Actual, Expected)]. +revparse_test(Repo) -> + odb_write_test(Repo), + {ok, Obj} = geef_revparse:single(Repo, "c300118399"), + [?_assertEqual(Obj#geef_object.type, blob), + ?_assertEqual(Obj#geef_object.id, geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"))]. + index_add_test(Repo) -> Data = <<"This is some text that will go in a file">>, {ok, Odb} = geef_repo:odb(Repo),