Skip to content

Commit 9586620

Browse files
authored
Merge pull request #433 from polytypic/enable-by-os_type
Add `os_type` label to enable/disable based on `Sys.os_type`
2 parents edfb3d6 + b160aca commit 9586620

File tree

8 files changed

+77
-1
lines changed

8 files changed

+77
-1
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
#### Added
44

5+
- Add `os_type` label to enable/disable based on `Sys.os_type` (#433,
6+
@polytypic)
7+
58
- Make MDX compatible with OCaml 5.1 (#435, @polytypic and @kit-ty-kate)
69

710
#### Changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,33 @@ The version number can be of the following forms:
390390
- `X.Y`
391391
- `X.Y.Z`
392392

393+
#### Matching based on the `os_type` (since mdx 2.4.0)
394+
395+
Block can be processed or ignored depending on the current
396+
[`os_type`](https://v2.ocaml.org/api/Sys.html#VALos_type).
397+
398+
For example, different blocks could be enabled depending on whether we are on
399+
Windows or not:
400+
401+
```ocaml
402+
#require "unix"
403+
```
404+
405+
<!-- $MDX os_type<>Win32 -->
406+
```ocaml
407+
# Unix.nice 0
408+
- : int = 0
409+
```
410+
411+
<!-- $MDX os_type=Win32 -->
412+
```ocaml
413+
# Unix.nice 0
414+
Exception: Invalid_argument "Unix.nice not implemented".
415+
```
416+
417+
The `os_type` values should be written in ASCII and are compared case
418+
insensitively.
419+
393420
#### Environment variables declaration
394421

395422
Environment variables can be declared at the beginning of a block:

lib/block.ml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ type t = {
111111
contents : string list;
112112
skip : bool;
113113
version_enabled : bool;
114+
os_type_enabled : bool;
114115
set_variables : (string * string) list;
115116
unset_variables : string list;
116117
value : value;
@@ -272,6 +273,16 @@ let version_enabled version =
272273
Label.Relation.compare op (Ocaml_version.compare curr_version v) 0
273274
| None -> true
274275

276+
let os_type_enabled os_type =
277+
match os_type with
278+
| Some (op, v) ->
279+
Label.Relation.compare op
280+
(String.compare
281+
(String.lowercase_ascii Sys.os_type)
282+
(String.lowercase_ascii v))
283+
0
284+
| None -> true
285+
275286
let get_label f (labels : Label.t list) = Util.List.find_map f labels
276287

277288
let label_not_allowed ~loc ~label ~kind =
@@ -296,6 +307,7 @@ type block_config = {
296307
dir : string option;
297308
skip : bool;
298309
version : (Label.Relation.t * Ocaml_version.t) option;
310+
os_type : (Label.Relation.t * string) option;
299311
set_variables : (string * string) list;
300312
unset_variables : string list;
301313
file_inc : string option;
@@ -315,6 +327,7 @@ let get_block_config l =
315327
dir = get_label (function Dir x -> Some x | _ -> None) l;
316328
skip = List.exists (function Label.Skip -> true | _ -> false) l;
317329
version = get_label (function Version (x, y) -> Some (x, y) | _ -> None) l;
330+
os_type = get_label (function Os_type (x, y) -> Some (x, y) | _ -> None) l;
318331
set_variables =
319332
List.filter_map (function Label.Set (v, x) -> Some (v, x) | _ -> None) l;
320333
unset_variables =
@@ -416,6 +429,7 @@ let mk ~loc ~section ~labels ~legacy_labels ~header ~contents ~errors =
416429
| None -> infer_block ~loc ~config ~header ~contents ~errors
417430
in
418431
let+ version_enabled = version_enabled config.version in
432+
let os_type_enabled = os_type_enabled config.os_type in
419433
{
420434
loc;
421435
section;
@@ -425,6 +439,7 @@ let mk ~loc ~section ~labels ~legacy_labels ~header ~contents ~errors =
425439
contents;
426440
skip = config.skip;
427441
version_enabled;
442+
os_type_enabled;
428443
set_variables = config.set_variables;
429444
unset_variables = config.unset_variables;
430445
value;
@@ -471,4 +486,4 @@ let is_active ?section:s t =
471486
| None -> Re.execp (Re.Perl.compile_pat p) "")
472487
| None -> true
473488
in
474-
active && t.version_enabled && not t.skip
489+
active && t.version_enabled && t.os_type_enabled && not t.skip

lib/block.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ type t = {
101101
skip : bool;
102102
version_enabled : bool;
103103
(** Whether the current OCaml version complies with the block's version. *)
104+
os_type_enabled : bool;
105+
(** Whether the current os type complies with the block's version. *)
104106
set_variables : (string * string) list;
105107
unset_variables : string list;
106108
value : value;

lib/label.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type t =
8989
| Skip
9090
| Non_det of non_det option
9191
| Version of Relation.t * Ocaml_version.t
92+
| Os_type of Relation.t * string
9293
| Set of string * string
9394
| Unset of string
9495
| Block_kind of block_kind
@@ -115,6 +116,7 @@ let pp ppf = function
115116
| Non_det (Some Nd_command) -> Fmt.string ppf "non-deterministic=command"
116117
| Version (op, v) ->
117118
Fmt.pf ppf "version%a%a" Relation.pp op Ocaml_version.pp v
119+
| Os_type (op, v) -> Fmt.pf ppf "os_type%a%s" Relation.pp op v
118120
| Set (v, x) -> Fmt.pf ppf "set-%s=%s" v x
119121
| Unset x -> Fmt.pf ppf "unset-%s" x
120122
| Block_kind bk -> pp_block_kind ppf bk
@@ -170,6 +172,7 @@ let interpret label value =
170172
| Ok v -> Ok (Version (op, v))
171173
| Error (`Msg e) ->
172174
Util.Result.errorf "Invalid `version` label value: %s." e)
175+
| "os_type" -> requires_value ~label ~value (fun op v -> Ok (Os_type (op, v)))
173176
| "non-deterministic" -> (
174177
match value with
175178
| None -> Ok (Non_det None)

lib/label.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type t =
4242
| Skip
4343
| Non_det of non_det option
4444
| Version of Relation.t * Ocaml_version.t
45+
| Os_type of Relation.t * string
4546
| Set of string * string
4647
| Unset of string
4748
| Block_kind of block_kind

test/bin/mdx-test/expect/dune.inc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,18 @@
371371
(alias runtest)
372372
(action (diff ocaml-errors-ellipsis/test-case.md ocaml-errors-ellipsis.actual)))
373373

374+
(rule
375+
(target os_type.actual)
376+
(deps (package mdx) (source_tree os_type))
377+
(action
378+
(with-stdout-to %{target}
379+
(chdir os_type
380+
(run ocaml-mdx test --output - test-case.md)))))
381+
382+
(rule
383+
(alias runtest)
384+
(action (diff os_type/test-case.md os_type.actual)))
385+
374386
(rule
375387
(target padding.actual)
376388
(deps (package mdx) (source_tree padding))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Mdx can skip blocks based on `os_type`:
2+
3+
```ocaml os_type<>Win32
4+
# #require "unix"
5+
# Unix.nice 0
6+
- : int = 0
7+
```
8+
9+
```ocaml os_type=Win32
10+
# #require "unix"
11+
# Unix.nice 0
12+
Exception: Invalid_argument "Unix.nice not implemented".
13+
```

0 commit comments

Comments
 (0)