Skip to content

Commit

Permalink
Add an 'exec' label to execute include OCaml blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
gpetiot committed Mar 4, 2024
1 parent bf33f76 commit bfc85ed
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 35 deletions.
15 changes: 6 additions & 9 deletions lib/block.ml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type include_ocaml_file = {
part_included : string option;
ocaml_value : ocaml_value option;
kind : OCaml_kind.t;
exec : bool;
}

type include_other_file = { header : Header.t option }
Expand Down Expand Up @@ -369,6 +370,7 @@ type block_config = {
env : string option;
dir : string option;
skip : bool;
exec : bool;
version : (Label.Relation.t * Ocaml_version.t) option;
os_type : (Label.Relation.t * string) option;
set_variables : (string * string) list;
Expand All @@ -389,6 +391,7 @@ let get_block_config l =
env = get_label (function Env x -> Some x | _ -> None) l;
dir = get_label (function Dir x -> Some x | _ -> None) l;
skip = List.exists (function Label.Skip -> true | _ -> false) l;
exec = List.exists (function Label.Exec -> true | _ -> false) l;
version = get_label (function Version (x, y) -> Some (x, y) | _ -> None) l;
os_type = get_label (function Os_type (x, y) -> Some (x, y) | _ -> None) l;
set_variables =
Expand Down Expand Up @@ -445,7 +448,7 @@ let mk_toplevel ~loc ~config ~contents ~errors =
let mk_include ~loc ~config ~header ~errors =
let kind = "include" in
match config with
| { file_inc = Some file_included; part; non_det; env; _ } -> (
| { file_inc = Some file_included; part; non_det; env; exec; _ } -> (
let kind =
match header with
| Some Header.OCaml -> `OCaml
Expand All @@ -467,7 +470,7 @@ let mk_include ~loc ~config ~header ~errors =
| Impl -> Some (mk_ocaml_value env non_det errors header)
| Intf -> None
in
let file_kind = Fk_ocaml { part_included; ocaml_value; kind } in
let file_kind = Fk_ocaml { part_included; ocaml_value; kind; exec } in
Ok (Include { file_included; file_kind })
| `Other -> (
match part with
Expand Down Expand Up @@ -569,10 +572,4 @@ let is_active ?section:s t =
| None -> Re.execp (Re.Perl.compile_pat p) "")
| None -> true
in
let can_update_content =
match t.value with
(* include blocks are always updated even if not executed *)
| Include _ -> true
| _ -> not t.skip
in
active_section && t.version_enabled && t.os_type_enabled && can_update_content
active_section && t.version_enabled && t.os_type_enabled && not t.skip
1 change: 1 addition & 0 deletions lib/block.mli
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type include_ocaml_file = {
If lines is not specified synchronize the whole file. *)
ocaml_value : ocaml_value option;
kind : OCaml_kind.t;
exec : bool;
}

type include_other_file = { header : Header.t option }
Expand Down
3 changes: 3 additions & 0 deletions lib/label.ml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ type t =
| Part of string
| Env of string
| Skip
| Exec
| Non_det of non_det option
| Version of Relation.t * Ocaml_version.t
| Os_type of Relation.t * string
Expand All @@ -111,6 +112,7 @@ let pp ppf = function
| Part p -> Fmt.pf ppf "part=%s" p
| Env e -> Fmt.pf ppf "env=%s" e
| Skip -> Fmt.string ppf "skip"
| Exec -> Fmt.string ppf "exec"
| Non_det None -> Fmt.string ppf "non-deterministic"
| Non_det (Some Nd_output) -> Fmt.string ppf "non-deterministic=output"
| Non_det (Some Nd_command) -> Fmt.string ppf "non-deterministic=command"
Expand Down Expand Up @@ -159,6 +161,7 @@ let requires_eq_value ~label ~value f =
let interpret label value =
match label with
| "skip" -> doesnt_accept_value ~label ~value Skip
| "exec" -> doesnt_accept_value ~label ~value Exec
| "ocaml" -> doesnt_accept_value ~label ~value (Block_kind OCaml)
| "cram" -> doesnt_accept_value ~label ~value (Block_kind Cram)
| "toplevel" -> doesnt_accept_value ~label ~value (Block_kind Toplevel)
Expand Down
1 change: 1 addition & 0 deletions lib/label.mli
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type t =
| Part of string
| Env of string
| Skip
| Exec (** Only for include blocks. *)
| Non_det of non_det option
| Version of Relation.t * Ocaml_version.t
| Os_type of Relation.t * string
Expand Down
7 changes: 3 additions & 4 deletions lib/test/mdx_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -360,17 +360,16 @@ let run_exn ~non_deterministic ~silent_eval ~record_backtrace ~syntax ~silent
| Include
{
file_included;
file_kind = Fk_ocaml { part_included; ocaml_value; _ };
file_kind = Fk_ocaml { part_included; ocaml_value; exec; _ };
} ->
assert (syntax <> Some Cram);
let new_block =
update_file_or_block ?root file file_included t part_included
in
let updated_block =
match ocaml_value with
(* including without executing *)
| Some _ when t.skip -> new_block
| Some ocaml_value -> run_ocaml_value new_block ocaml_value
| Some ocaml_value when exec ->
run_ocaml_value new_block ocaml_value
| _ -> new_block
in
Block.pp ?syntax ppf updated_block
Expand Down
3 changes: 2 additions & 1 deletion test/bin/mdx-test/expect/code/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ module type Foo = sig type t end

```ocaml skip
# Pipe.f ();;
- : unit
Line 1, characters 1-7:
Error: Unbound module Pipe
```
26 changes: 23 additions & 3 deletions test/bin/mdx-test/expect/exec-include/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ val f : int -> int
val f : int -> int
```

.ml files are included and executed:
`exec` has no effect:
<!-- $MDX file=code.mli,exec -->
```ocaml
val f : int -> int
```

.ml files are included but not executed by default:
<!-- $MDX file=code.ml,part=OK -->
```ocaml
let f x = x + 1
Expand All @@ -25,8 +31,7 @@ Line 1, characters 9-10:
Error: Unbound value x
```


.ml files are still included but no longer executed when `skip` is used:
.ml files are no longer included when `skip` is used:
<!-- $MDX file=code.ml,part=OK,skip -->
```ocaml
let f x = x + 1
Expand All @@ -36,3 +41,18 @@ let f x = x + 1
```ocaml
let k = x = 1
```

.ml files are executed when `exec` is used:
<!-- $MDX file=code.ml,part=OK,exec -->
```ocaml
let f x = x + 1
```

<!-- $MDX file=code.ml,part=KO,exec -->
```ocaml
let k = x = 1
```
```mdx-error
Line 1, characters 9-10:
Error: Unbound value x
```
10 changes: 5 additions & 5 deletions test/bin/mdx-test/expect/parts-begin-end/test-case.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Mdx can also understand ocaml code blocks:


```ocaml file=parts-begin-end.ml,part=toto,skip
```ocaml file=parts-begin-end.ml,part=toto
# let x = 3;;
val x : int = 3
# let y = 4;;
Expand All @@ -14,13 +14,13 @@ val y : int = 4
- : unit = ()
```

```ocaml file=parts-begin-end.ml,part=z_zz,skip
```ocaml file=parts-begin-end.ml,part=z_zz
```

```ocaml file=parts-begin-end.ml,part=4-2,skip
```ocaml file=parts-begin-end.ml,part=4-2
```

```ocaml file=parts-begin-end.ml,skip
```ocaml file=parts-begin-end.ml
```

```ocaml
Expand All @@ -31,5 +31,5 @@ val x : int = 2
- : unit = ()
```

```ocaml file=parts-begin-end.ml,part=indented,skip
```ocaml file=parts-begin-end.ml,part=indented
```
10 changes: 5 additions & 5 deletions test/bin/mdx-test/expect/parts-begin-end/test-case.md.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Mdx can also understand ocaml code blocks:


```ocaml file=parts-begin-end.ml,part=toto,skip
```ocaml file=parts-begin-end.ml,part=toto
let x = 34
let f = 42.3
let s = "toto"
Expand All @@ -13,18 +13,18 @@ let () =
;;
```

```ocaml file=parts-begin-end.ml,part=z_zz,skip
```ocaml file=parts-begin-end.ml,part=z_zz
let () =
print_string s
;;
```

```ocaml file=parts-begin-end.ml,part=4-2,skip
```ocaml file=parts-begin-end.ml,part=4-2
let () =
f x print_int;
```

```ocaml file=parts-begin-end.ml,skip
```ocaml file=parts-begin-end.ml
let () =
();
()
Expand Down Expand Up @@ -63,7 +63,7 @@ val x : int = 2
- : unit = ()
```

```ocaml file=parts-begin-end.ml,part=indented,skip
```ocaml file=parts-begin-end.ml,part=indented
let () = fooooooooooooooooooooooooooooooooooooooooooo in
if not fooooooooo then foooooooooooo
```
8 changes: 4 additions & 4 deletions test/bin/mdx-test/expect/sync-to-md/test-case.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Mdx can also understand ocaml code blocks:


```ocaml file=sync_to_md.ml,part=toto,skip
```ocaml file=sync_to_md.ml,part=toto
# let x = 3;;
val x : int = 3
# let y = 4;;
Expand All @@ -14,16 +14,16 @@ val y : int = 4
- : unit = ()
```

```ocaml file=sync_to_md.ml,part=zzz,skip
```ocaml file=sync_to_md.ml,part=zzz
```

```ocaml file=sync_to_md.ml,part=42,skip
```ocaml file=sync_to_md.ml,part=42
```

```ocaml file=sync_to_md.ml,part=
```

```ocaml file=sync_to_md.ml,skip
```ocaml file=sync_to_md.ml
```

```ocaml
Expand Down
8 changes: 4 additions & 4 deletions test/bin/mdx-test/expect/sync-to-md/test-case.md.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Mdx can also understand ocaml code blocks:


```ocaml file=sync_to_md.ml,part=toto,skip
```ocaml file=sync_to_md.ml,part=toto
let x = 34
let f = 42.3
let s = "toto"
Expand All @@ -13,13 +13,13 @@ let () =
;;
```

```ocaml file=sync_to_md.ml,part=zzz,skip
```ocaml file=sync_to_md.ml,part=zzz
let () =
print_string s
;;
```

```ocaml file=sync_to_md.ml,part=42,skip
```ocaml file=sync_to_md.ml,part=42
let () =
f x print_int
```
Expand All @@ -31,7 +31,7 @@ let () =
;;
```

```ocaml file=sync_to_md.ml,skip
```ocaml file=sync_to_md.ml
let () =
();
()
Expand Down

0 comments on commit bfc85ed

Please sign in to comment.