Forbid #require in dune files in OCaml syntax (#938)

And add run_and_read_lines to replace old use cases of Unix.open_process_in

Signed-off-by: Jeremie Dimino <jeremie@dimino.org>
This commit is contained in:
Jérémie Dimino 2018-07-02 08:17:53 +01:00 committed by GitHub
parent 87039cd616
commit 438fef915f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 13 deletions

View File

@ -102,6 +102,8 @@ next
when not defined by the user and make `@@default` be the default
target (#926, @diml)
- Forbid `#require` in `dune` files in OCaml syntax (#938, @diml)
- Add `%{profile}` variable. (#938, @rgrinberg)
1.0+beta20 (10/04/2018)

View File

@ -14,4 +14,7 @@ module V1 : sig
(** [send s] send [s] to jbuilder. [s] should be the contents of a
jbuild file following the specification described in the manual. *)
val send : string -> unit
(** Execute a command and read it's output *)
val run_and_read_lines : string -> string list
end

View File

@ -43,7 +43,7 @@ module Jbuilds = struct
type requires = No_requires | Unix
let extract_requires path str =
let extract_requires path str ~kind =
let rec loop n lines acc =
match lines with
| [] -> acc
@ -52,20 +52,31 @@ module Jbuilds = struct
match Scanf.sscanf line "#require %S" (fun x -> x) with
| exception _ -> acc
| s ->
match String.split s ~on:',' with
| [] -> acc
| ["unix"] -> Unix
| _ ->
let start =
{ Lexing.
pos_fname = Path.to_string path
let loc : Loc.t =
let start : Lexing.position =
{ pos_fname = Path.to_string path
; pos_lnum = n
; pos_cnum = 0
; pos_bol = 0
}
in
Loc.fail
{ start; stop = { start with pos_cnum = String.length line } }
{ start; stop = { start with pos_cnum = String.length line } }
in
(match (kind : File_tree.Dune_file.Kind.t) with
| Jbuild -> ()
| Dune ->
Loc.fail loc
"#require is no longer supported in dune files.\n\
You can use the following function instead of \
Unix.open_process_in:\n\
\n\
\ (** Execute a command and read it's output *)\n\
\ val run_and_read_lines : string -> string list");
match String.split s ~on:',' with
| [] -> acc
| ["unix"] -> Unix
| _ ->
Loc.fail loc
"Using libraries other that \"unix\" is not supported.\n\
See the manual for details.";
in
@ -73,7 +84,8 @@ module Jbuilds = struct
in
loop 1 (String.split str ~on:'\n') No_requires
let create_plugin_wrapper (context : Context.t) ~exec_dir ~plugin ~wrapper ~target =
let create_plugin_wrapper (context : Context.t) ~exec_dir ~plugin ~wrapper
~target ~kind =
let plugin_contents = Io.read_file plugin in
Io.with_file_out wrapper ~f:(fun oc ->
let ocamlc_config =
@ -106,6 +118,29 @@ module Jbuild_plugin = struct
let oc = open_out_bin %S in
output_string oc s;
close_out oc
let run_and_read_lines cmd =
let tmp_fname = Filename.temp_file "dune" ".output" in
at_exit (fun () -> Sys.remove tmp_fname);
let n =
Printf.ksprintf Sys.command "%%s > %%s" cmd (Filename.quote tmp_fname)
in
let rec loop ic acc =
match input_line ic with
| exception End_of_file -> close_in ic; List.rev acc
| line -> loop ic (line :: acc)
in
let output = loop (open_in tmp_fname) [] in
if n = 0 then
output
else begin
Printf.ksprintf failwith
"Command failed: %%s\n\
Exit code: %%d\n\
Output:\n\
%%s"
cmd n (String.concat "\n" output)
end
end
end
# 1 %S
@ -115,7 +150,7 @@ end
ocamlc_config
(Path.reach ~from:exec_dir target)
(Path.to_string plugin) plugin_contents);
extract_requires plugin plugin_contents
extract_requires plugin plugin_contents ~kind
let eval { jbuilds; ignore_promoted_rules } ~(context : Context.t) =
let open Fiber.O in
@ -132,7 +167,7 @@ end
ensure_parent_dir_exists generated_jbuild;
let requires =
create_plugin_wrapper context ~exec_dir:dir ~plugin:file ~wrapper
~target:generated_jbuild
~target:generated_jbuild ~kind
in
let context = Option.value context.for_host ~default:context in
let cmas =