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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
type gen_type =
| Float
| Int
| Bool
| String
| Datetime
let gen_type_to_example = function
| Float -> "0.3"
| Int -> "10"
| Bool -> "true"
| String -> {|"foobar"|}
| Datetime -> "(Ptime.of_float_s 1.0 |> Option.get)"
;;
let ocaml_type_of_gen_type = function
| Float -> "float"
| Int -> "int"
| Bool -> "bool"
| String -> "string"
| Datetime -> "Ptime.t"
;;
let caqti_type_of_gen_type = function
| Float -> "float"
| Int -> "int"
| Bool -> "bool"
| String -> "string"
| Datetime -> "ptime"
;;
let conformist_type_of_gen_type = function
| Float -> "float"
| Int -> "int"
| Bool -> "bool"
| String -> "string"
| Datetime -> "datetime"
;;
let gen_type_of_string (s : string) : (gen_type, string) result =
match s with
| "float" -> Ok Float
| "int" -> Ok Int
| "bool" -> Ok Bool
| "string" -> Ok String
| "datetime" -> Ok Datetime
| s -> Error (Format.sprintf "Invalid type '%s' provided" s)
;;
type schema = (string * gen_type) list
let schema_of_string (s : string list) : (schema, string) result =
s
|> List.map (String.split_on_char ':')
|> List.map (fun s ->
match s with
| [ name; type_ ] -> Ok (name, type_)
| _ ->
Error
(Format.sprintf
"Invalid input provided '%s'"
(String.concat ":" s)))
|> List.fold_left
(fun schema next ->
match schema, next with
| Ok schema, Ok (name, type_) ->
(match gen_type_of_string type_ with
| Ok gen_type -> Ok (List.cons (name, gen_type) schema)
| Error msg -> Error msg)
| Error msg, _ -> Error msg
| Ok _, Error msg -> Error msg)
(Result.ok [])
|> Result.map List.rev
;;
type file =
{ name : string
; template : string
; params : (string * string) list
}
let render { template; params; _ } =
List.fold_left
(fun res (name, value) ->
CCString.replace
~which:`All
~sub:(Format.sprintf "{{%s}}" name)
~by:value
res)
template
params
;;
let write_file (file : file) (path : string) : unit =
let content = render file in
let filepath = Format.sprintf "%s/%s" path file.name in
try
Bos.OS.File.write (Fpath.of_string filepath |> Result.get_ok) content
|> Result.get_ok;
print_endline (Format.sprintf "Wrote file '%s'" filepath)
with
| _ ->
let msg = Format.sprintf "Failed to write file '%s'" filepath in
print_endline msg;
failwith msg
;;
let write_files_and_create_dir path files =
Bos.OS.Dir.create (Fpath.of_string path |> Result.get_ok) |> ignore;
List.iter (fun file -> write_file file path) files
;;
let write_in_domain (context : string) (files : file list) : unit =
let root = Core_configuration.root_path () |> Option.get in
let model_path = Format.sprintf "%s/app/domain/%s" root context in
match Bos.OS.Dir.exists (Fpath.of_string model_path |> Result.get_ok) with
| Ok true -> failwith (Format.sprintf "Model '%s' exists already" model_path)
| Ok false | Error _ -> write_files_and_create_dir model_path files
;;
let write_in_test (name : string) (files : file list) : unit =
let root = Core_configuration.root_path () |> Option.get in
let test_path = Format.sprintf "%s/test/%s" root name in
match Bos.OS.Dir.exists (Fpath.of_string test_path |> Result.get_ok) with
| Ok true -> failwith (Format.sprintf "Test '%s' exists already" test_path)
| Ok false | Error _ -> write_files_and_create_dir test_path files
;;
let write_in_database (file : file) : unit =
let root = Core_configuration.root_path () |> Option.get in
let path = Format.sprintf "%s/database" root in
Bos.OS.Dir.create (Fpath.of_string path |> Result.get_ok) |> ignore;
List.iter (fun file -> write_file file path) [ file ]
;;
let write_in_view (name : string) (files : file list) : unit =
let root = Core_configuration.root_path () |> Option.get in
let view_path = Format.sprintf "%s/web/view/%s" root name in
match Bos.OS.Dir.exists (Fpath.of_string view_path |> Result.get_ok) with
| Ok true -> failwith (Format.sprintf "View '%s' exists already" view_path)
| Ok false | Error _ -> write_files_and_create_dir view_path files
;;
type database =
| MariaDb
| PostgreSql
let database_of_string = function
| "mariadb" -> MariaDb
| "postgresql" -> PostgreSql
| database ->
failwith
(Format.sprintf
"Invalid database provided '%s', only 'mariadb' and 'postgresql' \
supported"
database)
;;