Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sync_ext.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212(*
* Copyright (c) 2013-2017 Thomas Gazagnaire <thomas@gazagnaire.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openLwt.InfixopenSletinvalid_argffmt=Fmt.kstrfLwt.fail_invalid_argfmtletsrc=Logs.Src.create"irmin.sync"~doc:"Irmin remote sync"moduleLog=(valLogs.src_logsrc:Logs.LOG)letremote_storemx=Store.Store(m,x)moduleMake(S:Store.S)=structmoduleB=S.Private.Synctypedb=S.ttypecommit=S.commitletconvdxdy=letdx_to_bin_string=Type.(unstage(to_bin_stringdx))inletdy_of_bin_string=Type.(unstage(of_bin_stringdy))inType.stage(funx->dy_of_bin_string(dx_to_bin_stringx))letconvert_slice(typers)(moduleRP:PRIVATEwithtypeSlice.t=r)(moduleSP:PRIVATEwithtypeSlice.t=s)r=letconv_contents_k=Type.unstage(convRP.Contents.Key.tSP.Contents.Key.t)inletconv_contents_v=Type.unstage(convRP.Contents.Val.tSP.Contents.Val.t)inletconv_node_k=Type.unstage(convRP.Node.Key.tSP.Node.Key.t)inletconv_node_v=Type.unstage(convRP.Node.Val.tSP.Node.Val.t)inletconv_commit_k=Type.unstage(convRP.Commit.Key.tSP.Commit.Key.t)inletconv_commit_v=Type.unstage(convRP.Commit.Val.tSP.Commit.Val.t)inSP.Slice.empty()>>=funs->RP.Slice.iterr(function|`Contents(k,v)->(letk=conv_contents_kkinletv=conv_contents_vvinmatch(k,v)with|Okk,Okv->SP.Slice.adds(`Contents(k,v))|_->Lwt.return_unit)|`Node(k,v)->(letk=conv_node_kkinletv=conv_node_vvinmatch(k,v)with|Okk,Okv->SP.Slice.adds(`Node(k,v))|_->Lwt.return_unit)|`Commit(k,v)->(letk=conv_commit_kkinletv=conv_commit_vvinmatch(k,v)with|Okk,Okv->SP.Slice.adds(`Commit(k,v))|_->Lwt.return_unit))>>=fun()->Lwt.returnsletconvssrcdstl=letconv=Type.unstage(convsrcdst)inList.fold_left(funaccx->matchconvxwithOkx->x::acc|_->acc)[]lletpp_branch=Type.ppS.Branch.tletpp_hash=Type.ppS.Hash.ttypestatus=[`Empty|`Headofcommit]letpp_statusppf=function|`Empty->Fmt.stringppf"empty"|`Headc->Type.ppS.Hash.tppf(S.Commit.hashc)letstatus_tt=letopenTypeinvariant"status"(funemptyhead->function|`Empty->empty|`Headc->headc)|~case0"empty"`Empty|~case1"head"S.(commit_t@@repot)(func->`Headc)|>sealvletfetcht?depthremote=matchremotewith|Store.Store((moduleR),r)->(Log.debug(funf->f"fetch store");lets_repo=S.repotinletr_repo=R.reporinletconv=Type.unstage(convR.(commit_tr_repo)S.(commit_ts_repo))inS.Repo.headss_repo>>=funmin->letmin=convsS.(commit_ts_repo)R.(commit_tr_repo)mininR.Head.findr>>=function|None->Lwt.return(Ok`Empty)|Someh->(R.Repo.export(R.repor)?depth~min~max:(`Max[h])>>=funr_slice->convert_slice(moduleR.Private)(moduleS.Private)r_slice>>=funs_slice->S.Repo.imports_repos_slice>|=function|Errore->Errore|Ok()->(matchconvhwithOkh->Ok(`Headh)|Errore->Errore)))|S.Ee->(matchS.statustwith|`Empty|`Commit_->Lwt.return(Ok`Empty)|`Branchbr->(Log.debug(funl->l"Fetching branch %a"pp_branchbr);B.v(S.repot)>>=fung->B.fetchg?depthebr>>=function|Error_ase->Lwt.returne|Ok(Somec)->(Log.debug(funl->l"Fetched %a"pp_hashc);S.Commit.of_hash(S.repot)c>|=function|None->Ok`Empty|Somex->Ok(`Headx))|OkNone->(S.Head.findt>>=function|Someh->Lwt.return(Ok(`Headh))|None->Lwt.return(Ok`Empty))))|_->Lwt.return(Error(`Msg"fetch operation is not available"))letfetch_exnt?depthremote=fetcht?depthremote>>=function|Okh->Lwt.returnh|Error(`Msge)->invalid_argf"Sync.fetch_exn: %s"etypepull_error=[`Msgofstring|Merge.conflict]letpp_pull_errorppf=function|`Msgs->Fmt.stringppfs|`Conflictc->Fmt.pfppf"conflict: %s"cletpullt?depthremotekind:(status,pull_error)resultLwt.t=fetcht?depthremote>>=function|Errore->Lwt.return(Error(e:>pull_error))|Ok(`Headk)->(matchkindwith|`Set->S.Head.settk>|=fun()->Ok(`Headk)|`Mergeinfo->(S.Head.merge~into:t~infok>>=function|Ok()->Lwt.return(Ok(`Headk))|Errore->Lwt.return(Error(e:>pull_error))))|Ok`Empty->Lwt.return(Ok`Empty)letpull_exnt?depthremotekind=pullt?depthremotekind>>=function|Okx->Lwt.returnx|Errore->invalid_argf"Sync.pull_exn: %a"pp_pull_erroretypepush_error=[`Msgofstring|`Detached_head]letpp_push_errorppf=function|`Msgs->Fmt.stringppfs|`Detached_head->Fmt.stringppf"cannot push to a non-persistent store"letpusht?depthremote=Log.debug(funf->f"push");matchremotewith|Store.Store((moduleR),r)->(S.Head.findt>>=function|None->Lwt.return(Ok`Empty)|Someh->(Log.debug(funf->f"push store");R.Repo.heads(R.repor)>>=funmin->letr_repo=R.reporinlets_repo=S.repotinletmin=convsR.(commit_tr_repo)S.(commit_ts_repo)mininletconv=Type.unstage(convS.(commit_ts_repo)R.(commit_tr_repo))inS.Repo.export(S.repot)?depth~min>>=funs_slice->convert_slice(moduleS.Private)(moduleR.Private)s_slice>>=funr_slice->R.Repo.import(R.repor)r_slice>>=function|Errore->Lwt.return(Error(e:>push_error))|Ok()->(matchconvhwith|Errore->Lwt.return(Error(e:>push_error))|Okh->R.Head.setrh>>=fun()->S.Head.gett>|=funhead->Ok(`Headhead))))|S.Ee->(matchS.statustwith|`Empty->Lwt.return(Ok`Empty)|`Commit_->Lwt.return(Error`Detached_head)|`Branchbr->(S.of_branch(S.repot)br>>=S.Head.get>>=funhead->B.v(S.repot)>>=fung->B.pushg?depthebr>>=function|Ok()->Lwt.return(Ok(`Headhead))|Errorerr->Lwt.return(Error(err:>push_error))))|_->Lwt.return(Error(`Msg"push operation is not available"))letpush_exnt?depthremote=pusht?depthremote>>=function|Okx->Lwt.returnx|Errore->invalid_argf"Sync.push_exn: %a"pp_push_erroreend