123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224(*
* Copyright (c) 2018-2022 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!Importtypeempty=|moduletypeSubcommand=sigtyperunvalrun:runvalterm_internal:(unit->unit)Cmdliner.Term.t(** A pre-packaged [Cmdliner] term for executing {!val-run}. *)valterm:(unitCmdliner.Term.t*Cmdliner.Term.info[@alert"-deprecated"])(** [term] is {!term_internal} plus documentation and logs initialisation *)endmoduletypeS=sig(** Reads basic metrics from an existing store and prints them to stdout. *)moduleStat:sigincludeSubcommandwithtyperun:=root:string->unitLwt.t(** Internal implementation utilities exposed for use in other integrity
checks. *)typesize=Bytesofint[@@derivingirmin]typeobjects={nb_commits:int;nb_nodes:int;nb_contents:int}[@@derivingirmin]valtraverse_index:root:string->int->objectsendmoduleReconstruct_index:Subcommandwithtyperun:=root:string->output:stringoption->?index_log_size:int->unit->unit(** Rebuilds an index for an existing pack file *)(** Checks the integrity of a store *)moduleIntegrity_check:sigincludeSubcommandwithtyperun:=?ppf:Format.formatter->root:string->auto_repair:bool->always:bool->heads:stringlistoption->unit->unitLwt.tvalhandle_result:?ppf:Format.formatter->?name:string->([<`Fixedofint|`No_error],[<`Cannot_fixofstring|`Corruptedofint])result->unitend(** Checks the integrity of the index in a store *)moduleIntegrity_check_index:sigincludeSubcommandwithtyperun:=root:string->auto_repair:bool->unit->unitend(** Checks the integrity of inodes in a store *)moduleIntegrity_check_inodes:sigincludeSubcommandwithtyperun:=root:string->heads:stringlistoption->unitLwt.tend(** Traverses a commit to get stats on its underlying tree. *)moduleStats_commit:sigincludeSubcommandwithtyperun:=root:string->commit:stringoption->dump_blob_paths_to:stringoption->unit->unitLwt.tendvalcli:?terms:((unitCmdliner.Term.t*Cmdliner.Term.info)[@alert"-deprecated"])list->unit->empty(** Run a [Cmdliner] binary containing tools for running offline checks.
[terms] defaults to the set of checks in this module. *)endmoduletypeStore=sigincludeIrmin.SincludeStore_intf.Swithtyperepo:=repoandtypecommit:=commitendtypeintegrity_error=[`Wrong_hash|`Absent_value]moduletypeSigs=sigtypeintegrity_error=[`Wrong_hash|`Absent_value]typenonrecempty=emptyvalsetup_log:unitCmdliner.Term.tvalpath:stringCmdliner.Term.tmoduletypeSubcommand=SubcommandmoduletypeS=SmoduleMake(_:Store):SmoduleIntegrity_checks(XKey:Pack_key.S)(X:Irmin.Backend.SwithtypeCommit.key=XKey.tandtypeNode.key=XKey.tandtypeSchema.Hash.t=XKey.hash)(Index:Pack_index.S):sigvalcheck_always:?ppf:Format.formatter->auto_repair:bool->check:(kind:[>`Commit|`Contents|`Node]->offset:int63->length:int->Index.key->(unit,[<`Absent_value|`Wrong_hash])result)->Index.t->([>`Fixedofint|`No_error],[>`Cannot_fixofstring|`Corruptedofint])resultvalcheck_minimal:?ppf:Format.formatter->pred:(X.Node.value->(X.Node.Path.stepoption*[<`ContentsofXKey.t|`InodeofXKey.t|`NodeofXKey.t])list)->iter:(contents:(XKey.hashPack_key.t->unitLwt.t)->node:(XKey.t->unitLwt.t)->pred_node:(X.Repo.t->XKey.t->[>`ContentsofXKey.t|`NodeofXKey.t]listLwt.t)->pred_commit:(X.Repo.t->XKey.t->[>`NodeofXKey.t]listLwt.t)->X.Repo.t->unitLwt.t)->check:(offset:int63->length:int->XKey.hash->(unit,[<`Absent_value|`Wrong_hash])result)->recompute_hash:(X.Node.value->XKey.hash)->X.Repo.t->([>`No_error],[>`Cannot_fixofstring])resultLwt.tvalcheck_inodes:?ppf:Format.formatter->iter:(pred_node:(X.Repo.t->XKey.t->([>`ContentsofXKey.t|`NodeofXKey.t]as'a)listLwt.t)->node:(XKey.t->unitLwt.t)->commit:(XKey.t->unitLwt.t)->X.Repo.t->unitLwt.t)->pred:(X.Repo.t->XKey.t->'alistLwt.t)->check:(XKey.t->(unit,string)resultLwt.t)->X.Repo.t->([>`No_error],[>`Cannot_fixofstring])resultLwt.tendmoduleStats(S:sigtypestepvalstep_t:stepIrmin.Type.tmoduleHash:Irmin.Hash.Send):sigtypetvalv:unit->tvalvisit_commit:t->S.Hash.t->unitvalvisit_contents:t->S.Hash.t->unitvalvisit_node:t->S.Hash.t->(S.stepoption*[`ContentsofS.Hash.t|`InodeofS.Hash.t|`NodeofS.Hash.t])list->nb_children:int->width:int->unitvalpp_results:dump_blob_paths_to:stringoption->t->unitendend