From fcf10b429f49514c42c3bb3f25c0460a9a85202e Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 25 Jun 2019 16:31:19 +0200 Subject: [PATCH 01/20] Load packages from the 'require' label --- bin/test/main.ml | 7 ++++++- lib/block.ml | 10 ++++++++++ lib/block.mli | 3 +++ lib/top/mdx_top.ml | 5 +++++ lib/top/mdx_top.mli | 6 ++++++ test/labels.md.expected | 2 +- 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/bin/test/main.ml b/bin/test/main.ml index 3cd7ac921..65bb8f141 100644 --- a/bin/test/main.ml +++ b/bin/test/main.ml @@ -137,7 +137,12 @@ let eval_test t ?root c test = Log.debug (fun l -> l "eval_test %a" Fmt.(Dump.list (Fmt.fmt "%S")) (Toplevel.command test)); let root = root_dir ?root t in - with_dir root (fun () -> Mdx_top.eval c (Toplevel.command test)) + let required_packages = Block.required_packages t in + with_dir root (fun () -> + match Mdx_top.load_packages c required_packages with + | Ok () -> Mdx_top.eval c (Toplevel.command test) + | Error name -> Error [Fmt.strf "Package could not be found: %s" name] + ) let err_eval ~cmd lines = Fmt.epr "Got an error while evaluating:\n---\n%a\n---\n%a\n%!" diff --git a/lib/block.ml b/lib/block.ml index 6194e392d..c483bddf6 100644 --- a/lib/block.ml +++ b/lib/block.ml @@ -149,6 +149,7 @@ let labels = [ `Label "skip" , [`None]; `Label "non-deterministic", [`None; `Some "command"; `Some "output"]; `Label "version" , [`Any]; + `Label "require" , [`Any]; `Prefix "set-" , [`Any]; `Prefix "unset-" , [`None]; ] @@ -288,6 +289,15 @@ let unset_variables t = in List.map f (get_prefixed_labels t "unset-") +let required_packages t = + let f = function + | `Eq, "" -> + Fmt.failwith "invalid `require` label value: requires a value" + | `Eq, pkg -> pkg + | _ -> Fmt.failwith "invalid `env` label value" + in + List.map f (get_labels t "require") + let value t = t.value let section t = t.section let header t = t.header diff --git a/lib/block.mli b/lib/block.mli index c18af734a..9fd8973ec 100644 --- a/lib/block.mli +++ b/lib/block.mli @@ -94,6 +94,9 @@ val set_variables: t -> (string * string) list val unset_variables: t -> string list (** [unset_variable t] is the list of environment variable to unset *) +val required_packages: t -> string list +(** [required_packages t] is the names of the required packages *) + val skip: t -> bool (** [skip t] is true iff [skip] is in the labels of [t]. *) diff --git a/lib/top/mdx_top.ml b/lib/top/mdx_top.ml index e7eef9302..38cb1c815 100644 --- a/lib/top/mdx_top.ml +++ b/lib/top/mdx_top.ml @@ -744,6 +744,11 @@ let init ~verbose:v ~silent:s ~verbose_findlib () = silent t; t +let load_packages _ pkgs = + try Result.Ok (Topfind.load_deeply pkgs) + with Fl_package_base.No_such_package (name, _) -> + Result.Error name + module Part = Part let envs = Hashtbl.create 8 diff --git a/lib/top/mdx_top.mli b/lib/top/mdx_top.mli index 374542efa..37220f144 100644 --- a/lib/top/mdx_top.mli +++ b/lib/top/mdx_top.mli @@ -25,6 +25,12 @@ type t val init: verbose:bool -> silent:bool -> verbose_findlib:bool -> unit -> t (** [init ()] is a new configuration value. *) +val load_packages: t -> string list -> (unit, string) result +(** [load_packages t pkgs] Load the findlib packages [pkgs] by their name + into the toplevel. + Returns [Error pkg_name] if a package named [pkg_name] could not be found. + Otherwise, returns [Ok ()] *) + val eval: t -> string list -> (string list, string list) result (** [eval t p] evaluates the toplevel phrase [p] (possibly spawning on mulitple lines) with the configuration value [t]. *) diff --git a/test/labels.md.expected b/test/labels.md.expected index 730682f05..b9958963a 100644 --- a/test/labels.md.expected +++ b/test/labels.md.expected @@ -6,6 +6,6 @@ $ ls ``` ```sh toto,dir=xxx ->> "toto" is not a valid label or prefix. Valid labels are "dir", "source-tree", "file", "part", "env", "skip", "non-deterministic" and "version" and valid prefixes are "set-" and "unset-". +>> "toto" is not a valid label or prefix. Valid labels are "dir", "source-tree", "file", "part", "env", "skip", "non-deterministic", "version" and "require" and valid prefixes are "set-" and "unset-". $ xxx ``` From 940a7c23e8186f136efec89250521eb7d5de62a7 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 25 Jun 2019 18:01:25 +0200 Subject: [PATCH 02/20] Rule: Print dependencies to required packages --- bin/rule.ml | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/bin/rule.ml b/bin/rule.ml index b23d31295..7c7ac6a09 100644 --- a/bin/rule.ml +++ b/bin/rule.ml @@ -29,7 +29,7 @@ let prepend_root r b = match r with | None -> b | Some r -> Filename.concat r b -let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root options = +let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root ~requires options = let ml_files = String.Set.elements ml_files in let ml_files = List.map (prepend_root root) ml_files in let dirs = match root with @@ -44,6 +44,10 @@ let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root options = let f (cpt, acc) _ = cpt + 1, ("y" ^ string_of_int cpt) :: acc in List.fold_left f (0, []) ml_files |> snd in + let requires = String.Set.elements requires in + let pp_package_deps fmt name = + Fmt.pf fmt "\ (package %s)" name + in let pp_ml_deps fmt (var_name, ml_file) = Fmt.pf fmt "\ (:%s %s)" var_name ml_file in @@ -57,22 +61,18 @@ let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root options = let files = String.Set.of_list (List.map prelude_file prelude) in String.Set.elements files |> List.map (fun f -> Fmt.strf " %s" f) - |> String.concat ~sep:"\n" in let root = match root with None -> "" | Some r -> Fmt.strf "--root=%s " r in let deps = - let sep1 = if var_names <> [] then "\n" else "" in - let sep2 = if dirs <> [] && prelude <> "" then "\n" else "" in - let x = Fmt.strf "%a%s%a%s%s" - Fmt.(list ~sep:(unit "\n") pp_ml_deps) (List.combine var_names ml_files) - sep1 - Fmt.(list ~sep:(unit "\n") pp_dir_deps) dirs - sep2 - prelude + let x = + List.map (Fmt.to_to_string pp_package_deps) requires @ + List.map (Fmt.to_to_string pp_ml_deps) (List.combine var_names ml_files) @ + List.map (Fmt.to_to_string pp_dir_deps) dirs @ + prelude in match x with - | "" -> "" - | s -> "\n" ^ s + | [] -> "" + | s -> String.concat ~sep:"\n" ("" :: s) in let pp name arg = Fmt.pr @@ -117,7 +117,17 @@ let run () md_file section direction prelude prelude_str root = let on_item acc = function | Mdx.Section _ | Text _ -> acc | Block b when active b -> - let files, dirs, nd = acc in + let files, dirs, nd, requires = acc in + let requires = + (* Only depend on the base package, eg. 'a.b' become 'a' *) + let base_pkg pkg = + match String.cut ~sep:"." pkg with + | Some (base, _) -> base + | None -> pkg + in + Mdx.Block.required_packages b + |> List.fold_left (fun s e -> String.Set.add (base_pkg e) s) requires + in let nd = nd || match Mdx.Block.mode b with | `Non_det _ -> true | _ -> false @@ -129,19 +139,20 @@ let run () md_file section direction prelude prelude_str root = |> String.Set.union source_trees in let files = add_opt (Mdx.Block.file b) files in - files, dirs, nd + files, dirs, nd, requires | Block _ -> acc in let on_file file_contents items = - let ml_files, dirs, nd = - List.fold_left on_item (String.Set.empty, String.Set.empty, false) items + let ml_files, dirs, nd, requires = + let empty = String.Set.empty in + List.fold_left on_item (empty, empty, false, empty) items in let options = List.map (Fmt.to_to_string pp_prelude) prelude @ List.map (Fmt.to_to_string pp_prelude_str) prelude_str @ [Fmt.to_to_string pp_direction direction] in - print_rule ~md_file ~prelude ~nd ~ml_files ~dirs ~root options; + print_rule ~md_file ~prelude ~nd ~ml_files ~dirs ~root ~requires options; file_contents in Mdx.run md_file ~f:on_file; From e850eeacfac42531a57204bd0f1791e1e140eecf Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 25 Jun 2019 11:19:40 +0200 Subject: [PATCH 03/20] Add tests --- test/dune | 9 +++++++++ test/require/example_lib.opam | 0 test/require/example_lib/dune | 3 +++ test/require/example_lib/example_lib.ml | 1 + test/require/lib_b/dune | 4 ++++ test/require/lib_b/lib_b.ml | 1 + test/require/require.md | 15 +++++++++++++++ 7 files changed, 33 insertions(+) create mode 100644 test/require/example_lib.opam create mode 100644 test/require/example_lib/dune create mode 100644 test/require/example_lib/example_lib.ml create mode 100644 test/require/lib_b/dune create mode 100644 test/require/lib_b/lib_b.ml create mode 100644 test/require/require.md diff --git a/test/dune b/test/dune index f9655054f..9e029001c 100644 --- a/test/dune +++ b/test/dune @@ -268,3 +268,12 @@ (alias (name runtest) (action (diff dune_rules.inc dune_rules.inc.gen))) + +(alias + (name runtest) + (deps (:x require/require.md) + (package example_lib)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + (diff? %{x} %{x}.corrected) +))) diff --git a/test/require/example_lib.opam b/test/require/example_lib.opam new file mode 100644 index 000000000..e69de29bb diff --git a/test/require/example_lib/dune b/test/require/example_lib/dune new file mode 100644 index 000000000..ecca0033d --- /dev/null +++ b/test/require/example_lib/dune @@ -0,0 +1,3 @@ +(library + (name example_lib) + (public_name example_lib)) diff --git a/test/require/example_lib/example_lib.ml b/test/require/example_lib/example_lib.ml new file mode 100644 index 000000000..b1ae4eebf --- /dev/null +++ b/test/require/example_lib/example_lib.ml @@ -0,0 +1 @@ +let hello () = print_endline "Hello world!" diff --git a/test/require/lib_b/dune b/test/require/lib_b/dune new file mode 100644 index 000000000..411720df1 --- /dev/null +++ b/test/require/lib_b/dune @@ -0,0 +1,4 @@ +(library + (name lib_b) + (public_name example_lib.b) + (libraries example_lib)) diff --git a/test/require/lib_b/lib_b.ml b/test/require/lib_b/lib_b.ml new file mode 100644 index 000000000..0c5358ec6 --- /dev/null +++ b/test/require/lib_b/lib_b.ml @@ -0,0 +1 @@ +let hello () = Example_lib.hello () diff --git a/test/require/require.md b/test/require/require.md new file mode 100644 index 000000000..34acca3fa --- /dev/null +++ b/test/require/require.md @@ -0,0 +1,15 @@ +# Using local library + +```ocaml require=example_lib +# Example_lib.hello () +Hello world! +- : unit = () +``` + +# Sub library + +```ocaml require=example_lib.b +# Lib_b.hello () +Hello world! +- : unit = () +``` From 803ff47a57835bcf07d0b220005869dd723ff526 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Fri, 2 Aug 2019 17:06:54 +0200 Subject: [PATCH 04/20] Don't load packages into the toplevel Packages are now only used to generate the dune rule --- bin/test/main.ml | 7 +------ lib/top/mdx_top.ml | 5 ----- lib/top/mdx_top.mli | 6 ------ test/dune | 4 ++-- test/require/require.md | 2 ++ 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/bin/test/main.ml b/bin/test/main.ml index 65bb8f141..3cd7ac921 100644 --- a/bin/test/main.ml +++ b/bin/test/main.ml @@ -137,12 +137,7 @@ let eval_test t ?root c test = Log.debug (fun l -> l "eval_test %a" Fmt.(Dump.list (Fmt.fmt "%S")) (Toplevel.command test)); let root = root_dir ?root t in - let required_packages = Block.required_packages t in - with_dir root (fun () -> - match Mdx_top.load_packages c required_packages with - | Ok () -> Mdx_top.eval c (Toplevel.command test) - | Error name -> Error [Fmt.strf "Package could not be found: %s" name] - ) + with_dir root (fun () -> Mdx_top.eval c (Toplevel.command test)) let err_eval ~cmd lines = Fmt.epr "Got an error while evaluating:\n---\n%a\n---\n%a\n%!" diff --git a/lib/top/mdx_top.ml b/lib/top/mdx_top.ml index 38cb1c815..e7eef9302 100644 --- a/lib/top/mdx_top.ml +++ b/lib/top/mdx_top.ml @@ -744,11 +744,6 @@ let init ~verbose:v ~silent:s ~verbose_findlib () = silent t; t -let load_packages _ pkgs = - try Result.Ok (Topfind.load_deeply pkgs) - with Fl_package_base.No_such_package (name, _) -> - Result.Error name - module Part = Part let envs = Hashtbl.create 8 diff --git a/lib/top/mdx_top.mli b/lib/top/mdx_top.mli index 37220f144..374542efa 100644 --- a/lib/top/mdx_top.mli +++ b/lib/top/mdx_top.mli @@ -25,12 +25,6 @@ type t val init: verbose:bool -> silent:bool -> verbose_findlib:bool -> unit -> t (** [init ()] is a new configuration value. *) -val load_packages: t -> string list -> (unit, string) result -(** [load_packages t pkgs] Load the findlib packages [pkgs] by their name - into the toplevel. - Returns [Error pkg_name] if a package named [pkg_name] could not be found. - Otherwise, returns [Ok ()] *) - val eval: t -> string list -> (string list, string list) result (** [eval t p] evaluates the toplevel phrase [p] (possibly spawning on mulitple lines) with the configuration value [t]. *) diff --git a/test/dune b/test/dune index 9e029001c..694cc97ff 100644 --- a/test/dune +++ b/test/dune @@ -272,8 +272,8 @@ (alias (name runtest) (deps (:x require/require.md) + (package mdx) (package example_lib)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) - (diff? %{x} %{x}.corrected) -))) + (diff? %{x} %{x}.corrected)))) diff --git a/test/require/require.md b/test/require/require.md index 34acca3fa..35f6ac0d3 100644 --- a/test/require/require.md +++ b/test/require/require.md @@ -1,6 +1,7 @@ # Using local library ```ocaml require=example_lib +# #require "example_lib" # Example_lib.hello () Hello world! - : unit = () @@ -9,6 +10,7 @@ Hello world! # Sub library ```ocaml require=example_lib.b +# #require "example_lib.b" # Lib_b.hello () Hello world! - : unit = () From 5fdd66cc2117d57e7d947eb1807771a150a482f8 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Fri, 2 Aug 2019 17:07:25 +0200 Subject: [PATCH 05/20] Add executable example --- test/require/dune-project | 2 ++ test/require/example_exe/dune | 4 ++++ test/require/example_exe/example_exe.ml | 1 + test/require/require.md | 7 +++++++ 4 files changed, 14 insertions(+) create mode 100644 test/require/dune-project create mode 100644 test/require/example_exe/dune create mode 100644 test/require/example_exe/example_exe.ml diff --git a/test/require/dune-project b/test/require/dune-project new file mode 100644 index 000000000..e31cc6fdc --- /dev/null +++ b/test/require/dune-project @@ -0,0 +1,2 @@ +(lang dune 1.11) +(name example_lib) diff --git a/test/require/example_exe/dune b/test/require/example_exe/dune new file mode 100644 index 000000000..945d5ca58 --- /dev/null +++ b/test/require/example_exe/dune @@ -0,0 +1,4 @@ +(executable + (name example_exe) + (public_name example_lib.exe) + (libraries example_lib)) diff --git a/test/require/example_exe/example_exe.ml b/test/require/example_exe/example_exe.ml new file mode 100644 index 000000000..a38969127 --- /dev/null +++ b/test/require/example_exe/example_exe.ml @@ -0,0 +1 @@ +let () = Example_lib.hello () diff --git a/test/require/require.md b/test/require/require.md index 35f6ac0d3..c9b400fc6 100644 --- a/test/require/require.md +++ b/test/require/require.md @@ -15,3 +15,10 @@ Hello world! Hello world! - : unit = () ``` + +# Executables + +```sh require=example_lib.exe +$ example_lib.exe Hello +Hello world! +``` From 42a7e62249869cc5f95a5c37ef9fc37f50b15cf0 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 5 Aug 2019 10:43:17 +0200 Subject: [PATCH 06/20] Rename require to require-package --- lib/block.ml | 6 +++--- test/dune | 2 +- test/labels.md.expected | 2 +- test/require/{require.md => require-package.md} | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) rename test/require/{require.md => require-package.md} (68%) diff --git a/lib/block.ml b/lib/block.ml index c483bddf6..a0180bf47 100644 --- a/lib/block.ml +++ b/lib/block.ml @@ -149,7 +149,7 @@ let labels = [ `Label "skip" , [`None]; `Label "non-deterministic", [`None; `Some "command"; `Some "output"]; `Label "version" , [`Any]; - `Label "require" , [`Any]; + `Label "require-package" , [`Any]; `Prefix "set-" , [`Any]; `Prefix "unset-" , [`None]; ] @@ -292,11 +292,11 @@ let unset_variables t = let required_packages t = let f = function | `Eq, "" -> - Fmt.failwith "invalid `require` label value: requires a value" + Fmt.failwith "invalid `require-package` label value: requires a value" | `Eq, pkg -> pkg | _ -> Fmt.failwith "invalid `env` label value" in - List.map f (get_labels t "require") + List.map f (get_labels t "require-package") let value t = t.value let section t = t.section diff --git a/test/dune b/test/dune index 694cc97ff..87f19fad8 100644 --- a/test/dune +++ b/test/dune @@ -271,7 +271,7 @@ (alias (name runtest) - (deps (:x require/require.md) + (deps (:x require/require-package.md) (package mdx) (package example_lib)) (action (progn diff --git a/test/labels.md.expected b/test/labels.md.expected index b9958963a..a56cd4625 100644 --- a/test/labels.md.expected +++ b/test/labels.md.expected @@ -6,6 +6,6 @@ $ ls ``` ```sh toto,dir=xxx ->> "toto" is not a valid label or prefix. Valid labels are "dir", "source-tree", "file", "part", "env", "skip", "non-deterministic", "version" and "require" and valid prefixes are "set-" and "unset-". +>> "toto" is not a valid label or prefix. Valid labels are "dir", "source-tree", "file", "part", "env", "skip", "non-deterministic", "version" and "require-package" and valid prefixes are "set-" and "unset-". $ xxx ``` diff --git a/test/require/require.md b/test/require/require-package.md similarity index 68% rename from test/require/require.md rename to test/require/require-package.md index c9b400fc6..77d0ed82b 100644 --- a/test/require/require.md +++ b/test/require/require-package.md @@ -1,6 +1,6 @@ # Using local library -```ocaml require=example_lib +```ocaml require-package=example_lib # #require "example_lib" # Example_lib.hello () Hello world! @@ -9,7 +9,7 @@ Hello world! # Sub library -```ocaml require=example_lib.b +```ocaml require-package=example_lib.b # #require "example_lib.b" # Lib_b.hello () Hello world! @@ -18,7 +18,7 @@ Hello world! # Executables -```sh require=example_lib.exe +```sh require-package=example_lib.exe $ example_lib.exe Hello Hello world! ``` From 14ae16bfc96fc66fb6f319d277339e052b76e32a Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 5 Aug 2019 10:46:24 +0200 Subject: [PATCH 07/20] Don't split package names --- bin/rule.ml | 8 +------- test/require/require-package.md | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/bin/rule.ml b/bin/rule.ml index 7c7ac6a09..9a27aea0f 100644 --- a/bin/rule.ml +++ b/bin/rule.ml @@ -119,14 +119,8 @@ let run () md_file section direction prelude prelude_str root = | Block b when active b -> let files, dirs, nd, requires = acc in let requires = - (* Only depend on the base package, eg. 'a.b' become 'a' *) - let base_pkg pkg = - match String.cut ~sep:"." pkg with - | Some (base, _) -> base - | None -> pkg - in Mdx.Block.required_packages b - |> List.fold_left (fun s e -> String.Set.add (base_pkg e) s) requires + |> List.fold_left (fun s e -> String.Set.add e s) requires in let nd = nd || match Mdx.Block.mode b with | `Non_det _ -> true diff --git a/test/require/require-package.md b/test/require/require-package.md index 77d0ed82b..5701f6180 100644 --- a/test/require/require-package.md +++ b/test/require/require-package.md @@ -9,7 +9,7 @@ Hello world! # Sub library -```ocaml require-package=example_lib.b +```ocaml require-package=example_lib # #require "example_lib.b" # Lib_b.hello () Hello world! @@ -18,7 +18,7 @@ Hello world! # Executables -```sh require-package=example_lib.exe +```sh require-package=example_lib $ example_lib.exe Hello Hello world! ``` From 540c32b43aec1496273a69b5a418e5cdcfc4fc73 Mon Sep 17 00:00:00 2001 From: Craig Ferguson Date: Wed, 4 Sep 2019 16:00:15 +0200 Subject: [PATCH 08/20] Modify 'pp' to respect the 'skip' label --- bin/pp.ml | 22 ++++++++++++---------- test/section.md | 8 ++++++++ test/section.md.expected | 8 ++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/bin/pp.ml b/bin/pp.ml index 8867fb7eb..baebbedfe 100644 --- a/bin/pp.ml +++ b/bin/pp.ml @@ -34,16 +34,18 @@ let run () file section = | Mdx.Section _ | Text _ -> () | Block b -> let b = Mdx.Block.eval b in - Log.debug (fun l -> l "pp: %a" Mdx.Block.dump b); - let pp_lines = Fmt.(list ~sep:(unit "\n") string) in - let contents = Mdx.Block.executable_contents b in - match b.value with - | Toplevel _ -> Fmt.pr "%a\n" pp_lines contents - | OCaml -> - Fmt.pr "%a\n%a\n" - Mdx.Block.pp_line_directive (file, b.line) - pp_lines contents - | _ -> () + if not (Mdx.Block.skip b) then ( + Log.debug (fun l -> l "pp: %a" Mdx.Block.dump b); + let pp_lines = Fmt.(list ~sep:(unit "\n") string) in + let contents = Mdx.Block.executable_contents b in + match b.value with + | Toplevel _ -> Fmt.pr "%a\n" pp_lines contents + | OCaml -> + Fmt.pr "%a\n%a\n" + Mdx.Block.pp_line_directive (file, b.line) + pp_lines contents + | _ -> () + ) ) t; 0 diff --git a/test/section.md b/test/section.md index 7f8d1084b..84e5a0687 100644 --- a/test/section.md +++ b/test/section.md @@ -40,3 +40,11 @@ let () = print_endline (string_of_int x) # print_endline "42";; 42 ``` + +## Skipped blocks + +This block should not be executed by the tests: + +```ocaml skip +let () = assert false +``` diff --git a/test/section.md.expected b/test/section.md.expected index 8c5bcad98..c7f71b35f 100644 --- a/test/section.md.expected +++ b/test/section.md.expected @@ -50,3 +50,11 @@ let () = print_endline (string_of_int x) # print_endline "42";; 42 ``` + +## Skipped blocks + +This block should not be executed by the tests: + +```ocaml skip +let () = assert false +``` From c6657ee607b9ab4bb2cca3e32049ac6d141df1e7 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 6 Aug 2019 18:26:04 +0200 Subject: [PATCH 09/20] Parse parts line by line instead of using the OCaml parser --- lib/top/part.ml | 246 +++++------------------------------- test/sync_to_md.md.expected | 2 + test/sync_to_ml.ml.expected | 1 + 3 files changed, 38 insertions(+), 211 deletions(-) diff --git a/lib/top/part.ml b/lib/top/part.ml index 202af9d8d..cac13fe9e 100644 --- a/lib/top/part.ml +++ b/lib/top/part.ml @@ -14,7 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) -open Mdx.Migrate_ast open Mdx.Compat module Part = struct @@ -29,199 +28,41 @@ module Part = struct end -module Lexbuf = struct - - open Lexing - - type t = { - contents: string; - lexbuf : lexbuf; - } - - let initial_pos name = { - pos_fname = name; - pos_lnum = 1; - pos_bol = 0; - pos_cnum = 0; - } - - let v ~fname contents = - let lexbuf = Lexing.from_string contents in - lexbuf.lex_curr_p <- initial_pos fname; - Location.input_name := fname; - { contents; lexbuf } - - let of_file fname = - let ic = open_in fname in - let len = in_channel_length ic in - let result = really_input_string ic len in - close_in_noerr ic; - v ~fname result - -end - -module Phrase = struct - - open Lexing - open Parsetree - - type kind = Code | Part of string - - exception Cannot_parse_payload of Location.t - - let string_of_location - {Location.loc_start = {pos_fname; pos_lnum; pos_bol; pos_cnum};_} - = - Printf.sprintf "%s, line %d, col %d" pos_fname pos_lnum (pos_cnum - pos_bol) - - let payload_constants loc = function - | PStr [{pstr_desc = Pstr_eval (expr, _); _}] -> - let one {pexp_loc; pexp_desc; _} = match pexp_desc with - | Pexp_apply ({pexp_desc = Pexp_ident ident; _}, - [Asttypes.Nolabel, {pexp_desc = Pexp_constant const; _}]) -> - (pexp_loc, Some ident, const) - | Pexp_constant const -> (pexp_loc, None, const) - | _ -> raise (Cannot_parse_payload pexp_loc) - in - let rec consts = function - | {pexp_desc=Pexp_sequence(e, rest); _} -> one e :: consts rest - | e -> [one e] - in - consts expr - | PStr [] -> [] - | _ -> raise (Cannot_parse_payload loc) - - let payload_strings loc = function - | PStr [] -> [] - | x -> - let aux = function - | _, Some {Location.txt = Longident.Lident "ocaml"; _}, - Pconst_string (str, _) -> (`OCaml, str) - | _, None, Pconst_string (str, _) -> (`Raw, str) - | loc, _, _ -> raise (Cannot_parse_payload loc) - in - List.map aux (payload_constants loc x) - - let kind_impl = function - | {pstr_desc = Pstr_attribute (name, payload); pstr_loc} - when name.Asttypes.txt = "part" -> - begin match payload_strings pstr_loc payload with - | [`Raw, part] -> Part part - | _ -> - prerr_endline - (string_of_location pstr_loc ^ ": cannot parse [@@@part] payload"); - Code - | exception (Cannot_parse_payload loc) -> - prerr_endline - (string_of_location loc ^ ": cannot parse [@@@part] payload"); - Code - end - | _ -> Code - - let kind_intf = function - | {psig_desc = Psig_attribute (name, payload); psig_loc} - when name.Asttypes.txt = "part" -> - begin match payload_strings psig_loc payload with - | [`Raw, part] -> Part part - | _ -> - prerr_endline - (string_of_location psig_loc ^ ": cannot parse [@@@part] payload"); - Code - | exception (Cannot_parse_payload loc) -> - prerr_endline - (string_of_location loc ^ ": cannot parse [@@@part] payload"); - Code - end - | _ -> Code - - - (* by default, [structure_item] locations do not contain the [;;] token, - so here we try to extend the location when this is needed. *) - let shift_semi_semi doc loc = - let str = doc.Lexbuf.contents in - let stop = loc.pos_cnum in - let rec aux n = - if n+1 >= String.length str then loc - else match str.[n], str.[n+1] with - | '\n', _ -> aux (n+1) - | ';', ';' -> { loc with pos_cnum = n + 2 } - | _, _ -> loc - in - aux stop - - let body_impl doc s = - let start = match s with - | s::_ -> Some s.pstr_loc.loc_start.pos_cnum - | _ -> None - in - let stop = match List.rev s with - | s::_ -> Some (shift_semi_semi doc s.pstr_loc.loc_end).pos_cnum - | _ -> None - in - match start, stop with - | Some start, Some stop -> - String.sub doc.Lexbuf.contents start (stop - start) - | _ -> "" - - let body_intf doc s = - let start = match s with - | s::_ -> Some s.psig_loc.loc_start.pos_cnum - | _ -> None - in - let stop = match List.rev s with - | s::_ -> Some (shift_semi_semi doc s.psig_loc.loc_end).pos_cnum - | _ -> None +module Parse_parts = +struct + + let part_statement_re = + let open Re in + let ws = rep space in + compile @@ whole_string @@ seq [ + ws; str "[@@@"; ws; str "part"; ws; + str "\""; group (rep1 any); str "\""; + ws; str "]"; ws; opt (str ";;"); ws; + ] + + let make_part ~name ~lines = + (* Remove empty lines at the end of the part *) + let rec remove_empty = function + | "" :: tl -> remove_empty tl + | ls -> ls in - match start, stop with - | Some start, Some stop -> - String.sub doc.Lexbuf.contents start (stop - start) - | _ -> "" - - let parts ~body doc phrases = - let rec aux parts part strs = function - | (s, Code) :: rest -> aux parts part (s :: strs) rest - | (_, Part name) :: rest -> - let body = body doc (List.rev strs) in - let parts = Part.v ~name:part ~body :: parts in - aux parts name [] rest - | [] -> - let parts = - if part <> "" || strs <> [] then - let body = body doc (List.rev strs) in - Part.v ~name:part ~body :: parts - else - if List.length parts = 0 then - [Part.v ~name:"" ~body:""] - else - parts - in - List.rev parts - in - aux [] "" [] phrases - - let handle_syntax_error e = -#if OCAML_MAJOR >= 4 && OCAML_MINOR >= 8 - (* The function is now Parse.prepare_error, but it is not - exposed; luckily enough, it is register to print the - exception. *) - Fmt.failwith "Cannot parse: %s" (Printexc.to_string (Syntaxerr.Error e)) -#else - Fmt.failwith "Cannot parse: %a" Syntaxerr.report_error e -#endif - - let read_impl doc = - try - let strs = Parse.implementation doc.Lexbuf.lexbuf in - List.map (fun x -> x, kind_impl x) strs - with Syntaxerr.Error e -> - handle_syntax_error e - - let read_intf doc = - try - let strs = Parse.interface doc.Lexbuf.lexbuf in - List.map (fun x -> x, kind_intf x) strs - with Syntaxerr.Error e -> - handle_syntax_error e + let body = String.concat "\n" (List.rev (remove_empty lines)) in + Part.v ~name ~body + + let rec parse_parts input name lines = + match input_line input with + | exception End_of_file -> [make_part ~name ~lines] + | line -> + match Re.exec_opt part_statement_re line with + | None -> parse_parts input name (line :: lines) + | Some groups -> + let part = make_part ~name ~lines in + let new_name = Re.Group.get groups 1 in + part :: parse_parts input new_name [] + + let of_file name = + let input = open_in name in + parse_parts input "" [] end @@ -229,25 +70,8 @@ type file = | Parts of Part.t list | Body of (exn * string) -let read_impl lexbuf = - Phrase.(parts ~body:body_impl lexbuf (read_impl lexbuf)) - -let read_intf lexbuf = - Phrase.(parts ~body:body_intf lexbuf (read_intf lexbuf)) - let read file = - let lexbuf = Lexbuf.of_file file in - let read = match Filename.extension file with - | ".ml" -> read_impl - | ".mli" -> read_intf - | s -> Fmt.failwith "unknown extension: %s" s - in - try - lexbuf - |> read - |> fun x -> Parts x - with e -> - Body (e, lexbuf.Lexbuf.contents) + Parts (Parse_parts.of_file file) let err_parse_error (e, _) = Fmt.failwith "Parse error: %a" Fmt.exn e diff --git a/test/sync_to_md.md.expected b/test/sync_to_md.md.expected index c9fa847f4..3900948e1 100644 --- a/test/sync_to_md.md.expected +++ b/test/sync_to_md.md.expected @@ -37,6 +37,7 @@ let () = () ;; + let x = 34 let f = 42.3 let s = "toto" @@ -47,6 +48,7 @@ let () = print_float f ;; + let () = print_string s ;; diff --git a/test/sync_to_ml.ml.expected b/test/sync_to_ml.ml.expected index 218c5c2e2..595026bc4 100644 --- a/test/sync_to_ml.ml.expected +++ b/test/sync_to_ml.ml.expected @@ -19,6 +19,7 @@ let f = "hello world!" [@@@part "42"] ;; + let () = f x print_int From a21bfad2dec0bdecd04cef74fc56da32d97a1c1c Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 6 Aug 2019 18:33:22 +0200 Subject: [PATCH 10/20] Add tests --- test/sync_to_ml.md | 11 ++++++++++- test/sync_to_ml.md.expected | 11 ++++++++++- test/sync_to_ml.mli | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/test/sync_to_ml.md b/test/sync_to_ml.md index a1534deed..8f04f12aa 100644 --- a/test/sync_to_ml.md +++ b/test/sync_to_ml.md @@ -40,6 +40,15 @@ let () = () ``` +```ocaml file=sync_to_ml.mli,part=1 +module A = +struct +``` + +```ocaml file=sync_to_ml.mli,part=2 + type t = Some of int | Many +``` + ```ocaml file=sync_to_ml.mli,part=3 -type t = Some of int | Many +end ``` diff --git a/test/sync_to_ml.md.expected b/test/sync_to_ml.md.expected index ed0e77fc0..8cae828e5 100644 --- a/test/sync_to_ml.md.expected +++ b/test/sync_to_ml.md.expected @@ -40,6 +40,15 @@ let () = () ``` +```ocaml file=sync_to_ml.mli,part=1 +module A = +struct +``` + +```ocaml file=sync_to_ml.mli,part=2 + type t = Some of int | Many +``` + ```ocaml file=sync_to_ml.mli,part=3 -type t = Some of int | Many +end ``` diff --git a/test/sync_to_ml.mli b/test/sync_to_ml.mli index 99c842ba5..e05de951e 100644 --- a/test/sync_to_ml.mli +++ b/test/sync_to_ml.mli @@ -1,5 +1,14 @@ val f: unit -> unit +[@@@part "1"] ;; + +module A = +struct + +[@@@part "2"] ;; + + type t = Some of int | Many + [@@@part "3"] ;; -type t = Some of int | Many +end From 49be5a176aeaf109be300e6b4c7fe8149ab75854 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 6 Aug 2019 19:02:34 +0200 Subject: [PATCH 11/20] Remove error handling code --- lib/top/part.ml | 72 ++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/lib/top/part.ml b/lib/top/part.ml index cac13fe9e..90b1ea664 100644 --- a/lib/top/part.ml +++ b/lib/top/part.ml @@ -28,6 +28,11 @@ module Part = struct end +(** Remove empty strings at the beginning of a list *) +let rec remove_empty_heads = function + | "" :: tl -> remove_empty_heads tl + | l -> l + module Parse_parts = struct @@ -41,12 +46,7 @@ struct ] let make_part ~name ~lines = - (* Remove empty lines at the end of the part *) - let rec remove_empty = function - | "" :: tl -> remove_empty tl - | ls -> ls - in - let body = String.concat "\n" (List.rev (remove_empty lines)) in + let body = String.concat "\n" (List.rev (remove_empty_heads lines)) in Part.v ~name ~body let rec parse_parts input name lines = @@ -66,25 +66,17 @@ struct end -type file = - | Parts of Part.t list - | Body of (exn * string) - -let read file = - Parts (Parse_parts.of_file file) +type file = Part.t list -let err_parse_error (e, _) = - Fmt.failwith "Parse error: %a" Fmt.exn e +let read file = Parse_parts.of_file file -let find file ~part = match file, part with - | Body (_, s), None -> Some [s] - | Body b, _ -> err_parse_error b - | Parts parts, Some part -> - (match List.find_opt (fun p -> String.equal (Part.name p) part) parts with +let find file ~part = match part with + | Some part -> + (match List.find_opt (fun p -> String.equal (Part.name p) part) file with | Some p -> Some [Part.body p] | None -> None ) - | Parts parts, None -> - List.fold_left (fun acc p -> Part.body p :: [""] @ acc) [] parts + | None -> + List.fold_left (fun acc p -> Part.body p :: [""] @ acc) [] file |> List.rev |> fun x -> Some x @@ -96,25 +88,19 @@ let rec replace_or_append part_name body = function | [] -> [{ name = part_name; body }] -let replace file ~part ~lines = match file, part with - | Body (e, _), None -> Body (e, String.concat "\n" lines) - | Body b , _ -> err_parse_error b - | Parts parts, _ -> - let part = match part with None -> "" | Some p -> p in - let parts = replace_or_append part (String.concat "\n" lines) parts in - Parts parts - -let contents = function - | Body (_, s) -> String.trim s ^ "\n" - | Parts parts -> - let lines = - List.fold_left (fun acc p -> - let body = Part.body p in - match Part.name p with - | "" -> body :: acc - | n -> body :: ("\n[@@@part \"" ^ n ^ "\"] ;;\n") :: acc - ) [] parts - in - let lines = List.rev lines in - let lines = String.concat "\n" lines in - String.trim lines ^ "\n" +let replace file ~part ~lines = + let part = match part with None -> "" | Some p -> p in + replace_or_append part (String.concat "\n" lines) file + +let contents file = + let lines = + List.fold_left (fun acc p -> + let body = Part.body p in + match Part.name p with + | "" -> body :: acc + | n -> body :: ("\n[@@@part \"" ^ n ^ "\"] ;;\n") :: acc + ) [] file + in + let lines = List.rev lines in + let lines = String.concat "\n" lines in + String.trim lines ^ "\n" From 8796b38c961583268b485607189172b697321396 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 19 Aug 2019 18:40:11 +0200 Subject: [PATCH 12/20] Fix extra empty line between parts in to-md direction --- bin/test/main.ml | 11 +++++------ test/sync_to_md.md.expected | 2 -- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/bin/test/main.ml b/bin/test/main.ml index 3cd7ac921..d2c0c741f 100644 --- a/bin/test/main.ml +++ b/bin/test/main.ml @@ -183,13 +183,12 @@ let run_toplevel_tests ?root c ppf tests t = Block.pp_footer ppf () let trim l = - let rec aux = function - | [] -> [] - | h::t -> if String.trim h = "" then aux t else String.trim h :: t + let rec trim_front = function + | ""::t -> trim_front t + | l -> l in - let no_head = aux l in - let no_tail = List.rev (aux (List.rev no_head)) in - no_tail + let rev_trim l = trim_front (List.rev (trim_front l)) in + rev_trim (List.rev_map String.trim l) type file = { first: Mdx_top.Part.file; current: Mdx_top.Part.file } diff --git a/test/sync_to_md.md.expected b/test/sync_to_md.md.expected index 3900948e1..c9fa847f4 100644 --- a/test/sync_to_md.md.expected +++ b/test/sync_to_md.md.expected @@ -37,7 +37,6 @@ let () = () ;; - let x = 34 let f = 42.3 let s = "toto" @@ -48,7 +47,6 @@ let () = print_float f ;; - let () = print_string s ;; From 4307cf2c7fa88760bb39932a22c69de7084133ac Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 19 Aug 2019 19:15:52 +0200 Subject: [PATCH 13/20] Preserve trailing whitespaces before part separators --- lib/top/part.ml | 34 +++++++++++++++++++++------------- test/sync_to_ml.mli | 4 ++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/top/part.ml b/lib/top/part.ml index 90b1ea664..f222920ce 100644 --- a/lib/top/part.ml +++ b/lib/top/part.ml @@ -20,10 +20,12 @@ module Part = struct type t = { name: string; + sep_indent: string; (** Whitespaces before the [@@@part] separator *) body: string; } - let v ~name ~body = { name; body } + let v ~name ~sep_indent ~body = { name; sep_indent; body } let name {name;_} = name + let sep_indent {sep_indent;_} = sep_indent let body {body;_} = body end @@ -40,29 +42,33 @@ struct let open Re in let ws = rep space in compile @@ whole_string @@ seq [ - ws; str "[@@@"; ws; str "part"; ws; + group ws; str "[@@@"; ws; str "part"; ws; str "\""; group (rep1 any); str "\""; ws; str "]"; ws; opt (str ";;"); ws; ] - let make_part ~name ~lines = + let next_part ~name ~sep_indent = fun lines -> let body = String.concat "\n" (List.rev (remove_empty_heads lines)) in - Part.v ~name ~body + Part.v ~name ~sep_indent ~body - let rec parse_parts input name lines = + let next_part_of_groups groups = + let sep_indent = Re.Group.get groups 1 in + let name = Re.Group.get groups 2 in + next_part ~name ~sep_indent + + let rec parse_parts input make_part lines = match input_line input with - | exception End_of_file -> [make_part ~name ~lines] + | exception End_of_file -> [make_part lines] | line -> match Re.exec_opt part_statement_re line with - | None -> parse_parts input name (line :: lines) + | None -> parse_parts input make_part (line :: lines) | Some groups -> - let part = make_part ~name ~lines in - let new_name = Re.Group.get groups 1 in - part :: parse_parts input new_name [] + let next_part = next_part_of_groups groups in + make_part lines :: parse_parts input next_part [] let of_file name = let input = open_in name in - parse_parts input "" [] + parse_parts input (next_part ~name:"" ~sep_indent:"") [] end @@ -86,7 +92,7 @@ let rec replace_or_append part_name body = function | p :: tl -> p :: replace_or_append part_name body tl | [] -> - [{ name = part_name; body }] + [{ name = part_name; sep_indent = ""; body }] let replace file ~part ~lines = let part = match part with None -> "" | Some p -> p in @@ -98,7 +104,9 @@ let contents file = let body = Part.body p in match Part.name p with | "" -> body :: acc - | n -> body :: ("\n[@@@part \"" ^ n ^ "\"] ;;\n") :: acc + | n -> + let indent = Part.sep_indent p in + body :: ("\n" ^ indent ^ "[@@@part \"" ^ n ^ "\"] ;;\n") :: acc ) [] file in let lines = List.rev lines in diff --git a/test/sync_to_ml.mli b/test/sync_to_ml.mli index e05de951e..b210bac3c 100644 --- a/test/sync_to_ml.mli +++ b/test/sync_to_ml.mli @@ -5,10 +5,10 @@ val f: unit -> unit module A = struct -[@@@part "2"] ;; + [@@@part "2"] ;; type t = Some of int | Many -[@@@part "3"] ;; + [@@@part "3"] ;; end From a4470a6b0cc25ca08b40114b74b9dbafb1c5d805 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 20 Aug 2019 11:58:02 +0200 Subject: [PATCH 14/20] Trim empty lines upfront --- bin/test/main.ml | 10 +--------- lib/top/part.ml | 7 +++++-- test/sync_to_ml.ml.expected | 1 - 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/bin/test/main.ml b/bin/test/main.ml index d2c0c741f..262d59a4f 100644 --- a/bin/test/main.ml +++ b/bin/test/main.ml @@ -182,14 +182,6 @@ let run_toplevel_tests ?root c ppf tests t = ) tests; Block.pp_footer ppf () -let trim l = - let rec trim_front = function - | ""::t -> trim_front t - | l -> l - in - let rev_trim l = trim_front (List.rev (trim_front l)) in - rev_trim (List.rev_map String.trim l) - type file = { first: Mdx_top.Part.file; current: Mdx_top.Part.file } let files: (string, file) Hashtbl.t = Hashtbl.create 8 @@ -227,8 +219,8 @@ let update_block_with_file ppf t file part = (match part with None -> "" | Some p -> p) file | Some lines -> - let lines = trim lines in let contents = String.concat "\n" lines in + let contents = String.trim contents in Output.pp ppf (`Output contents); Block.pp_footer ppf () diff --git a/lib/top/part.ml b/lib/top/part.ml index f222920ce..2af1a034c 100644 --- a/lib/top/part.ml +++ b/lib/top/part.ml @@ -35,6 +35,9 @@ let rec remove_empty_heads = function | "" :: tl -> remove_empty_heads tl | l -> l +let trim_empty_rev l = + remove_empty_heads (List.rev (remove_empty_heads l)) + module Parse_parts = struct @@ -47,8 +50,8 @@ struct ws; str "]"; ws; opt (str ";;"); ws; ] - let next_part ~name ~sep_indent = fun lines -> - let body = String.concat "\n" (List.rev (remove_empty_heads lines)) in + let next_part ~name ~sep_indent = fun lines_rev -> + let body = String.concat "\n" (trim_empty_rev lines_rev) in Part.v ~name ~sep_indent ~body let next_part_of_groups groups = diff --git a/test/sync_to_ml.ml.expected b/test/sync_to_ml.ml.expected index 595026bc4..218c5c2e2 100644 --- a/test/sync_to_ml.ml.expected +++ b/test/sync_to_ml.ml.expected @@ -19,7 +19,6 @@ let f = "hello world!" [@@@part "42"] ;; - let () = f x print_int From eb3159186750aef067030d109b8e8689044a75a0 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Fri, 6 Sep 2019 17:58:44 +0200 Subject: [PATCH 15/20] Style & minor fix --- bin/rule.ml | 5 ++--- lib/block.ml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bin/rule.ml b/bin/rule.ml index 9a27aea0f..4afa3306a 100644 --- a/bin/rule.ml +++ b/bin/rule.ml @@ -64,13 +64,12 @@ let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root ~requires options = in let root = match root with None -> "" | Some r -> Fmt.strf "--root=%s " r in let deps = - let x = + match List.map (Fmt.to_to_string pp_package_deps) requires @ List.map (Fmt.to_to_string pp_ml_deps) (List.combine var_names ml_files) @ List.map (Fmt.to_to_string pp_dir_deps) dirs @ prelude - in - match x with + with | [] -> "" | s -> String.concat ~sep:"\n" ("" :: s) in diff --git a/lib/block.ml b/lib/block.ml index a0180bf47..6c98177c4 100644 --- a/lib/block.ml +++ b/lib/block.ml @@ -294,7 +294,7 @@ let required_packages t = | `Eq, "" -> Fmt.failwith "invalid `require-package` label value: requires a value" | `Eq, pkg -> pkg - | _ -> Fmt.failwith "invalid `env` label value" + | _ -> Fmt.failwith "invalid `require-package` label value" in List.map f (get_labels t "require-package") From 375a878dc4fed4c0db5ca302f77b991b7f2366f1 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 9 Sep 2019 11:52:30 +0200 Subject: [PATCH 16/20] Fix prelude_str generate wrong sexp --- bin/rule.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/rule.ml b/bin/rule.ml index 4afa3306a..2f9f60ab7 100644 --- a/bin/rule.ml +++ b/bin/rule.ml @@ -99,7 +99,7 @@ let pp_direction fmt = function | `To_ml -> Fmt.pf fmt "--direction=to-ml" let pp_prelude fmt s = Fmt.pf fmt "--prelude=%s" s -let pp_prelude_str fmt s = Fmt.pf fmt "--prelude-str=%S" s +let pp_prelude_str fmt s = Fmt.pf fmt "--prelude-str %S" s let add_opt e s = match e with None -> s | Some e -> String.Set.add e s From 34cd12a2a9d13e3717e9fb3a1309b89fcd0a92a8 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Fri, 6 Sep 2019 18:09:03 +0200 Subject: [PATCH 17/20] Generate more test rules All rules that were not using an .expected file --- test/dune | 205 +++++++++---------------------------------- test/dune.inc | 206 ++++++++++++++++++++++++++++++++++++++++++++ test/dune_rules.inc | 12 --- 3 files changed, 245 insertions(+), 178 deletions(-) create mode 100644 test/dune.inc delete mode 100644 test/dune_rules.inc diff --git a/test/dune b/test/dune index 87f19fad8..82311c055 100644 --- a/test/dune +++ b/test/dune @@ -1,3 +1,42 @@ +(include dune.inc) + +; Generates rules + +(rule + (targets dune.inc.gen) + (deps (package mdx)) + (action + (with-stdout-to %{targets} + (progn + (run ocaml-mdx rule %{dep:pp.md}) + (run ocaml-mdx rule %{dep:ellipsis.md}) + (run ocaml-mdx rule %{dep:envs.md}) + (run ocaml-mdx rule %{dep:empty_line.md}) + (run ocaml-mdx rule %{dep:spaces.md}) + (run ocaml-mdx rule %{dep:cram.t}) + (run ocaml-mdx rule %{dep:errors.md}) + (run ocaml-mdx rule %{dep:heredoc.md}) + (run ocaml-mdx rule %{dep:mlt.md}) + (run ocaml-mdx rule %{dep:semisemi.md}) + (run ocaml-mdx rule %{dep:exit.md}) + (run ocaml-mdx rule %{dep:padding.md}) + (run ocaml-mdx rule %{dep:multilines.md}) + (run ocaml-mdx rule %{dep:lines.md}) + (run ocaml-mdx rule %{dep:lwt.md}) + (run ocaml-mdx rule %{dep:non-det.md}) + (run ocaml-mdx rule %{dep:code.md}) + (run ocaml-mdx rule %{dep:set_environment_variable.md}) + (run ocaml-mdx rule %{dep:unset_environment_variable.md}) + (run ocaml-mdx rule --prelude-str "#require \"lwt\"" --prelude-str "toto:let x = \"42\"" %{dep:prelude.md}) + (run ocaml-mdx rule --prelude prelude.ml %{dep:prelude_file.md}) + (run ocaml-mdx rule --direction=to-ml %{dep:dune_rules.md}) + (run ocaml-mdx rule %{dep:require/require-package.md}) + )))) + +(alias + (name runtest) + (action (diff dune.inc dune.inc.gen))) + (alias (name runtest) (deps (:x section.md) (:y section.md.expected) (package mdx)) @@ -26,27 +65,6 @@ (run ocaml-mdx test --force-output %{x}) (diff? %{y} %{x}.corrected)))) -(alias - (name runtest) - (deps (:x ellipsis.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x envs.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x empty_line.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - (alias (name runtest) (deps (:x empty_lines.md) (:y empty_lines.md.expected) (package mdx)) @@ -61,97 +79,6 @@ (run ocaml-mdx output %{x} -o output.html) (diff? %{y} output.html)))) -(alias - (name runtest) - (deps (:x spaces.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x cram.t) (package mdx)) - (action (progn - (run ocaml-mdx test --syntax=cram %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x errors.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x heredoc.md) section.md (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x mlt.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x semisemi.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x exit.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x padding.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x multilines.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x lines.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x lwt.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x non-det.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x code.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - (alias (name runtest) (deps (:x dir.md) (package mdx)) @@ -167,40 +94,6 @@ (action (progn (run ocaml-mdx test --force-output --root=.. %{x}) (diff? %{y} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x set_environment_variable.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x unset_environment_variable.md) (package mdx)) - (action (progn - (run ocaml-mdx test %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x prelude.md) (package mdx)) - (action (progn - (run ocaml-mdx - test - --prelude-str "#require \"lwt\"" - --prelude-str "toto:let x = \"42\"" - %{x}) - (diff? %{x} %{x}.corrected)))) - -(alias - (name runtest) - (deps (:x prelude_file.md) prelude.ml (package mdx)) - (action (progn - (run ocaml-mdx test --prelude prelude.ml %{x}) - (diff? %{x} %{x}.corrected)))) - - (alias (name runtest) (deps (:x sync_to_md.md) @@ -257,23 +150,3 @@ (name runtest) (deps (:x section.out) (:y section.out.expected)) (action (diff? %{x} %{y}))) - -(include dune_rules.inc) - -(rule - (targets dune_rules.inc.gen) - (deps (source_tree test-cases) (:x dune_rules.md) (package mdx)) - (action (with-stdout-to %{targets} (run ocaml-mdx rule --direction=to-ml %{x})))) - -(alias - (name runtest) - (action (diff dune_rules.inc dune_rules.inc.gen))) - -(alias - (name runtest) - (deps (:x require/require-package.md) - (package mdx) - (package example_lib)) - (action (progn - (run ocaml-mdx test --direction=infer-timestamp %{x}) - (diff? %{x} %{x}.corrected)))) diff --git a/test/dune.inc b/test/dune.inc new file mode 100644 index 000000000..565d938d1 --- /dev/null +++ b/test/dune.inc @@ -0,0 +1,206 @@ +(alias + (name runtest) + (deps (:x pp.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x ellipsis.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x envs.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x empty_line.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x spaces.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x cram.t) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x errors.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest-all) + (deps (:x errors.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp --non-deterministic %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x heredoc.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x mlt.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x semisemi.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x exit.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x padding.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x multilines.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x lines.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x lwt.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x non-det.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest-all) + (deps (:x non-det.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp --non-deterministic %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x code.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x set_environment_variable.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x unset_environment_variable.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x prelude.md) + (package mdx)) + (action (progn + (run ocaml-mdx test --prelude-str "#require \"lwt\"" --prelude-str "toto:let x = \"42\"" --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x prelude_file.md) + (package mdx) + prelude.ml) + (action (progn + (run ocaml-mdx test --prelude=prelude.ml --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x dune_rules.md) + (package mdx) + (:y1 dune_rules_1.ml) + (:y0 dune_rules_2.ml) + (source_tree foo)) + (action (progn + (run ocaml-mdx test --direction=to-ml %{x}) + (diff? %{y1} %{y1}.corrected) + (diff? %{y0} %{y0}.corrected) + (diff? %{x} %{x}.corrected)))) +(alias + (name runtest) + (deps (:x require/require-package.md) + (package mdx) + (package example_lib)) + (action (progn + (run ocaml-mdx test --direction=infer-timestamp %{x}) + + (diff? %{x} %{x}.corrected)))) diff --git a/test/dune_rules.inc b/test/dune_rules.inc deleted file mode 100644 index 22d9c4a1a..000000000 --- a/test/dune_rules.inc +++ /dev/null @@ -1,12 +0,0 @@ -(alias - (name runtest) - (deps (:x dune_rules.md) - (package mdx) - (:y1 dune_rules_1.ml) - (:y0 dune_rules_2.ml) - (source_tree foo)) - (action (progn - (run ocaml-mdx test --direction=to-ml %{x}) - (diff? %{y1} %{y1}.corrected) - (diff? %{y0} %{y0}.corrected) - (diff? %{x} %{x}.corrected)))) From 672efd1efc0d6ec6de8ead3cf5f0a9d6594531fa Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Mon, 9 Sep 2019 15:57:29 +0200 Subject: [PATCH 18/20] Don't generate cram test The --syntax option cannot be passed to mdx rule --- test/dune | 8 +++++++- test/dune.inc | 8 -------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test/dune b/test/dune index 82311c055..34a21aa6d 100644 --- a/test/dune +++ b/test/dune @@ -13,7 +13,6 @@ (run ocaml-mdx rule %{dep:envs.md}) (run ocaml-mdx rule %{dep:empty_line.md}) (run ocaml-mdx rule %{dep:spaces.md}) - (run ocaml-mdx rule %{dep:cram.t}) (run ocaml-mdx rule %{dep:errors.md}) (run ocaml-mdx rule %{dep:heredoc.md}) (run ocaml-mdx rule %{dep:mlt.md}) @@ -79,6 +78,13 @@ (run ocaml-mdx output %{x} -o output.html) (diff? %{y} output.html)))) +(alias + (name runtest) + (deps (:x cram.t) (package mdx)) + (action (progn + (run ocaml-mdx test --syntax=cram %{x}) + (diff? %{x} %{x}.corrected)))) + (alias (name runtest) (deps (:x dir.md) (package mdx)) diff --git a/test/dune.inc b/test/dune.inc index 565d938d1..28a1fbd81 100644 --- a/test/dune.inc +++ b/test/dune.inc @@ -39,14 +39,6 @@ (diff? %{x} %{x}.corrected)))) (alias - (name runtest) - (deps (:x cram.t) - (package mdx)) - (action (progn - (run ocaml-mdx test --direction=infer-timestamp %{x}) - - (diff? %{x} %{x}.corrected)))) -(alias (name runtest) (deps (:x errors.md) (package mdx)) From 1da8234c74fd065c93ab3c52da93a9a1051fb261 Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Wed, 11 Sep 2019 19:11:00 +0200 Subject: [PATCH 19/20] Remove extra package deps on mdx This reverts #141. Package dependencies cannot be resolved to opam packages by dune as of today. This so-called fix introduces a bug and the package dependency on mdx should only be added when vendoring mdx itself, eg in a duniverse. I'll re-enable that in the `--duniverse-mode`! --- bin/rule.ml | 3 +-- test/dune.inc | 66 ++++++++++++++++----------------------------------- 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/bin/rule.ml b/bin/rule.ml index 2f9f60ab7..1fc645ac3 100644 --- a/bin/rule.ml +++ b/bin/rule.ml @@ -78,8 +78,7 @@ let print_rule ~nd ~prelude ~md_file ~ml_files ~dirs ~root ~requires options = "\ (alias\n\ \ (name %s)\n\ -\ (deps (:x %s)\n\ -\ (package mdx)%s)\n\ +\ (deps (:x %s)%s)\n\ \ (action (progn\n\ \ (run ocaml-mdx test %a %s%s%%{x})\n%a\n\ \ (diff? %%{x} %%{x}.corrected))))\n" diff --git a/test/dune.inc b/test/dune.inc index 28a1fbd81..2c8e119e5 100644 --- a/test/dune.inc +++ b/test/dune.inc @@ -1,167 +1,146 @@ (alias (name runtest) - (deps (:x pp.md) - (package mdx)) + (deps (:x pp.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x ellipsis.md) - (package mdx)) + (deps (:x ellipsis.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x envs.md) - (package mdx)) + (deps (:x envs.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x empty_line.md) - (package mdx)) + (deps (:x empty_line.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x spaces.md) - (package mdx)) + (deps (:x spaces.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x errors.md) - (package mdx)) + (deps (:x errors.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest-all) - (deps (:x errors.md) - (package mdx)) + (deps (:x errors.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp --non-deterministic %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x heredoc.md) - (package mdx)) + (deps (:x heredoc.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x mlt.md) - (package mdx)) + (deps (:x mlt.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x semisemi.md) - (package mdx)) + (deps (:x semisemi.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x exit.md) - (package mdx)) + (deps (:x exit.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x padding.md) - (package mdx)) + (deps (:x padding.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x multilines.md) - (package mdx)) + (deps (:x multilines.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x lines.md) - (package mdx)) + (deps (:x lines.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x lwt.md) - (package mdx)) + (deps (:x lwt.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x non-det.md) - (package mdx)) + (deps (:x non-det.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest-all) - (deps (:x non-det.md) - (package mdx)) + (deps (:x non-det.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp --non-deterministic %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x code.md) - (package mdx)) + (deps (:x code.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x set_environment_variable.md) - (package mdx)) + (deps (:x set_environment_variable.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x unset_environment_variable.md) - (package mdx)) + (deps (:x unset_environment_variable.md)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) (diff? %{x} %{x}.corrected)))) (alias (name runtest) - (deps (:x prelude.md) - (package mdx)) + (deps (:x prelude.md)) (action (progn (run ocaml-mdx test --prelude-str "#require \"lwt\"" --prelude-str "toto:let x = \"42\"" --direction=infer-timestamp %{x}) @@ -169,7 +148,6 @@ (alias (name runtest) (deps (:x prelude_file.md) - (package mdx) prelude.ml) (action (progn (run ocaml-mdx test --prelude=prelude.ml --direction=infer-timestamp %{x}) @@ -178,7 +156,6 @@ (alias (name runtest) (deps (:x dune_rules.md) - (package mdx) (:y1 dune_rules_1.ml) (:y0 dune_rules_2.ml) (source_tree foo)) @@ -190,7 +167,6 @@ (alias (name runtest) (deps (:x require/require-package.md) - (package mdx) (package example_lib)) (action (progn (run ocaml-mdx test --direction=infer-timestamp %{x}) From 571f6001fdfba393a2ecd7d53f3f5bf918506ec8 Mon Sep 17 00:00:00 2001 From: Guillaume Petiot Date: Thu, 12 Sep 2019 10:44:19 +0700 Subject: [PATCH 20/20] Use dune modes stanza to fix warning 58 --- lib/top/dune | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/top/dune b/lib/top/dune index 01e161502..540c080f4 100644 --- a/lib/top/dune +++ b/lib/top/dune @@ -1,5 +1,6 @@ (library (name mdx_top) (public_name mdx.top) + (modes byte) (preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file}))) (libraries unix mdx compiler-libs compiler-libs.toplevel threads findlib.top))