From 2d6f4a67cc09350aeb5b152cc9fff20856fae9b7 Mon Sep 17 00:00:00 2001 From: Vesa Karvonen Date: Thu, 27 Jul 2023 14:13:59 +0300 Subject: [PATCH 1/4] Add `os_type` label to enable/disable based on `Sys.os_type` --- lib/block.ml | 17 ++++++++++++++++- lib/block.mli | 2 ++ lib/label.ml | 3 +++ lib/label.mli | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/block.ml b/lib/block.ml index 46ae3ad55..c194236f4 100644 --- a/lib/block.ml +++ b/lib/block.ml @@ -111,6 +111,7 @@ type t = { contents : string list; skip : bool; version_enabled : bool; + os_type_enabled : bool; set_variables : (string * string) list; unset_variables : string list; value : value; @@ -272,6 +273,16 @@ let version_enabled version = Label.Relation.compare op (Ocaml_version.compare curr_version v) 0 | None -> true +let os_type_enabled os_type = + match os_type with + | Some (op, v) -> + Label.Relation.compare op + (String.compare + (String.lowercase_ascii Sys.os_type) + (String.lowercase_ascii v)) + 0 + | None -> true + let get_label f (labels : Label.t list) = Util.List.find_map f labels let label_not_allowed ~loc ~label ~kind = @@ -296,6 +307,7 @@ type block_config = { dir : string option; skip : bool; version : (Label.Relation.t * Ocaml_version.t) option; + os_type : (Label.Relation.t * string) option; set_variables : (string * string) list; unset_variables : string list; file_inc : string option; @@ -315,6 +327,7 @@ let get_block_config l = dir = get_label (function Dir x -> Some x | _ -> None) l; skip = List.exists (function Label.Skip -> 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 = List.filter_map (function Label.Set (v, x) -> Some (v, x) | _ -> None) l; unset_variables = @@ -416,6 +429,7 @@ let mk ~loc ~section ~labels ~legacy_labels ~header ~contents ~errors = | None -> infer_block ~loc ~config ~header ~contents ~errors in let+ version_enabled = version_enabled config.version in + let os_type_enabled = os_type_enabled config.os_type in { loc; section; @@ -425,6 +439,7 @@ let mk ~loc ~section ~labels ~legacy_labels ~header ~contents ~errors = contents; skip = config.skip; version_enabled; + os_type_enabled; set_variables = config.set_variables; unset_variables = config.unset_variables; value; @@ -471,4 +486,4 @@ let is_active ?section:s t = | None -> Re.execp (Re.Perl.compile_pat p) "") | None -> true in - active && t.version_enabled && not t.skip + active && t.version_enabled && t.os_type_enabled && not t.skip diff --git a/lib/block.mli b/lib/block.mli index e4334997e..b2dc62339 100644 --- a/lib/block.mli +++ b/lib/block.mli @@ -101,6 +101,8 @@ type t = { skip : bool; version_enabled : bool; (** Whether the current OCaml version complies with the block's version. *) + os_type_enabled : bool; + (** Whether the current os type complies with the block's version. *) set_variables : (string * string) list; unset_variables : string list; value : value; diff --git a/lib/label.ml b/lib/label.ml index 802cb2456..b18fc6f02 100644 --- a/lib/label.ml +++ b/lib/label.ml @@ -89,6 +89,7 @@ type t = | Skip | Non_det of non_det option | Version of Relation.t * Ocaml_version.t + | Os_type of Relation.t * string | Set of string * string | Unset of string | Block_kind of block_kind @@ -115,6 +116,7 @@ let pp ppf = function | Non_det (Some Nd_command) -> Fmt.string ppf "non-deterministic=command" | Version (op, v) -> Fmt.pf ppf "version%a%a" Relation.pp op Ocaml_version.pp v + | Os_type (op, v) -> Fmt.pf ppf "os_type%a%s" Relation.pp op v | Set (v, x) -> Fmt.pf ppf "set-%s=%s" v x | Unset x -> Fmt.pf ppf "unset-%s" x | Block_kind bk -> pp_block_kind ppf bk @@ -170,6 +172,7 @@ let interpret label value = | Ok v -> Ok (Version (op, v)) | Error (`Msg e) -> Util.Result.errorf "Invalid `version` label value: %s." e) + | "os_type" -> requires_value ~label ~value (fun op v -> Ok (Os_type (op, v))) | "non-deterministic" -> ( match value with | None -> Ok (Non_det None) diff --git a/lib/label.mli b/lib/label.mli index a95d3f924..5abc4205d 100644 --- a/lib/label.mli +++ b/lib/label.mli @@ -42,6 +42,7 @@ type t = | Skip | Non_det of non_det option | Version of Relation.t * Ocaml_version.t + | Os_type of Relation.t * string | Set of string * string | Unset of string | Block_kind of block_kind From e075e57247297b988070166b0a8b93e72032d24c Mon Sep 17 00:00:00 2001 From: Vesa Karvonen Date: Mon, 21 Aug 2023 17:02:45 +0300 Subject: [PATCH 2/4] Add documentation on the new `os_type` label --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 435aba446..fd5f4721e 100644 --- a/README.md +++ b/README.md @@ -390,6 +390,33 @@ The version number can be of the following forms: - `X.Y` - `X.Y.Z` +#### Matching based on the `os_type` (since mdx 2.4.0) + +Block can be processed or ignored depending on the current +[`os_type`](https://v2.ocaml.org/api/Sys.html#VALos_type). + +For example, different blocks could be enabled depending on whether we are on +Windows or not: + + ```ocaml + #require "unix" + ``` + + + ```ocaml + # Unix.nice 0 + - : int = 0 + ``` + + + ```ocaml + # Unix.nice 0 + Exception: Invalid_argument "Unix.nice not implemented". + ``` + +The `os_type` values should be written in ASCII and are compared case +insensitively. + #### Environment variables declaration Environment variables can be declared at the beginning of a block: From a9cdc4334f5ebb9b538af9257d071ce1479d81a3 Mon Sep 17 00:00:00 2001 From: Vesa Karvonen Date: Mon, 21 Aug 2023 17:17:14 +0300 Subject: [PATCH 3/4] Add a minimalist test case for the `os_type` label --- test/bin/mdx-test/expect/dune.inc | 12 ++++++++++++ test/bin/mdx-test/expect/os_type/test-case.md | 13 +++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/bin/mdx-test/expect/os_type/test-case.md diff --git a/test/bin/mdx-test/expect/dune.inc b/test/bin/mdx-test/expect/dune.inc index 4fd4e8f1a..f489a3e2e 100644 --- a/test/bin/mdx-test/expect/dune.inc +++ b/test/bin/mdx-test/expect/dune.inc @@ -371,6 +371,18 @@ (alias runtest) (action (diff ocaml-errors-ellipsis/test-case.md ocaml-errors-ellipsis.actual))) +(rule + (target os_type.actual) + (deps (package mdx) (source_tree os_type)) + (action + (with-stdout-to %{target} + (chdir os_type + (run ocaml-mdx test --output - test-case.md))))) + +(rule + (alias runtest) + (action (diff os_type/test-case.md os_type.actual))) + (rule (target padding.actual) (deps (package mdx) (source_tree padding)) diff --git a/test/bin/mdx-test/expect/os_type/test-case.md b/test/bin/mdx-test/expect/os_type/test-case.md new file mode 100644 index 000000000..bfb405f71 --- /dev/null +++ b/test/bin/mdx-test/expect/os_type/test-case.md @@ -0,0 +1,13 @@ +Mdx can skip blocks based on `os_type`: + +```ocaml os_type<>Win32 +# #require "unix" +# Unix.nice 0 +- : int = 0 +``` + +```ocaml os_type=Win32 +# #require "unix" +# Unix.nice 0 +Exception: Invalid_argument "Unix.nice not implemented". +``` From b160aca219ea582429bd0f5940f8b2d30e96067b Mon Sep 17 00:00:00 2001 From: Vesa Karvonen Date: Mon, 21 Aug 2023 17:23:18 +0300 Subject: [PATCH 4/4] Add `os_type` under "Added" --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e28bc8b89..ab3cae69e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,9 @@ #### Added +- Add `os_type` label to enable/disable based on `Sys.os_type` (#433, + @polytypic) + - Make MDX compatible with OCaml 5.1 (#435, @polytypic and @kit-ty-kate) #### Changed