forked from
gazagnaire.org/irmin
Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1(** Import command - import data from external formats. *)
2
3let run ~repo ~branch file =
4 let config = Config.load ~repo () in
5 Eio_main.run @@ fun env ->
6 let fs = Eio.Stdenv.cwd env in
7 Eio.Switch.run @@ fun sw ->
8 let file_path = Eio.Path.(fs / file) in
9 let data = Eio.Path.load file_path in
10 (* Detect format from extension or content *)
11 let is_car =
12 String.length file > 4
13 && String.sub file (String.length file - 4) 4 = ".car"
14 in
15 if is_car then begin
16 (* Import CAR file *)
17 let header, blocks = Atp.Car.of_string ~cid_format:`Atproto data in
18 let irmin_dir = Filename.concat config.Config.store_path ".irmin" in
19 (try Unix.mkdir irmin_dir 0o755 with Unix.Unix_error _ -> ());
20 let store_path = Eio.Path.(fs / irmin_dir / "blocks") in
21 let blockstore = Atp.Blockstore.filesystem store_path in
22 let count = ref 0 in
23 List.iter
24 (fun (cid, block_data) ->
25 blockstore#put cid block_data;
26 incr count)
27 blocks;
28 blockstore#sync;
29 Common.success "Imported %d blocks from %a" !count Common.styled_cyan file;
30 ignore header;
31 ignore branch;
32 0
33 end
34 else begin
35 (* Import as plain content at path *)
36 let (module B : Common.BACKEND) = Common.backend_of_config config in
37 let store = B.open_store ~sw ~fs ~config in
38 let tree =
39 match B.checkout store ~branch with
40 | None -> B.empty_tree store
41 | Some t -> t
42 in
43 let path = Common.path_of_string file in
44 let tree = B.tree_add tree path data in
45 let parents =
46 match B.head store ~branch with None -> [] | Some h -> [ h ]
47 in
48 let message = "Import " ^ file in
49 let hash =
50 B.commit store ~tree ~parents ~message ~author:"irmin <irmin@local>"
51 in
52 B.set_head store ~branch hash;
53 Common.success "Imported %a" Common.styled_cyan file;
54 0
55 end