forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathounit_cmd_util.ml
112 lines (97 loc) · 2.95 KB
/
ounit_cmd_util.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
let (//) = Filename.concat
(** may nonterminate when [cwd] is '.' *)
let rec unsafe_root_dir_aux cwd =
if Sys.file_exists (cwd//Literals.bsconfig_json) then cwd
else unsafe_root_dir_aux (Filename.dirname cwd)
let project_root = unsafe_root_dir_aux (Sys.getcwd ())
let jscomp = project_root // "jscomp"
let bsc_exe = project_root // "bsc"
let runtime_dir = jscomp // "runtime"
let others_dir = jscomp // "others"
let stdlib_dir = jscomp // "stdlib-406"
(* let rec safe_dup fd =
let new_fd = Unix.dup fd in
if (Obj.magic new_fd : int) >= 3 then
new_fd (* [dup] can not be 0, 1, 2*)
else begin
let res = safe_dup fd in
Unix.close new_fd;
res
end *)
let safe_close fd =
try Unix.close fd with Unix.Unix_error(_,_,_) -> ()
type output = {
stderr : string ;
stdout : string ;
exit_code : int
}
let perform command args =
let new_fd_in, new_fd_out = Unix.pipe () in
let err_fd_in, err_fd_out = Unix.pipe () in
match Unix.fork () with
| 0 ->
begin try
safe_close new_fd_in;
safe_close err_fd_in;
Unix.dup2 err_fd_out Unix.stderr ;
Unix.dup2 new_fd_out Unix.stdout;
Unix.execv command args
with _ ->
exit 127
end
| pid ->
(* when all the descriptors on a pipe's input are closed and the pipe is
empty, a call to [read] on its output returns zero: end of file.
when all the descriptiors on a pipe's output are closed, a call to
[write] on its input kills the writing process (EPIPE).
*)
safe_close new_fd_out ;
safe_close err_fd_out ;
let in_chan = Unix.in_channel_of_descr new_fd_in in
let err_in_chan = Unix.in_channel_of_descr err_fd_in in
let buf = Buffer.create 1024 in
let err_buf = Buffer.create 1024 in
(try
while true do
Buffer.add_string buf (input_line in_chan );
Buffer.add_char buf '\n'
done;
with
End_of_file -> ()) ;
(try
while true do
Buffer.add_string err_buf (input_line err_in_chan );
Buffer.add_char err_buf '\n'
done;
with
End_of_file -> ()) ;
let exit_code = match snd @@ Unix.waitpid [] pid with
| Unix.WEXITED exit_code -> exit_code
| Unix.WSIGNALED _signal_number
| Unix.WSTOPPED _signal_number -> 127 in
{
stdout = Buffer.contents buf ;
stderr = Buffer.contents err_buf;
exit_code
}
let perform_bsc args =
perform bsc_exe
(Array.append
[|bsc_exe ;
"-bs-package-name" ; "bs-platform";
"-bs-no-version-header";
"-bs-cross-module-opt";
"-w";
"-40";
"-I" ;
runtime_dir ;
"-I";
others_dir ;
"-I" ;
stdlib_dir
|] args)
let bsc_check_eval str =
perform_bsc [|"-bs-eval"; str|]
let debug_output o =
Printf.printf "\nexit_code:%d\nstdout:%s\nstderr:%s\n"
o.exit_code o.stdout o.stderr