Source file config.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
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
open Ez_file.V1
open Types
open EzFile.OP
let config_of_toml filename =
match EzToml.from_file filename with
| `Error _ -> Error.raise "Could not parse config file %S" filename
| `Ok table ->
let config_author = EzToml.get_string_option table [ "user"; "author" ] in
let config_github_organization =
EzToml.get_string_option table [ "user"; "github-organization" ]
in
let config_license = EzToml.get_string_option table [ "user"; "license" ] in
let config_share_dir =
EzToml.get_string_option table [ "user"; "share-dir" ]
in
let config_copyright =
EzToml.get_string_option table [ "user"; "copyright" ]
in
let config_opam_repo =
EzToml.get_string_option table [ "user"; "opam-repo" ]
in
let config_dev_tools =
EzToml.get_string_list_option table [ "user"; "dev-tools" ]
in
let config_auto_upgrade =
EzToml.get_bool_option table [ "user"; "auto-upgrade" ]
in
let config_auto_opam_yes =
EzToml.get_bool_option table [ "user"; "auto-opam-yes" ]
in
{ config_author;
config_github_organization;
config_share_dir;
config_license;
config_copyright;
config_opam_repo;
config_dev_tools;
config_auto_upgrade ;
config_auto_opam_yes ;
}
let config_template =
{|
[user]
# author = "Author Name <email>"
# github-organization = "...organization..."
# license = "...license..."
# copyright = "Company Ltd"
## Location of your local project opam-repo:
# opam-repo = "/home/user/GIT/opam-repository"
# dev-tools = [ "merlin", "tuareg" ]
## Do not upgrade project at 'drom build'
# auto-upgrade = false
## Do not call opam with -y for local opam switches:
# auto-opam-yes = false
|}
let update_with oldc newc =
{
config_author = ( match newc.config_author, oldc.config_author with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_github_organization =
( match newc.config_github_organization,
oldc.config_github_organization with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_share_dir = ( match newc.config_share_dir, oldc.config_share_dir with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_license = ( match newc.config_license, oldc.config_license with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_copyright = ( match newc.config_copyright, oldc.config_copyright with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_opam_repo = ( match newc.config_opam_repo, oldc.config_opam_repo with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_dev_tools = ( match newc.config_dev_tools, oldc.config_dev_tools with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_auto_upgrade = ( match newc.config_auto_upgrade, oldc.config_auto_upgrade with
| None, oldc -> oldc
| newc, _ -> newc ) ;
config_auto_opam_yes = ( match newc.config_auto_opam_yes, oldc.config_auto_opam_yes with
| None, oldc -> oldc
| newc, _ -> newc ) ;
}
let getenv_opt v = match Sys.getenv v with
| exception Not_found -> None
| s -> Some s
let getenv_bool_opt v =
match getenv_opt v with
| None -> None
| Some ( "no" | "0" | "n" | "N" ) -> Some false
| _ -> Some true
let load () =
let config_file = Globals.config_dir // "config" in
if not @@ Sys.file_exists config_file then begin
EzFile.make_dir ~p:true Globals.config_dir;
EzFile.write_file config_file config_template
end;
let config_home = config_of_toml config_file in
let config_env = {
config_author = getenv_opt "DROM_AUTHOR" ;
config_github_organization = getenv_opt "DROM_GITHUB_ORGANIZATION" ;
config_license = getenv_opt "DROM_GITHUB_ORGANIZATION" ;
config_copyright = getenv_opt "DROM_COPYRIGHT" ;
config_opam_repo = getenv_opt "DROM_OPAM_REPO" ;
config_share_dir = getenv_opt "DROM_SHARE_DIR" ;
config_dev_tools = None ;
config_auto_upgrade = getenv_bool_opt "DROM_AUTO_UPGRADE" ;
config_auto_opam_yes = getenv_bool_opt "DROM_AUTO_OPAM_YES" ;
}
in
let path = Sys.getcwd () in
let rec iter path =
let new_path = Filename.dirname path in
let config =
if new_path <> path then
iter new_path
else
update_with config_home config_env
in
let file = path // ".drom.config" in
if Sys.file_exists file then begin
if !Globals.verbosity > 1 then
Printf.eprintf "Loading local user config from %s\n%!" file;
let config_local = config_of_toml file in
update_with config config_local
end
else
config
in
iter path
let config = lazy (load ())
let find_share_dir ?(for_copy=false) () =
let share_dirs =
(
if for_copy then [] else
match Sys.getenv "DROM_SHARE_DIR" with
| share_dir -> [ Some "env var DROM_SHARE_DIR", share_dir ]
| exception Not_found -> []
)
@
(
match
Globals.find_ancestor_file "share"
(fun ~dir ~path:_ -> dir)
with
| None -> []
| Some dir -> [ Some "local ./share/drom", dir // "share" // "drom" ]
)
@
(
if for_copy then [] else
[ None, Globals.opam_root () // "plugins" // "opam-drom" ]
)
@
(
match Globals.opam_switch_prefix with
| Some opam_switch_prefix ->
let share_dir = opam_switch_prefix // "share" // Globals.command in
[ Some "OPAM_SWITCH_PREFIX", share_dir ]
| None -> []
)
@
(
if for_copy then [] else
let config = Lazy.force config in
match config.config_share_dir with
| None -> []
| Some share_dir -> [ Some "user config share_dir", share_dir ]
)
in
let rec iter msgs = function
[] ->
if !Globals.verbosity > 0 then begin
Printf.eprintf
"Warning: drom is not correctly configured, no share_dir found\n%!";
List.iter (fun (msg, dir) ->
Printf.eprintf
" * %s points to directory with missing %S\n%!"
msg dir;
) msgs;
end;
None
| (msg, share_dir) :: dirs ->
let skeletons_dir = share_dir // "skeletons" in
if not ( Sys.file_exists skeletons_dir ) then begin
let msgs =
match msg with
| None -> msgs
| Some msg -> (msg, skeletons_dir) :: msgs
in
iter msgs dirs
end else
Some share_dir
in
iter [] share_dirs
let share_dir = lazy ( find_share_dir () )
let share_dir () = Lazy.force share_dir
let config () = Lazy.force config