Skip to content

[RFC] mdx stanza rework #3955

@voodoos

Description

@voodoos

Presentation

This issue documents the design of a rework of the current mdx stanza.
Implementation has already begun in this draft PR#3956, but there is still time to
discuss the design. One important point is the role distribution between mdx
and dune with regard to code generation.

I think the best choice is to do the code generation on the mdx side because
the generated code uses the public mdx libs and if these change the generator
should also change and it will be easier to keep these in sync if they are
packaged together. However relying on dune to generate the code might be more
performant.

Current status of MDX / Dune :

MDX = multiple binaries:

  • ocaml-mdx a native entry point which invoke mdx-test
  • mdx-test the actual test binary, compiled to bytecode because it interacts
    with the toplevel

The Stanza

(mdx
 (files <glob>)         ; files to test
 (packages <packages>)  ; local dune pkgs that the doc blocks depend on
 (preludes <files>))    ; code to run before the test

No generic deps field and only public libraries (in packages) can be exposed
to MDX.

For each file to test:

  • Dune calls ocaml-mdx deps thefile.md to obtain the dependencies of the
    tested file (when code blocks include code from other files)
  • Dune call ocaml-mdx test [--prelude ...] -o thefile.corrected thefile.md,
    which call the mdx-test binary. This binary basically calls a function in
    MDX's oublic library: Mdx_test.run-exn.
  • Diff the result with the expected output and allow the promotion of these
    results.

Limitations

  1. MDX cannot link to private libs without knowing their CMI paths.
  2. mdx-test must be compiled to bytecode
  3. ocaml-mdx invokes mdx-test at runtime, but this dependency cannot be
    expressed easily in dune. In RWO, workaround is to add an explicit dependency
    on mdx package.
  4. No full "deps" field
  5. The future opam monorepo version of RWO will not compatible with the
    (package mdx) solution because (package) works only locally.

The new MDX stanza

(mdx
 (files <glob>)
 (deps <deps>)
 (libraries <library-dependencies>) ; Libraries that will be statically linked in the test executable
 (preludes <files>))

The stanza's syntax is similar but the execution differs a little

Once for each mdx stanza:

  • Dune would call once a ocaml-mdx dune-gen subcommand (not for end-user use)
    that would generate the source of an executable MDX as a library.
  • This test-running program will use the newly accessible Mdx_test.run_exn function and
    is linked with the public and private libraries that the tests use.
  • Arguments for this generator would include:
    • paths to cmi files of the deps, including the ones of private libraries
    • the preludes defined in the stanza
  • Then dune builds a -- bytecode -- test executable from the generated source.

For each file to test:

  • Dune calls ocaml-mdx deps thefile.md to obtain the dependencies of the
    tested file (when code blocks include code from other files)
  • Dune call the newly generated executable with the file as argument
  • Diff the result with the expected output and allow the promotion of these
    results.

This should solve limitations 1, 3, 4 and 5. However bytecode compilation will remain
necessary as long as no native "JIT" toplevel is available.

Ping @NathanReb, @emillon

Metadata

Metadata

Assignees

Labels

mdxRelated to the internal mdx plugin

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions