Make extensions portable in cram output

With some really ugly post processing
This commit is contained in:
Rudi Grinberg 2018-04-18 20:17:49 +07:00
parent f8f1a4036e
commit ab50461741
8 changed files with 89 additions and 51 deletions

View File

@ -12,13 +12,49 @@ type item =
let eol = '\n' | eof
let ext = '.' ['a'-'z' 'A'-'Z' '0'-'9']+
rule file = parse
| eof { [] }
| " $ " ([^'\n']* as str) eol { Command str :: file lexbuf }
| " " ([^'\n']* as str) eol { Output str :: file lexbuf }
| ([^'\n']* as str) eol { Comment str :: file lexbuf }
and postprocess tbl b = parse
| eof { Buffer.contents b }
| ([^ '/'] as c) (ext as e)
{ Buffer.add_char b c;
begin match List.assoc e tbl with
| res -> Buffer.add_string b res
| exception Not_found -> Buffer.add_string b e
end;
postprocess tbl b lexbuf
}
| _ as c { Buffer.add_char b c; postprocess tbl b lexbuf }
{
module Configurator = Configurator.V1
let make_ext_replace config =
let tbl =
let var = Configurator.ocaml_config_var_exn config in
let exts =
[ var "ext_dll", "$ext_dll"
; var "ext_asm", "$ext_asm"
; var "ext_lib", "$ext_lib"
; var "ext_obj", "$ext_obj"
] in
(* need to special case exe since we can only remove this extension in
general *)
match var "ext_exe" with
| "" -> exts
| ext -> (ext, "") :: exts
in
List.iter tbl ~f:(fun (e, _) -> assert (e <> ""));
fun s ->
let l = Lexing.from_string s in
postprocess tbl (Buffer.create (String.length s)) l
type version = int * int * int
let parse_version s =
@ -58,51 +94,53 @@ rule file = parse
let ocaml_version = ref None in
let skip_versions = ref [] in
let expect_test = ref None in
let usage = sprintf "%s [OPTIONS]" (Filename.basename Sys.executable_name) in
let anon s =
match !expect_test with
| None -> expect_test := Some s
| Some _ -> raise (Arg.Bad "test must only be given once") in
Arg.parse
let args =
[ "-ocamlv"
, Arg.String (fun s -> ocaml_version := Some (parse_version s))
, "Version of ocaml being used"
; "-skip-versions"
, Arg.String (fun s -> skip_versions := parse_skip_versions s)
, "Comma separated versions of ocaml where to skip test"
] anon usage;
let expect_test =
match !expect_test with
| None -> raise (Arg.Bad "expect test file must be passed")
| Some p -> p in
begin match !ocaml_version, !skip_versions with
| None, [] -> ()
| None, _::_ -> raise (Arg.Bad "provide -ocaml along with -skip-versions")
| Some v, skip ->
if List.exists skip ~f:(fun (op, v') -> test op v v') then exit 0
end;
Test_common.run_expect_test expect_test ~f:(fun file_contents lexbuf ->
let items = file lexbuf in
let temp_file = Filename.temp_file "jbuilder-test" ".output" in
at_exit (fun () -> Sys.remove temp_file);
let buf = Buffer.create (String.length file_contents + 1024) in
List.iter items ~f:(function
| Output _ -> ()
| Comment s -> Buffer.add_string buf s; Buffer.add_char buf '\n'
| Command s ->
Printf.bprintf buf " $ %s\n" s;
let fd = Unix.openfile temp_file [O_WRONLY; O_TRUNC] 0 in
let pid =
Unix.create_process "sh" [|"sh"; "-c"; s|] Unix.stdin fd fd
in
Unix.close fd;
let n =
match snd (Unix.waitpid [] pid) with
| WEXITED n -> n
| _ -> 255
in
List.iter (Io.lines_of_file temp_file) ~f:(fun line ->
Printf.bprintf buf " %s\n" (Ansi_color.strip line));
if n <> 0 then Printf.bprintf buf " [%d]\n" n);
Buffer.contents buf)
; "-test"
, Arg.String (fun s -> expect_test := Some s)
, "expect test file"
] in
Configurator.main ~args ~name:"cram" (fun configurator ->
let expect_test =
match !expect_test with
| None -> raise (Arg.Bad "expect test file must be passed")
| Some p -> p in
begin match !ocaml_version, !skip_versions with
| None, [] -> ()
| None, _::_ -> raise (Arg.Bad "provide -ocaml along with -skip-versions")
| Some v, skip ->
if List.exists skip ~f:(fun (op, v') -> test op v v') then exit 0
end;
Test_common.run_expect_test expect_test ~f:(fun file_contents lexbuf ->
let items = file lexbuf in
let temp_file = Filename.temp_file "jbuilder-test" ".output" in
at_exit (fun () -> Sys.remove temp_file);
let buf = Buffer.create (String.length file_contents + 1024) in
List.iter items ~f:(function
| Output _ -> ()
| Comment s -> Buffer.add_string buf s; Buffer.add_char buf '\n'
| Command s ->
Printf.bprintf buf " $ %s\n" s;
let fd = Unix.openfile temp_file [O_WRONLY; O_TRUNC] 0 in
let pid =
Unix.create_process "sh" [|"sh"; "-c"; s|] Unix.stdin fd fd
in
Unix.close fd;
let n =
match snd (Unix.waitpid [] pid) with
| WEXITED n -> n
| _ -> 255
in
let ext_replace = make_ext_replace configurator in
List.iter (Io.lines_of_file temp_file) ~f:(fun line ->
Printf.bprintf buf " %s\n"
(ext_replace (Ansi_color.strip line)));
if n <> 0 then Printf.bprintf buf " [%d]\n" n);
Buffer.contents buf)
)
}

View File

@ -2,7 +2,7 @@
(executable
((name cram)
(libraries (test_common jbuilder))))
(libraries (test_common jbuilder configurator))))
(ocamllex (cram))

