Restrict what one can do with the OCaml syntax

Until we decide in what direction it should go.
This commit is contained in:
Jeremie Dimino 2017-06-06 10:23:22 +01:00
parent 1255bd22fc
commit e51002d1b7
4 changed files with 40 additions and 54 deletions

View File

@ -18,6 +18,11 @@
- Deprecate `copy-and-add-line-directive` and rename it `copy#`
- Remove the ability to load arbitrary libraries in jbuild file in
OCaml syntax. Only `unix` is supported since a few released packages
are using it. The OCaml syntax might eventually be replaced by a
simpler mechanism that plays better with incremental builds
- Properly define and implement scopes
- Inside user actions, `${^}` now includes files matches by

View File

@ -168,23 +168,3 @@ the user can define preferences such as colors.
It doesn't follow the specification given in the readme of
[parsexp](https://github.com/janestreet/parsexp). This need to be
fixed.
## Make Jbuild_plugin a library
Currently Jbuilder generates a wrapper script containing the source
code of the `Jbuild_plugin` followed by the user script. While this
method is trivial to implement, it is not great if users want to write
libraries for jbuild plugins.
What we should do instead is create a proper `jbuild_plugin` library
that is installed. This library should read a file containing the
build context details generated by Jbuilder and passed as
`Sys.argv.(1)`.
We need to refactor things a bit to make this happen, in particular
the library will propably need to know how to parse s-expression. We
can create a `jbuild_common` library to put the parts that are common
between `jbuild_plugin` and `jbuilder`.
Note that `doc/jbuild` is an OCaml script. To simplify the bootstrap,
we should just convert it back to a static `jbuild` file.

View File

@ -979,28 +979,8 @@ in the rest of this section. The code in the script will have access to a
<https://github.com/janestreet/jbuilder/blob/master/plugin/jbuild_plugin.mli>`__
module containing details about the build context it is executed in.
The script can use the directive ``#require`` to access libraries:
.. code:: ocaml
#require "base,re";;
Note that any library required by a ``jbuild`` file must be part of the
installed world.
If you don't like the S-expression syntax, then this method gives you a way to
use whatever else you want. For instance you could have an API to describe your
project in OCaml directly:
.. code:: ocaml
(* -*- tuareg -*- *)
#require "my_jbuild_api"
open My_jbuild_api
let () =
library "foo" ~modules:["plop"; "bidule"]
Currently the ``Jbuild_plugin`` module is only available inside plugins. It is
however planned to make it a proper library, see `the roadmap
<../ROADMAP.org>`__ for details.
The OCaml syntax gives you an escape hatch for when the S-expression
syntax is not enough. It is not clear whether the OCaml syntax will be
supported in the long term as it doesn't work well with incremental
builds. It is possible that it will be replaced by just an ``include``
stanza where one can include a generated file.

View File

@ -20,14 +20,35 @@ module Jbuilds = struct
| Local path -> Path.Local.ensure_parent_directory_exists path
| External _ -> ()
let extract_requires str =
List.fold_left (String.split str ~on:'\n') ~init:String_set.empty ~f:(fun acc line ->
match Scanf.sscanf line "#require %S" (fun x -> x) with
| exception _ -> acc
| s ->
String_set.union acc
(String_set.of_list (String.split s ~on:',')))
|> String_set.elements
let extract_requires ~fname str =
let rec loop n lines acc =
match lines with
| [] -> acc
| line :: lines ->
let acc =
match Scanf.sscanf line "#require %S" (fun x -> x) with
| exception _ -> acc
| s ->
match String.split s ~on:',' with
| [] -> acc
| ["unix"] as l -> l
| _ ->
let start =
{ Lexing.
pos_fname = fname
; pos_lnum = n
; pos_cnum = 0
; pos_bol = 0
}
in
Loc.fail
{ start; stop = { start with pos_cnum = String.length line } }
"Using libraries other that \"unix\" is not supported.\n\
See the manual for details.";
in
loop (n + 1) lines acc
in
loop 1 (String.split str ~on:'\n') []
let create_plugin_wrapper (context : Context.t) ~exec_dir ~plugin ~wrapper ~target =
let plugin = Path.to_string plugin in
@ -60,7 +81,7 @@ end
Printf.sprintf "%-*S , %S" (longest + 2) k v)))
(Path.reach ~from:exec_dir target)
plugin plugin_contents);
extract_requires plugin_contents
extract_requires ~fname:plugin plugin_contents
let eval jbuilds ~(context : Context.t) =
let open Future in