Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file checks.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212(*
* Copyright (c) 2018-2021 Tarides <contact@tarides.com>
*
* 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.
*)open!ImportopenIrmin_pack.ChecksmoduleIO=Irmin_pack.IO.UnixmoduletypeS=sigincludeSmoduleCheck_self_contained:sigvalrun:root:string->heads:stringlistoption->unitLwt.t(** Ensure that the upper layer of the store is self-contained.*)valterm:(unit->unit)Cmdliner.Term.t(** A pre-packaged [Cmdliner] term for executing {!run}. *)endvalcli:unit->empty(** Run a [Cmdliner] binary containing tools for running offline checks. *)endmoduleLayout=structincludeLayout(** Only works for layered stores that use the default names for layers. *)letlower,upper0,upper1=letof_idid~root=Filename.concatroot(Irmin_layers.Layer_id.to_stringid)in(of_id`Lower,of_id`Upper0,of_id`Upper1)lettoplevelroot=[Layout.flip~root;lower~root;upper1~root;upper0~root]endmoduleMake(M:Maker)(Store:S.Store)=structmoduleSimple=Make(M)moduleHash=Store.Hashletread_flip~root=letpath=Layout.flip~rootinmatchIO.existspathwith|false->Lwt.return_none|true->let*t=IO_layers.IO.vpathinlet*a=IO_layers.IO.read_flipt>|=function|true->`Upper1|false->`Upper0inIO_layers.IO.closet>|=fun()->SomeamoduleStat=structmoduleLayer_stat=Simple.Stattypefiles_layer={flip:[`Upper1|`Upper0]option;lower:Layer_stat.files;upper1:Layer_stat.files;upper0:Layer_stat.files;}[@@derivingirmin]typeobjects_layer={lower:Layer_stat.objects;upper1:Layer_stat.objects;upper0:Layer_stat.objects;}[@@derivingirmin]typet={hash_size:Layer_stat.size;log_size:int;files:files_layer;objects:objects_layer;}[@@derivingirmin]letv=Layer_stat.v~version:`V2letv~root=read_flip~root>|=funflip->letlower=v~root:(Layout.lower~root)andupper1=v~root:(Layout.upper1~root)andupper0=v~root:(Layout.upper0~root)in{flip;lower;upper1;upper0}letconfroot=Irmin_pack.Conf.v~readonly:false~fresh:falserootlettraverse_indexes~rootlog_size=letlower=Layer_stat.traverse_index~root:(Layout.lower~root)log_sizeandupper1=Layer_stat.traverse_index~root:(Layout.upper1~root)log_sizeandupper0=Layer_stat.traverse_index~root:(Layout.upper0~root)log_sizein{lower;upper1;upper0}letrun~root=Logs.app(funf->f"Getting statistics for store: `%s'@,"root);letlog_size=confroot|>Irmin_pack.Conf.index_log_sizeinletobjects=traverse_indexes~rootlog_sizeinlet+files=v~rootin{hash_size=BytesHash.hash_size;log_size;files;objects}|>Irmin.Type.pp_json~minify:falsetFmt.stdoutletterm_internal=Cmdliner.Term.(const(funroot()->Lwt_main.run(run~root))$path)letterm=letdoc="Print high-level statistics about the store."inCmdliner.Term.(term_internal$setup_log,info~doc"stat")endmoduleIntegrity_check=structletconfroot=Irmin_pack.Conf.v~readonly:false~fresh:falserootletrun~root~auto_repair=letconf=confrootinletlower_root=Layout.lower~rootinletupper_root1=Layout.upper1~rootinletupper_root0=Layout.upper0~rootinletconf=Conf.v~conf~lower_root~upper_root1~upper_root0()inlet+repo=Store.Repo.vconfinletres=Store.integrity_check~auto_repairrepoinList.iter(fun(r,id)->Simple.Integrity_check.handle_result~name:(Irmin_layers.Layer_id.to_stringid)r)resletterm_internal=letauto_repair=letopenCmdliner.Arginvalue&(flag@@info~doc:"Automatically repair issues"["auto-repair"])inCmdliner.Term.(const(funrootauto_repair()->Lwt_main.run(run~root~auto_repair))$path$auto_repair)letterm=letdoc="Check integrity of an existing store."inCmdliner.Term.(term_internal$setup_log,info~doc"integrity-check")endmoduleCheck_self_contained=structletconfroot=letconf=Irmin_pack.Conf.v~readonly:truerootinConf.v~conf~with_lower:false()letheads=letopenCmdliner.Arginvalue&opt(some(list~sep:','string))None&info["heads"]~doc:"List of head commit hashes"~docv:"HEADS"letcheck_store~root~heads(moduleS:S.Store)=let*repo=S.Repo.v(confroot)inlet*heads=matchheadswith|None->S.Repo.headsrepo|Someheads->Lwt_list.filter_map_s(funx->matchRepr.of_stringS.Hash.txwith|Okx->S.Commit.of_hashrepox|_->Lwt.returnNone)headsinlet*()=S.check_self_contained~headsrepo>|=function|Ok(`Msgmsg)->Logs.app(funl->l"Ok -- %s"msg)|Error(`Msgmsg)->Logs.err(funl->l"Error -- %s"msg)inS.Repo.closerepoletrun~root~heads=check_store~root~heads(moduleStore)letterm_internal=Cmdliner.Term.(const(funrootheads()->Lwt_main.run(run~root~heads))$path$heads)letterm=letdoc="Check that the upper layer of the store is self contained."inCmdliner.Term.(term_internal$setup_log,info~doc"check-self-contained")endletcli()=Simple.cli~terms:[Stat.term;Integrity_check.term;Check_self_contained.term]()end