From fa24599e82eb0c39cec9fd7086dfe1e60fc3849a Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Thu, 12 Mar 2015 18:47:37 +0200 Subject: [PATCH 1/8] Running `mix` should be sufficient, as an Elixir dependency --- mix.exs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mix.exs b/mix.exs index ffa470c..3633e5d 100644 --- a/mix.exs +++ b/mix.exs @@ -37,6 +37,9 @@ defmodule Mix.Tasks.Compile.Nif do def run(_) do project = Mix.Project.get! + Mix.shell.info("* Running make...") + Mix.shell.info(:os.cmd('make')) + if function_exported?(project, :nif, 0) do do_run(project.nif) else From 6c73d9e29ed8217488262e416c27abd941051834 Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sat, 14 Mar 2015 12:28:42 +0200 Subject: [PATCH 2/8] fix Geef.Signature for Elixir use --- lib/geef/signature.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/geef/signature.ex b/lib/geef/signature.ex index 20e470a..5de6d3f 100644 --- a/lib/geef/signature.ex +++ b/lib/geef/signature.ex @@ -10,8 +10,12 @@ defmodule Geef.Signature do defp maybe_sig({:ok, sig}), do: from_record(sig) defp maybe_sig(error = {:error, _}), do: error - def from_record({:geef_signature}) do - %Geef.Signature{} + def from_record({:geef_signature, name, email, time}) do + %Geef.Signature{name: name, email: email, time: time} + end + + def to_record(%Geef.Signature{name: name, email: email, time: time}) do + {:geef_signature, name, email, time} end end From f943274ad8bcf5e92c88424976318cfe87f86457 Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sun, 15 Mar 2015 20:04:50 +0200 Subject: [PATCH 3/8] bug fix to commit create (when parents are given) --- c_src/commit.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/c_src/commit.c b/c_src/commit.c index c3e72f1..7202b64 100644 --- a/c_src/commit.c +++ b/c_src/commit.c @@ -117,7 +117,7 @@ geef_commit_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return geef_oom(env); i = 0; - tail = argv[8]; + tail = argv[7]; while (enif_get_list_cell(env, tail, &head, &tail)) { if (!enif_inspect_binary(env, head, &bin)) return enif_make_badarg(env); @@ -145,14 +145,12 @@ ERL_NIF_TERM geef_commit_message(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; - geef_object *obj, *tree; + geef_object *obj; const char *msg; if (!enif_get_resource(env, argv[0], geef_object_type, (void **) &obj)) return enif_make_badarg(env); - tree = enif_alloc_resource(geef_object_type, sizeof(geef_object)); - msg = git_commit_message((git_commit *) obj->obj); if (geef_string_to_bin(&bin, msg) < 0) return geef_error(env); From b2af788af0fe6b31cbb2b57e87a3de1305cf593f Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Mon, 13 Apr 2015 19:15:49 +0300 Subject: [PATCH 4/8] some fixes from dialyzer output --- lib/geef/pkt.ex | 4 ++-- lib/geef/signature.ex | 2 +- lib/geef/tree.ex | 6 +++--- mix.exs | 9 ++++++++- src/geef_nif.erl | 2 +- test/index_test.exs | 1 - 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/geef/pkt.ex b/lib/geef/pkt.ex index bdfc02a..3273930 100644 --- a/lib/geef/pkt.ex +++ b/lib/geef/pkt.ex @@ -8,8 +8,8 @@ defmodule Geef.Pkt do def parse_request(str) do case :geef_pkt.parse_request(str) do - {:ok, req} -> - {:ok, Geef.Request.new req} + {:ok, {:geef_request, service, path, host}} -> + {:ok, %Geef.Request{service: service, path: path, host: host}} error -> error end diff --git a/lib/geef/signature.ex b/lib/geef/signature.ex index 5de6d3f..46808f9 100644 --- a/lib/geef/signature.ex +++ b/lib/geef/signature.ex @@ -14,7 +14,7 @@ defmodule Geef.Signature do %Geef.Signature{name: name, email: email, time: time} end - def to_record(%Geef.Signature{name: name, email: email, time: time}) do + def to_record(%Geef.Signature{name: name, email: email, time: time}) do {:geef_signature, name, email, time} end diff --git a/lib/geef/tree.ex b/lib/geef/tree.ex index ac0bb8c..4d190f9 100644 --- a/lib/geef/tree.ex +++ b/lib/geef/tree.ex @@ -71,13 +71,13 @@ defimpl Enumerable, for: Geef.Tree do alias Geef.TreeError def count(tree) do - Tree.count(tree) + {:ok, Tree.count(tree)} end def member?(tree, key) do case Tree.get(tree, key) do - {:ok, _} -> true - _ -> false + {:ok, _} -> {:ok, true} + _ -> {:ok, false} end end diff --git a/mix.exs b/mix.exs index 3633e5d..7c40c6e 100644 --- a/mix.exs +++ b/mix.exs @@ -113,7 +113,8 @@ defmodule Geef.Mixfile do [ app: :geef, version: "0.0.1", compilers: [:nif, :erlang, :elixir, :app], - deps: deps ] + deps: deps, + dialyzer: dialyzer ] end def nif do @@ -131,4 +132,10 @@ defmodule Geef.Mixfile do defp deps do [] end + + def dialyzer do + [ plt_apps: [:erts, :kernel, :stdlib, :mnesia], + flags: ["-Wunmatched_returns","-Werror_handling","-Wrace_conditions", "-Wno_opaque"]] + end + end diff --git a/src/geef_nif.erl b/src/geef_nif.erl index 5b03c9a..96a262b 100644 --- a/src/geef_nif.erl +++ b/src/geef_nif.erl @@ -115,7 +115,7 @@ commit_tree(_Handle) -> commit_create(_RepoHandle, _Ref, _Author, _Committer, _Encoding, _Message, _Tree, _Parents) -> ?NIF_FN. --spec commit_message(term) -> binary(). +-spec commit_message(term) -> {ok, binary()} | {error, term()}. commit_message(_CommitHandle) -> ?NIF_FN. diff --git a/test/index_test.exs b/test/index_test.exs index d5b1f7e..73a7b59 100644 --- a/test/index_test.exs +++ b/test/index_test.exs @@ -2,7 +2,6 @@ defmodule IndexTest do use ExUnit.Case use Geef alias Geef.Index - alias Geef.Index.Entry import RepoHelpers From 1e48686acad511275e1765027f5f054afb0c373d Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sat, 11 Jul 2015 07:50:03 +0300 Subject: [PATCH 5/8] fix Geef.Object.lookup --- lib/geef/object.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/geef/object.ex b/lib/geef/object.ex index 4698b14..b2a5d12 100644 --- a/lib/geef/object.ex +++ b/lib/geef/object.ex @@ -16,6 +16,8 @@ defmodule Geef.Object do case lookup(repo, id) do {:ok, obj = %Geef.Object{type: ^type}} -> {:ok, obj} + {:ok, _obj} -> + {:error, :type_mismatch} error -> error end From 8c3946309588ede9c7efd9b37eee5425101bd865 Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sat, 11 Jul 2015 09:55:51 +0300 Subject: [PATCH 6/8] fix Geef.Tree enumerable --- lib/geef/tree.ex | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/geef/tree.ex b/lib/geef/tree.ex index 4d190f9..854e695 100644 --- a/lib/geef/tree.ex +++ b/lib/geef/tree.ex @@ -66,30 +66,31 @@ defmodule Geef.TreeError do end end -defimpl Enumerable, for: Geef.Tree do +defimpl Enumerable, for: Geef.Object do + alias Geef.Object alias Geef.Tree alias Geef.TreeError - def count(tree) do + def count(tree = %Object{type: :tree}) do {:ok, Tree.count(tree)} end - def member?(tree, key) do + def member?(tree = %Object{type: :tree}, key) do case Tree.get(tree, key) do {:ok, _} -> {:ok, true} _ -> {:ok, false} end end - def reduce(tree, acc, fun) do + def reduce(tree = %Object{type: :tree}, acc, fun) do reduce(tree, 0, Tree.count(tree), acc, fun) end # We're done when the index is equal to the number of entries - defp reduce(_, idx, idx, acc, _), do: acc + defp reduce(_, idx, idx, {:cont, acc}, _), do: {:done, acc} # Call the user-passed function and recurse with the next index - defp reduce(tree, idx, count, acc, fun) do + defp reduce(tree, idx, count, {:cont, acc}, fun) do case Tree.nth(tree, idx) do {:ok, entry} -> reduce(tree, idx + 1, count, fun.(entry, acc), fun) @@ -98,4 +99,9 @@ defimpl Enumerable, for: Geef.Tree do end end + # Almost default Enumerable implementation + defp reduce(_, _, _, {:halt, acc}, _), do: {:halted, acc} + defp reduce(tree, idx, count, {:suspend, acc}, fun) do + {:suspended, acc, &reduce(tree, idx, count, &1, fun)} + end end From 01254f2f901c62df45a7e85821560e1aaa164579 Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sat, 18 Jul 2015 14:24:15 +0300 Subject: [PATCH 7/8] add Geef.Config module for Elixir --- lib/geef.ex | 17 ++++++++++------- lib/geef/config.ex | 25 +++++++++++++++++++++++++ lib/geef/repository.ex | 2 ++ src/geef_config.erl | 9 ++++++++- test/config_test.exs | 30 ++++++++++++++++++++++++++++++ test/test_helper.exs | 2 +- 6 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 lib/geef/config.ex create mode 100644 test/config_test.exs diff --git a/lib/geef.ex b/lib/geef.ex index bfd3017..90745b5 100644 --- a/lib/geef.ex +++ b/lib/geef.ex @@ -2,17 +2,20 @@ defmodule Geef do defmacro __using__(_) do quote do - alias Geef.Repository + alias Geef.Blob + alias Geef.Commit + alias Geef.Config + alias Geef.Index + alias Geef.Index.Tree + alias Geef.Object alias Geef.Odb alias Geef.Oid alias Geef.Reference - alias Geef.Object - alias Geef.Commit - alias Geef.Tree - alias Geef.TreeEntry - alias Geef.Blob - alias Geef.Tag + alias Geef.Repository alias Geef.Signature + alias Geef.Tree + alias Geef.Tag + alias Geef.TreeEntry end end diff --git a/lib/geef/config.ex b/lib/geef/config.ex new file mode 100644 index 0000000..fb5a236 --- /dev/null +++ b/lib/geef/config.ex @@ -0,0 +1,25 @@ +defmodule Geef.Config do + import Geef + alias Geef.Repository + + def stop(config), do: :geef_config.stop(config) + + def open(repo) when is_pid(repo), do: Repository.config(repo) + def open(path), do: :geef_config.open(path) + def open!(arg), do: open(arg) |> assert_ok + + def set(config, key, value) do + :geef_config.set(config, make_config_key(key), value) + end + + def get_bool(config, key) do + :geef_config.get_bool(config, make_config_key(key)) + end + + def get_string(config, key) do + :geef_config.get_string(config, make_config_key(key)) + end + + defp make_config_key(key) when is_binary(key), do: String.to_char_list(key) + defp make_config_key(key), do: key +end diff --git a/lib/geef/repository.ex b/lib/geef/repository.ex index 91000bc..ef6b189 100644 --- a/lib/geef/repository.ex +++ b/lib/geef/repository.ex @@ -15,7 +15,9 @@ defmodule Geef.Repository do def discover(path), do: :geef_repo.discover(path) def bare?(repo), do: :geef_repo.is_bare(repo) + def gitdir(repo), do: :geef_repo.path(repo) def workdir(repo), do: :geef_repo.workdir(repo) + def config(repo), do: :geef_repo.config(repo) def reference_names(repo), do: :geef_repo.references(repo) end diff --git a/src/geef_config.erl b/src/geef_config.erl index ff13767..e60831d 100644 --- a/src/geef_config.erl +++ b/src/geef_config.erl @@ -16,6 +16,7 @@ -export([set/3]). -export([get_bool/2]). -export([get_string/2]). +-export([stop/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -60,6 +61,9 @@ get_bool(Pid, Name) -> get_string(Pid, Name) -> gen_server:call(Pid, {get_string, Name}). +stop(Pid) -> + gen_server:call(Pid, stop). + %%%=================================================================== %%% gen_server callbacks %%%=================================================================== @@ -96,7 +100,10 @@ handle_call({set_string, Name, Val}, _From, State = #state{handle=Handle}) -> handle_call({get_string, Name}, _From, State = #state{handle=Handle}) -> Reply = geef_nif:config_get_string(Handle, Name), - {reply, Reply, State}. + {reply, Reply, State}; + +handle_call(stop, _From, State) -> + {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% @private diff --git a/test/config_test.exs b/test/config_test.exs new file mode 100644 index 0000000..f12511b --- /dev/null +++ b/test/config_test.exs @@ -0,0 +1,30 @@ +defmodule ConfigTest do + use ExUnit.Case + use Geef + import RepoHelpers + + + setup do + {repo, path} = tmp_bare + Process.link(repo) + {:ok, config} = Repository.config(repo) + on_exit(fn -> File.rm_rf!(path) end) + {:ok, [config: config, path: path]} + end + + test "write and get a boolean", meta do + config = meta[:config] + var = "core.logallrefupdates" + assert :ok = Config.set(config, var, true) + assert {:ok, true} = Config.get_bool(config, var) + end + + test "write and get a string", meta do + config = meta[:config] + var = "user.name" + val = "Random J. Hacker" + assert :ok = Config.set(config, var, val) + assert {:ok, ^val} = Config.get_string(config, var) + end + +end diff --git a/test/test_helper.exs b/test/test_helper.exs index 19b1813..0217d3c 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -2,7 +2,7 @@ ExUnit.start defmodule RepoHelpers do def tmp_bare do - {a, b, c} = :erlang.now() + {a, b, c} = :erlang.timestamp() n = node() dir = :io_lib.format("geef-~p~p~p~p.git", [n, a, b, c]) path = Path.join(System.tmp_dir!, dir) From 79f89bcd4121a358e9f4b891dc6f03e341a1d4c7 Mon Sep 17 00:00:00 2001 From: Ramon Snir Date: Sat, 18 Jul 2015 20:36:14 +0300 Subject: [PATCH 8/8] add Geef.Revwalk module for Elixir --- c_src/revwalk.c | 12 ++++++++++++ c_src/revwalk.h | 1 + lib/geef.ex | 1 + lib/geef/repository.ex | 1 + lib/geef/revwalk.ex | 32 ++++++++++++++++++++++++++++++++ src/geef_nif.erl | 3 +++ src/geef_repo.erl | 40 ++++++++++++++++++++-------------------- src/geef_revwalk.erl | 19 +++++++++++++++++-- test/revwalk_test.erl | 16 ++++++++-------- test/revwalk_test.exs | 29 +++++++++++++++++++++++++++++ test/test_helper.exs | 23 ++++++++++++++++++++++- 11 files changed, 146 insertions(+), 31 deletions(-) create mode 100644 lib/geef/revwalk.ex create mode 100644 test/revwalk_test.exs diff --git a/c_src/revwalk.c b/c_src/revwalk.c index 0a85f60..8ae6013 100644 --- a/c_src/revwalk.c +++ b/c_src/revwalk.c @@ -108,6 +108,18 @@ geef_revwalk_sorting(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return atoms.ok; } +ERL_NIF_TERM +geef_revwalk_simplify_first_parent(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_revwalk *walk; + + if (!enif_get_resource(env, argv[0], geef_revwalk_type, (void **) &walk)) + return enif_make_badarg(env); + + git_revwalk_simplify_first_parent(walk->walk); + + return atoms.ok; +} ERL_NIF_TERM geef_revwalk_reset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) diff --git a/c_src/revwalk.h b/c_src/revwalk.h index c10b898..881c424 100644 --- a/c_src/revwalk.h +++ b/c_src/revwalk.h @@ -18,6 +18,7 @@ ERL_NIF_TERM geef_revwalk_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[ ERL_NIF_TERM geef_revwalk_next(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_revwalk_push(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_revwalk_sorting(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_revwalk_simplify_first_parent(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_revwalk_reset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); #endif diff --git a/lib/geef.ex b/lib/geef.ex index 90745b5..0269d8d 100644 --- a/lib/geef.ex +++ b/lib/geef.ex @@ -12,6 +12,7 @@ defmodule Geef do alias Geef.Oid alias Geef.Reference alias Geef.Repository + alias Geef.Revwalk alias Geef.Signature alias Geef.Tree alias Geef.Tag diff --git a/lib/geef/repository.ex b/lib/geef/repository.ex index ef6b189..189bac5 100644 --- a/lib/geef/repository.ex +++ b/lib/geef/repository.ex @@ -18,6 +18,7 @@ defmodule Geef.Repository do def gitdir(repo), do: :geef_repo.path(repo) def workdir(repo), do: :geef_repo.workdir(repo) def config(repo), do: :geef_repo.config(repo) + def revwalk(repo), do: :geef_repo.revwalk(repo) def reference_names(repo), do: :geef_repo.references(repo) end diff --git a/lib/geef/revwalk.ex b/lib/geef/revwalk.ex new file mode 100644 index 0000000..262e906 --- /dev/null +++ b/lib/geef/revwalk.ex @@ -0,0 +1,32 @@ +defmodule Geef.Revwalk do + import Geef + alias Geef.Object + + def stop(walk), do: :geef_revwalk.stop(walk) + + def open(repo) when is_pid(repo), do: Repository.revwalk(repo) + def open!(arg), do: open(arg) |> assert_ok + + def push(walk, %Object{type: :commit, id: commit}), do: push(walk, commit) + def push(walk, commit), do: :geef_revwalk.push(walk, commit) + + def hide(walk, %Object{type: :commit, id: commit}), do: hide(walk, commit) + def hide(walk, commit), do: :geef_revwalk.hide(walk, commit) + + def simplify_first_parent(walk), do: :geef_revwalk.simplify_first_parent(walk) + + def sorting(walk, flags \\ []) + def sorting(walk, flags) when is_list(flags) do + flags = Enum.map(flags, &compile_sorting_flag/1) + :geef_revwalk.sorting(walk, flags) + end + def sorting(walk, flag), do: sorting(walk, [flag]) + + def next(walk), do: :geef_revwalk.next(walk) + + def reset(walk), do: :geef_revwalk.reset(walk) + + defp compile_sorting_flag(:topological_sort), do: :toposort + defp compile_sorting_flag(:time_sort), do: :timesort + defp compile_sorting_flag(:reverse_sort), do: :reversesort +end diff --git a/src/geef_nif.erl b/src/geef_nif.erl index 96a262b..df6e4e3 100644 --- a/src/geef_nif.erl +++ b/src/geef_nif.erl @@ -159,6 +159,9 @@ revwalk_next(_Walk) -> revwalk_sorting(_Walk, _Sort) -> ?NIF_FN. +revwalk_simplify_first_parent(_Walk) -> + ?NIF_FN. + revwalk_reset(_Walk) -> ?NIF_FN. diff --git a/src/geef_repo.erl b/src/geef_repo.erl index d8e684c..f64a4e3 100644 --- a/src/geef_repo.erl +++ b/src/geef_repo.erl @@ -7,12 +7,12 @@ %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + terminate/2, code_change/3]). %% API -export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1, - lookup_object/2, revwalk/1, stop/1, - reference_dwim/2, handle/1, iterator/2]). + lookup_object/2, revwalk/1, stop/1, + reference_dwim/2, handle/1, iterator/2]). -export([reference_has_log/2]). -export([reference_resolve/2]). -export([reflog_read/2, reflog_delete/2]). @@ -37,21 +37,21 @@ discover(Path) -> -spec open(iolist()) -> {ok, pid()} | {error, term()}. open(Path) -> case geef_nif:repository_open(Path) of - {ok, Handle} -> - start_link(Handle); - Other -> - Other + {ok, Handle} -> + start_link(Handle); + Other -> + Other end. %% @doc Initialize a new repository -spec init(iolist(), boolean()) -> {ok, pid()} | {error, term()}. init(Path, Bare) -> case geef_nif:repository_init(Path, Bare) of - {ok, Handle} -> - start_link(Handle); - Other -> - Other - end. + {ok, Handle} -> + start_link(Handle); + Other -> + Other + end. %% @doc The repository's git-dir path -spec path(pid()) -> binary(). @@ -224,18 +224,18 @@ start_link(Handle) -> handle_odb(Handle) -> case geef_nif:repository_get_odb(Handle) of - {ok, OdbHandle} -> - geef_odb:start_link(OdbHandle); - Other -> - Other + {ok, OdbHandle} -> + geef_odb:start_link(OdbHandle); + Other -> + Other end. handle_revwalk(Handle) -> case geef_nif:revwalk_new(Handle) of - {ok, WalkHandle} -> - geef_revwalk:start_link(WalkHandle); - Error -> - Error + {ok, WalkHandle} -> + geef_revwalk:start_link(WalkHandle); + Error -> + Error end. handle_config(Handle) -> diff --git a/src/geef_revwalk.erl b/src/geef_revwalk.erl index 14d2ec2..10a9dd1 100644 --- a/src/geef_revwalk.erl +++ b/src/geef_revwalk.erl @@ -12,11 +12,11 @@ %% API -export([start_link/1]). --export([push/2, hide/2, next/1, sorting/2, stop/1]). +-export([push/2, hide/2, next/1, sorting/2, simplify_first_parent/1, reset/1, stop/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + terminate/2, code_change/3]). -record(state, {handle}). -include("geef_records.hrl"). @@ -46,7 +46,16 @@ sorting(Pid, Opts) when is_list(Opts) -> sorting(Pid, Opt) when is_atom(Opt) -> gen_server:call(Pid, {sort, [Opt]}). +-spec simplify_first_parent(pid) -> ok. +simplify_first_parent(Pid) -> + gen_server:call(Pid, simplify_first_parent). + +-spec reset(pid) -> ok. +reset(Pid) -> + gen_server:call(Pid, reset). + %% @doc Next commit in the walk +-spec next(pid) -> {ok, geef_oid:oid()} | {error, iterover}. next(Pid) -> gen_server:call(Pid, next). @@ -76,12 +85,18 @@ init(Handle) -> handle_call({sort, Opts}, _From, State = #state{handle=Handle}) -> geef_nif:revwalk_sorting(Handle, Opts), {reply, ok, State}; +handle_call(simplify_first_parent, _From, State = #state{handle=Handle}) -> + geef_nif:revwalk_simplify_first_parent(Handle), + {reply, ok, State}; handle_call({push, Oid}, _From, State = #state{handle=Handle}) -> Reply = geef_nif:revwalk_push(Handle, Oid, false), {reply, Reply, State}; handle_call({hide, Oid}, _From, State = #state{handle=Handle}) -> Reply = geef_nif:revwalk_push(Handle, Oid, true), {reply, Reply, State}; +handle_call(reset, _From, State = #state{handle=Handle}) -> + geef_nif:revwalk_reset(Handle), + {reply, ok, State}; handle_call(next, _From, State = #state{handle=Handle}) -> Reply = geef_nif:revwalk_next(Handle), {reply, Reply, State}; diff --git a/test/revwalk_test.erl b/test/revwalk_test.erl index 3f79664..c938b32 100644 --- a/test/revwalk_test.erl +++ b/test/revwalk_test.erl @@ -4,10 +4,10 @@ repo_test_() -> case os:getenv("GEEF_RESOURCES") of - false -> - []; - _ -> - {foreach, fun start/0, fun stop/1, [fun amount_test/1]} + false -> + []; + _ -> + {foreach, fun start/0, fun stop/1, [fun amount_test/1]} end. start() -> @@ -18,10 +18,10 @@ start() -> count_walk(Walk, Acc) -> case geef_revwalk:next(Walk) of - {ok, _} -> - count_walk(Walk, Acc + 1); - {error, iterover} -> - Acc + {ok, _} -> + count_walk(Walk, Acc + 1); + {error, iterover} -> + Acc end. amount_test(Repo) -> diff --git a/test/revwalk_test.exs b/test/revwalk_test.exs new file mode 100644 index 0000000..0fcbea6 --- /dev/null +++ b/test/revwalk_test.exs @@ -0,0 +1,29 @@ +defmodule RevwalkTest do + use ExUnit.Case + use Geef + import RepoHelpers + + + setup do + {repo, path, head, boring_ancestor} = tmp_commit_line + Process.link(repo) + {:ok, walk} = Repository.revwalk(repo) + on_exit(fn -> File.rm_rf!(path) end) + {:ok, [walk: walk, head: head, boring_ancestor: boring_ancestor]} + end + + test "walk and count", meta do + walk = meta[:walk] + Revwalk.push(walk, meta[:head]) + Revwalk.hide(walk, meta[:boring_ancestor]) + assert 3 = count_walk(walk) + end + + defp count_walk walk, acc \\ 0 + defp count_walk walk, acc do + case Revwalk.next(walk) do + {:ok, _} -> count_walk(walk, acc + 1) + {:error, :iterover} -> acc + end + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs index 0217d3c..d0959c7 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,12 +1,33 @@ ExUnit.start defmodule RepoHelpers do + use Geef + def tmp_bare do {a, b, c} = :erlang.timestamp() n = node() dir = :io_lib.format("geef-~p~p~p~p.git", [n, a, b, c]) path = Path.join(System.tmp_dir!, dir) - {:ok, repo} = Geef.Repository.init(path, true) + {:ok, repo} = Repository.init(path, true) {repo, path} end + + def tmp_commit_line do + {repo, path} = tmp_bare() + sig = Signature.now("Geef Test", "test@geef") + message = "commit message" + {:ok, idx} = Index.new() + {:ok, empty_index} = Index.write_tree(idx, repo) + + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, []) + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, [c]) + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, [c]) + boring_ancestor = c + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, [c]) + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, [c]) + {:ok, c} = Commit.create(repo, sig, sig, message, empty_index, [c]) + head = c + + {repo, path, head, boring_ancestor} + end end