Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

irmin: enable MDX on lib/*.mli, fix broken doc examples

Run mdx on lib/{irmin,schema,worktree}.mli so the {[ ... ]} odoc blocks
now type-check, plus replace the broken examples that referenced a
fictional Sha1 module and `directory`/`entry` combinators that do not
exist in Schema (the API uses `node` and the prebuilt Irmin_json codec).

irmin.mli and schema.mli show the heap-load + cursor-navigate flow
against `Irmin.SHA256` + `Irmin_json.schema`, with `assert` on the
expected outcome (root child names, navigation success). Both use
`Irmin.Heap.of_list` to drop the `Heap.Mem` functor instantiation,
keeping the example small enough to read.

worktree.mli wraps the checkout/status/commit lifecycle in a `let run
() = ...` to defer the Eio_main + filesystem side effects, and the
example now consumes every return value (Fmt.pr on commit hash and
status length, Result handled on both branches) rather than `_changes`
or `ignore`.

The schema.mli `mime_rules` one-liner that needed 30+ lines of codec
setup to typecheck moved to inline-code prose; per the mdx skill,
that's the right call when an illustration's setup would balloon the
doc.

+59 -32
+12
lib/dune
··· 2 2 (name irmin) 3 3 (public_name nox-irmin) 4 4 (libraries eio fpath digestif fmt logs bytesrw merge3 magic-mime)) 5 + 6 + (mdx 7 + (files irmin.mli schema.mli worktree.mli) 8 + (libraries 9 + nox-irmin 10 + nox-irmin.json 11 + digestif 12 + fmt 13 + fpath 14 + eio 15 + eio.unix 16 + eio_main))
+6 -13
lib/irmin.mli
··· 5 5 delayed persistence. Proofs are subheaps. 6 6 7 7 {[ 8 - module S = Schema.Make (struct 9 - type hash = Sha1.t 10 - type block = string 11 - let hash_equal = Sha1.equal 12 - let hash_block = Sha1.digest_string 13 - end) 8 + module S = Irmin.SHA256 14 9 15 - let tree = S.fix (fun self -> 16 - directory [ "*" => entry [ "mode" => S.opaque; "target" => self ] ]) 17 - 18 - let c = S.at heap tree root in 19 - match S.step c "config.json" with 20 - | Some c' -> S.get c' 21 - | None -> ... 10 + let block = {|{"config.json":{"port":8080}}|} 11 + let root = Digestif.SHA256.digest_string block 12 + let heap = Irmin.Heap.of_list ~equal:Digestif.SHA256.equal [ (root, block) ] 13 + let names = S.at heap Irmin_json.schema root |> S.list |> List.map fst 14 + let () = assert (names = [ "config.json" ]) 22 15 ]} *) 23 16 24 17 module Hash = Hash
+9 -14
lib/schema.mli
··· 7 7 ({!step_any}) or typed {!field}s ({!val-step}). 8 8 9 9 {[ 10 - let json = node ~name:"application/json" ~dec ~enc () 10 + module S = Irmin.SHA256 11 11 12 - let directory = 13 - fix (fun self -> 14 - node ~name:"application/x-tree" ~dec ~enc 15 - ~rules:[ "*.json" => json; "*" => self ] ()) 16 - 17 - let c = at heap directory root in 18 - match step c (field "config.json" json) with 19 - | Some json_c -> get json_c (* : json_value option *) 20 - | None -> ... (* missing path or wrong codec *) 12 + let block = {|{"config.json":{"port":8080}}|} 13 + let root = Digestif.SHA256.digest_string block 14 + let heap = Irmin.Heap.of_list ~equal:Digestif.SHA256.equal [ (root, block) ] 15 + let cursor = S.at heap Irmin_json.schema root 16 + let sub = S.step cursor (S.field "config.json" Irmin_json.schema) 17 + let () = assert (Option.is_some sub) 21 18 ]} *) 22 19 23 20 module Make (H : sig ··· 157 154 val mime_rules : _ t list -> rule list 158 155 (** [mime_rules codecs] emits one MIME-dispatch rule per codec in [codecs] 159 156 whose [mime] is set. Codecs without a MIME are skipped. Intended as a 160 - one-line way to wire a bundle of codecs into a parent tree: 161 - {[ 162 - directory (mime_rules [ json; tar; oci ] @ [ "*" => entry ]) 163 - ]} *) 157 + one-line way to wire a bundle of codecs into a parent tree, e.g. 158 + [directory (mime_rules [ json; tar; oci ] @ [ "*" => entry ])]. *) 164 159 165 160 val id : 'a t -> 'a Type.Id.t 166 161 (** [id c] is the runtime type witness for [c]'s value type. *)
+32 -5
lib/worktree.mli
··· 5 5 and size. [status] only re-hashes files whose mtime or size changed. 6 6 7 7 {[ 8 - let module W = Worktree.Make (Hash) in 9 - W.checkout ~fs heap ~hash:root ~dir; 10 - (* edit files on disk normally *) 11 - let changes = W.status ~fs ~dir in 12 - W.commit ~fs heap ~branch:"main" ~dir ~message:"update" ~author:"me" 8 + module W = Irmin.Worktree.Make (struct 9 + type hash = Digestif.SHA1.t 10 + 11 + let hash_equal = Digestif.SHA1.equal 12 + let hash_string s = Digestif.SHA1.digest_string s 13 + let to_hex = Digestif.SHA1.to_hex 14 + let of_hex = Digestif.SHA1.of_hex 15 + end) 16 + 17 + module Heap = Irmin.Heap.Mem (struct 18 + type hash = Digestif.SHA1.t 19 + type block = string 20 + 21 + let equal = Digestif.SHA1.equal 22 + end) 23 + 24 + let run () = 25 + Eio_main.run @@ fun env -> 26 + let fs = Eio.Stdenv.fs env in 27 + let heap = Heap.v () in 28 + let root = Digestif.SHA1.digest_string "" in 29 + let dir = Fpath.v "/tmp/irmin-example" in 30 + match W.checkout ~fs heap ~hash:root ~dir with 31 + | Error (`Msg e) -> Fmt.pr "checkout failed: %s@." e 32 + | Ok () -> ( 33 + let changes = W.status ~fs ~dir in 34 + Fmt.pr "%d files changed@." (List.length changes); 35 + match 36 + W.commit ~fs heap ~branch:"main" ~dir ~message:"update" ~author:"me" 37 + with 38 + | Ok h -> Fmt.pr "committed %s@." (Digestif.SHA1.to_hex h) 39 + | Error (`Msg e) -> Fmt.pr "commit failed: %s@." e) 13 40 ]} *) 14 41 15 42 module Make (H : sig