View File

@ -1,7 +1,7 @@
$ jbuilder exec ./qnativerun/run.exe --display short
ocamldep qnativerun/run.ml.d
ocamlc q/q_stub.o
ocamlmklib q/dllq_stubs.so,q/libq_stubs.a
ocamlc q/q_stub$ext_obj
ocamlmklib q/dllq_stubs$ext_dll,q/libq_stubs$ext_lib
ocamldep q/q.ml.d
ocamldep q/q.mli.d
ocamlc q/.q.objs/q.{cmi,cmti}

View File

@ -6,8 +6,8 @@
ocamlc .foo.objs/dummy.{cmi,cmo,cmt}
ocamlopt .foo.objs/dummy.{cmx,o}
ocamlopt foo.{a,cmxa}
ocamlc bar.o
ocamlmklib dllfoo_stubs.so,libfoo_stubs.a
ocamlc bar$ext_obj
ocamlmklib dllfoo_stubs$ext_dll,libfoo_stubs$ext_lib
ocamlc .test.eobjs/lexer1.{cmi,cmo,cmt}
ocamlopt .test.eobjs/lexer1.{cmx,o}
ocamlc .test.eobjs/test.{cmi,cmo,cmt}

View File

@ -33,7 +33,7 @@
"_build/install/default.foo/lib/p/p.ml" {"../../foo-sysroot/lib/p/p.ml"}
"_build/install/default.foo/lib/p/p.cma" {"../../foo-sysroot/lib/p/p.cma"}
"_build/install/default.foo/lib/p/p.cmxa" {"../../foo-sysroot/lib/p/p.cmxa"}
"_build/install/default.foo/lib/p/p.a" {"../../foo-sysroot/lib/p/p.a"}
"_build/install/default.foo/lib/p/p$ext_lib" {"../../foo-sysroot/lib/p/p$ext_lib"}
"_build/install/default.foo/lib/p/p.cmxs" {"../../foo-sysroot/lib/p/p.cmxs"}
"_build/install/default.foo/lib/p/p.dune" {"../../foo-sysroot/lib/p/p.dune"}
]

View File

@ -25,7 +25,7 @@
"_build/install/default/lib/foo/foo.ml" {"foo.ml"}
"_build/install/default/lib/foo/foo.cma" {"foo.cma"}
"_build/install/default/lib/foo/foo.cmxa" {"foo.cmxa"}
"_build/install/default/lib/foo/foo.a" {"foo.a"}
"_build/install/default/lib/foo/foo$ext_lib" {"foo$ext_lib"}
"_build/install/default/lib/foo/foo.cmxs" {"foo.cmxs"}
"_build/install/default/lib/foo/foo.js" {"foo.js"}
"_build/install/default/lib/foo/cfoo.h" {"cfoo.h"}

View File

@ -1,6 +1,6 @@
$ jbuilder build --display short --dev bin/technologic.bc.js @install lib/x.cma.js lib/x__Y.cmo.js bin/z.cmo.js
ocamlc lib/stubs.o
ocamlmklib lib/dllx_stubs.so,lib/libx_stubs.a
ocamlc lib/stubs$ext_obj
ocamlmklib lib/dllx_stubs$ext_dll,lib/libx_stubs$ext_lib
ocamlopt .ppx/js_of_ocaml-ppx/ppx.exe
ppx lib/x.pp.ml
ocamldep lib/x.pp.ml.d

View File

@ -8,7 +8,7 @@
each module cannot appear in more than one "modules" field - it must belong
to a single library or executable.
This warning will become an error in the future.
Multiple rules generated for _build/default/lib.o:
Multiple rules generated for _build/default/lib$ext_obj:
- <internal location>
- <internal location>
[1]