-
Notifications
You must be signed in to change notification settings - Fork 13
/
store.ml
119 lines (106 loc) · 4.63 KB
/
store.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
open Core
type library_name = string
exception RegisteredAlready of library_name
type store = {
library_dir: string;
}
(* Basic operations *)
let list reg = FileUtil.ls reg.library_dir |> List.map ~f:FilePath.basename |> List.sort ~compare:String.compare
let directory reg name = Filename.concat reg.library_dir name
let mem reg name = directory reg name |> FileUtil.test FileUtil.Is_dir
let remove_multiple reg names =
List.map ~f:(directory reg) names |> FileUtil.rm ~force:Force ~recurse:true
let remove reg name =
remove_multiple reg [name]
let add_dir reg name dir =
let add_dir reg name dir = FileUtil.cp ~recurse:true [dir] (directory reg name) in
match mem reg name, FileUtil.test FileUtil.Is_dir dir with
| true, _ -> remove reg name; add_dir reg name dir
| _, false -> failwith (dir ^ " is not a directory")
| false, true -> add_dir reg name dir
(* | false, false -> FileUtil.cp ~recurse:true [dir] (directory reg name) *)
let add_library reg name library =
if mem reg name
then failwith (Printf.sprintf "%s is already registered. Please remove it first." name)
else Library.write_dir (directory reg name) library
let initialize libraries_dir =
FileUtil.mkdir ~parent:true libraries_dir
let read library_dir = {
library_dir = library_dir;
}
(* Tests *)
open Core
let create_new_reg dir =
let registry_dir = Filename.concat dir "registry" in
initialize registry_dir;
read registry_dir
let with_new_reg f =
let dir = Filename_unix.temp_dir "Satyrographos" "Store" in
protect ~f:(fun () -> create_new_reg dir |> f) ~finally:(fun () -> FileUtil.rm ~force:Force ~recurse:true [dir])
let test_library_list ~expect reg =
[%test_result: string list] ~expect (list reg)
let test_library_content ~expect reg p =
[%test_result: string list] ~expect begin
let target_dir = directory reg p in
target_dir |> FileUtil.ls |> List.map ~f:(FilePath.make_relative target_dir)
end
let%test "store: initialize" = with_new_reg (fun _ -> true)
let%test "store: list: empty" = with_new_reg begin fun reg ->
match list reg with [] -> true | _ :: _ -> false
end
let%test_unit "store: add empty dir" = with_new_reg begin fun reg ->
let dir = Filename_unix.temp_dir "Satyrographos" "Library" in
add_dir reg "a" dir;
test_library_list ~expect:["a"] reg;
[%test_result: bool] ~expect:true (mem reg "a");
[%test_result: bool] ~expect:false (mem reg "b");
[%test_result: bool] ~expect:true (directory reg "a" |> FileUtil.(test Is_dir ))
end
let%test_unit "store: add nonempty dir" = with_new_reg begin fun reg ->
let dir = Filename_unix.temp_dir "Satyrographos" "Library" in
FilePath.concat dir "c" |> FileUtil.touch;
add_dir reg "a" dir;
test_library_list ~expect:["a"] reg;
[%test_result: bool] ~expect:true (mem reg "a");
[%test_result: bool] ~expect:false (mem reg "b");
[%test_result: bool] ~expect:true (directory reg "a" |> FileUtil.(test Is_dir));
test_library_content ~expect:["c"] reg "a"
end
let%test_unit "store: add nonempty dir twice" = with_new_reg begin fun reg ->
let dir1 = Filename_unix.temp_dir "Satyrographos" "Library" in
FilePath.concat dir1 "c" |> FileUtil.touch;
add_dir reg "a" dir1;
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["c"] reg "a";
let dir2 = Filename_unix.temp_dir "Satyrographos" "Library" in
FilePath.concat dir2 "d" |> FileUtil.touch;
add_dir reg "a" dir2;
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["d"] reg "a"
end
let%test_unit "store: added dir must be copied" = with_new_reg begin fun reg ->
let dir = Filename_unix.temp_dir "Satyrographos" "Library" in
FilePath.concat dir "c" |> FileUtil.touch;
add_dir reg "a" dir;
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["c"] reg "a";
FilePath.concat dir "d" |> FileUtil.touch;
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["c"] reg "a";
FileUtil.rm [FilePath.concat dir "c"];
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["c"] reg "a";
end
let%test_unit "store: add the same directory twice with different contents" = with_new_reg begin fun reg ->
let dir = Filename_unix.temp_dir "Satyrographos" "Library" in
FilePath.concat dir "c" |> FileUtil.touch;
add_dir reg "a" dir;
test_library_list ~expect:["a"] reg;
test_library_content ~expect:["c"] reg "a";
FilePath.concat dir "d" |> FileUtil.touch;
FileUtil.rm [FilePath.concat dir "c"];
add_dir reg "b" dir;
test_library_list ~expect:["a"; "b"] reg;
test_library_content ~expect:["c"] reg "a";
test_library_content ~expect:["d"] reg "b";
end