From 7a1a079a5a7fb79fb46b756b32e30c226c928159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 10 Apr 2013 15:20:46 +0200 Subject: [PATCH] Make revwalk a gen_server --- src/geef_repo.erl | 18 ++++++- src/geef_revwalk.erl | 115 +++++++++++++++++++++++++++++++++---------- 2 files changed, 107 insertions(+), 26 deletions(-) diff --git a/src/geef_repo.erl b/src/geef_repo.erl index 28c1b4c..7037217 100644 --- a/src/geef_repo.erl +++ b/src/geef_repo.erl @@ -15,7 +15,8 @@ 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, stop/1]). +-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]). -include("geef_records.hrl"). -record(state, {handle}). @@ -80,6 +81,10 @@ references(Pid) -> lookup_object(Pid, Oid) -> gen_server:call(Pid, {lookup_object, Oid}). +%% @doc Create a revision walker for the given repository. +revwalk(Pid) -> + gen_server:call(Pid, revwalk). + stop(Pid) -> gen_server:call(Pid, stop). @@ -112,6 +117,9 @@ handle_call({lookup_object, Oid}, _From, State = #state{handle=Handle}) -> {reply, Reply, State}; handle_call(stop, _From, State) -> {stop, normal, State}; +handle_call(revwalk, _From, State = #state{handle=Handle}) -> + Reply = handle_revwalk(Handle), + {reply, Reply, State}; handle_call(_Request, _From, State) -> Reply = {error, "Unkown call"}, {reply, Reply, State}. @@ -154,3 +162,11 @@ handle_odb(Handle) -> Other -> Other end. + +handle_revwalk(Handle) -> + case geef:revwalk_new(Handle) of + {ok, WalkHandle} -> + geef_revwalk:start_link(WalkHandle); + Error -> + Error + end. diff --git a/src/geef_revwalk.erl b/src/geef_revwalk.erl index 8707bc7..dd0308d 100644 --- a/src/geef_revwalk.erl +++ b/src/geef_revwalk.erl @@ -1,45 +1,110 @@ +%%%------------------------------------------------------------------- +%%% @author Carlos Martín Nieto +%%% @copyright (C) 2013, Carlos Martín Nieto +%%% @doc +%%% +%%% @end +%%% Created : 6 Apr 2013 by Carlos Martín Nieto +%%%------------------------------------------------------------------- -module(geef_revwalk). --export([new/1, push/2, hide/2, next/1, sorting/2]). +-behaviour(gen_server). +%% API +-export([start_link/1]). +-export([push/2, hide/2, next/1, sorting/2]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-record(state, {handle}). -include("geef_records.hrl"). - -%% @doc Create a revision walker --spec new(repo()) -> {ok, revwalk()} | {error, term}. -new(#repo{handle=Handle}) -> - case geef:revwalk_new(Handle) of - {ok, WalkHandle} -> - {ok, #revwalk{handle=WalkHandle}}; - Other -> - Other - end. - +%%%=================================================================== +%%% API +%%%=================================================================== %% @doc Push a commit. This commit and its parents will be included in %% the walk as long as they haven't been hidden. At least one commit %% must be pushed before starting a walk. --spec push(revwalk(), oid()) -> ok | {error, binary()}. -push(#revwalk{handle=Handle}, #oid{oid=Oid}) -> - geef:revwalk_push(Handle, Oid, false). +-spec push(pid(), oid()) -> ok | {error, binary()}. +push(Pid, #oid{oid=Oid}) -> + gen_server:call(Pid, {push, Oid}). %% @doc Hide a commit. Hide a commit and its parents. Any Parent of %% this commit won't be included in the walk. --spec hide(revwalk(), oid()) -> ok | {error, binary()}. -hide(#revwalk{handle=Handle}, #oid{oid=Oid}) -> - geef:revwalk_push(Handle, Oid, true). +-spec hide(pid(), oid()) -> ok | {error, binary()}. +hide(Pid, #oid{oid=Oid}) -> + gen_server:call(Pid, {hide, Oid}). + +%% @doc Select the sorting method +-spec sorting(pid, atom() | [atom()]) -> ok. +sorting(Pid, Opts) when is_list(Opts) -> + gen_server:call(Pid, {sort, Opts}); +sorting(Pid, Opt) when is_atom(Opt) -> + gen_server:call(Pid, {sort, [Opt]}). %% @doc Next commit in the walk -next(#revwalk{handle=Handle}) -> +next(Pid) -> + gen_server:call(Pid, next). + +%%-------------------------------------------------------------------- +%% @doc +%% Starts the server +%% +%% @spec start_link() -> {ok, Pid} | ignore | {error, Error} +%% @end +%%-------------------------------------------------------------------- +start_link(Handle) -> + gen_server:start_link(?MODULE, Handle, []). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +%% @private +init(Handle) -> + {ok, #state{handle=Handle}}. + +%% @private +handle_call({sort, Opts}, _From, State = #state{handle=Handle}) -> + geef:revwalk_sorting(Handle, Opts), + {reply, ok, State}; +handle_call({push, Oid}, _From, State = #state{handle=Handle}) -> + Reply = geef:revwalk_push(Handle, Oid, false), + {reply, Reply, State}; +handle_call({hide, Oid}, _From, State = #state{handle=Handle}) -> + Reply = geef:revwalk_push(Handle, Oid, true), + {reply, Reply, State}; +handle_call(next, _From, State = #state{handle=Handle}) -> + Reply = handle_next(Handle), + {reply, Reply, State}. + +%% @private +handle_cast(_Msg, State) -> + {noreply, State}. + +%% @private +handle_info(_Info, State) -> + {noreply, State}. + +%% @private +terminate(_Reason, _State) -> + ok. + +%% @private +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +handle_next(Handle) -> case geef:revwalk_next(Handle) of {ok, Oid} -> {ok, #oid{oid=Oid}}; Other -> Other end. - -sorting(#revwalk{handle=Handle}, Opts) when is_list(Opts) -> - geef:revwalk_sorting(Handle, Opts); -sorting(Walk = #revwalk{}, Opt) when is_atom(Opt) -> - sorting(Walk, [Opt]). -