Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix evaluate-time error with MDX stanza and unavailable packages #3650

Merged
merged 3 commits into from
Jul 28, 2020

Conversation

craigfe
Copy link
Contributor

@craigfe craigfe commented Jul 24, 2020

This adds a test that reproduces a Dune bug when using mdx stanzas in combination with the -p command-line option.

Why this happens

Expanding the Mdx stanza involves looking up each stated package in the super context and generating an alias to install it (https://github.com/ocaml/dune/blob/master/src/dune/mdx.ml#L185-L188). When -p is passed, it's possible that not all packages will be available, causing an exception to be raised.

I would expect the MDX stanza to not be expanded (and the executable not to be required) when the supplied package name is not one of the set in the stanza. There is a question of what to do with internal package dependencies, for instance:

(mdx
 (files README.md)
 (packages irmin irmin-unix))

In this case, irmin-unix depends on irmin but not vice-versa, so ideally this stanza would be run when -p ... irmin-unix ... is passed. Perhaps it'll be necessary to associate a specific package to each stanza (along with libraries) to resolve this issue.

I'm happy to prepare a PR to fix this issue if anyone has ideas.

CC: @NathanReb

@NathanReb
Copy link
Collaborator

Do you know what the current behaviour is with regular rules that have (package ...) dependencies? This shouldn't be any different here. In particular I was considering replacing the packages field with a regular deps field.

I also ran into a slightly related bug where running dune build required mdx to be installed.

@craigfe
Copy link
Contributor Author

craigfe commented Jul 27, 2020

I had a look around when looking for an easy fix, and my understanding is that mdx is unique in having a packages field (everything else having a singular package field). My expectation was that the MDX stanza would have both package and libraries fields, and the user is responsible for ensuring that the stated package pulls in all the necessary dependencies.

@NathanReb
Copy link
Collaborator

The packages field is strictly equivalent to a bunch of (deps (package ...) (package ...)). What I'm wondering is how a rule with such dependencies behave in the context of -p? Is it simply not executed or does the build fail?

I'll give that a spin!

@NathanReb
Copy link
Collaborator

Note that I'm planning to add a libraries field to the mdx stanza so that you can depend on libraries directly without having to load them with ocamlfind but it requires a few changes on how it's implemented.

The same kind of issues will then arise i.e. you won't be able to run your mdx test if the -p option doesn't let you build one of the libraries specified here I guess.

@NathanReb
Copy link
Collaborator

The package field i.e. the field specifying to which package the stanza and associated tests belong is a broader problem that was already raised with other tests such as inline_tests see this issue.

We could eventually add one to the mdx stanza but that wouldn't solve the dependencies issue at hand here which is that the stanza can depend on other packages and therefore won't work if -p isn't passed the list of all those packages. That's true of package and library dependencies.

One thing we need to fix though is that nasty error, even if it must just fail, it should do it in a clean and similar way to any rule that suffers the same issue.

@rgrinberg
Copy link
Member

The packages field is strictly equivalent to a bunch of (deps (package ...) (package ...)). What I'm wondering is how a rule with such dependencies behave in the context of -p? Is it simply not executed or does the build fail?

It will fail when you build its targets because its dependencies aren't satisfied.

@craigfe I fixed the same issue in the (deps ..) field #3424. Do you think you could do a similar fix here?

@rgrinberg
Copy link
Member

Alternatively, you can evaluate the packages field using Dep_conf_eval.unnamed. This way, we'll only have a single code path for this validation.

@craigfe craigfe force-pushed the mdx-support-package-selection branch 2 times, most recently from b3a1a77 to 99546d1 Compare July 28, 2020 09:00
@craigfe
Copy link
Contributor Author

craigfe commented Jul 28, 2020

@rgrinberg: I've pushed a commit that improves error handling in a similar manner. (Will avoid going the Dep_conf_eval.unnamed route for now, since @NathanReb is working on this code too.)

@rgrinberg
Copy link
Member

This fix is not the right way to do it. It raises the error when the rule is evaluated rather than when it is executed.

Now I'm more convinced we should just reuse unnamed in Deps_conf_eval which handles this correctly.

@craigfe craigfe force-pushed the mdx-support-package-selection branch from 99546d1 to 429b110 Compare July 28, 2020 18:51
@craigfe
Copy link
Contributor Author

craigfe commented Jul 28, 2020

I've pushed a new commit that switches to Dep_conf_eval.unnamed, which looks much cleaner; thanks. (It wasn't clear to me how to avoid an evaluate-time error with the Build_system.Alias.package_install approach anyway.)

@craigfe craigfe force-pushed the mdx-support-package-selection branch from 429b110 to ed91231 Compare July 28, 2020 18:56
@craigfe craigfe changed the title Add a reproduction for MDX failing in combination with the -p option Fix evaluate-time error with MDX stanza and unavailable packages Jul 28, 2020
@craigfe craigfe force-pushed the mdx-support-package-selection branch from ed91231 to b050ee1 Compare July 28, 2020 19:03
@rgrinberg
Copy link
Member

Thanks. The fix looks good now. To clarify for anyone else reading, it was necessary to delay the error to prevent other rules in the same directory from being broken. Raising on evaluation aborts the entire set of rules for the directory, while this approach delays the error until a target of the broken rule is actually needed.

craigfe and others added 3 commits July 28, 2020 15:05
Signed-off-by: Craig Ferguson <me@craigfe.io>
Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
@rgrinberg rgrinberg force-pushed the mdx-support-package-selection branch from b050ee1 to 507995b Compare July 28, 2020 22:05
@rgrinberg
Copy link
Member

rgrinberg commented Jul 28, 2020

Looks good, thanks. All I've done is improve the locations in your error message

@rgrinberg rgrinberg merged commit 44d5194 into ocaml:master Jul 28, 2020
rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Aug 14, 2020
…lugin, dune-private-libs and dune-glob (2.7.0)

CHANGES:

- Write intermediate files in a `.mdx` folder for each `mdx` stanza
  to prevent the corresponding actions to be executed as part of the `@all`
  alias (ocaml/dune#3659, @NathanReb)

- Read Coq flags from `env` (ocaml/dune#3547 , fixes ocaml/dune#3486, @gares)

- Allow bisect_ppx to be enabled/disabled via dune-workspace. (ocaml/dune#3404,
  @stephanieyou)

- Formatting of dune files is now done in the executing dune process instead of
  in a separate process. (ocaml/dune#3536, @nojb)

- Add a `--debug-artifact-substution` flag to help debug problem with
  version not being captured by `dune-build-info` (ocaml/dune#3589,
  @jeremiedimino)

- Allow the use of the `context_name` variable in the `enabled_if` fields of
  executable(s) and install stanzas. (ocaml/dune#3568, fixes ocaml/dune#3566, @voodoos)

- Fix compatibility with OCaml 4.12.0 when compiling empty archives; no .a file
  is generated. (ocaml/dune#3576, @dra27)

- `$ dune utop` no longer tries to load optional libraries that are unavailable
  (ocaml/dune#3612, fixes ocaml/dune#3188, @anuragsoni)

- Fix dune-build-info on 4.10.0+flambda (ocaml/dune#3599, @emillon, @jeremiedimino).

- Allow multiple libraries with `inline_tests` to be defined in the same
  directory (ocaml/dune#3621, @rgrinberg)

- Run exit hooks in jsoo separate compilation mode (ocaml/dune#3626, fixes ocaml/dune#3622,
  @rgrinberg)

- Add (alias ...), (mode ...) fields to (copy_fields ...) stanza (ocaml/dune#3631, @nojb)

- (copy_files ...) now supports copying files from outside the workspace using
  absolute file names (ocaml/dune#3639, @nojb)

- Dune does not use `ocamlc` as an intermediary to call C compiler anymore.
  Configuration flags `ocamlc_cflags` and `ocamlc_cppflags` are always prepended
  to the compiler arguments. (ocaml/dune#3565, fixes ocaml/dune#3346, @voodoos)

- Revert the build optimization in ocaml/dune#2268. This optimization slows down building
  individual executables when they're part of an `executables` stanza group
  (ocaml/dune#3644, @rgrinberg)

- Use `{dev}` rather than `{pinned}` in the generated `.opam` file. (ocaml/dune#3647,
  @kit-ty-kate)

- Insert correct extension name when editing `dune-project` files. Previously,
  dune would just insert the stanza name. (ocaml/dune#3649, fixes ocaml/dune#3624, @rgrinberg)

- Fix crash when evaluating an `mdx` stanza that depends on unavailable
  packages. (ocaml/dune#3650, @craigfe)

- Fix typo in `cache-check-probablity` field in dune config files. This field
  now requires 2.7 as it wasn't usable before this version. (ocaml/dune#3652, @edwintorok)

- Add `"odoc" {with-doc}` to the dependencies in the generated `.opam` files.
  (ocaml/dune#3667, @kit-ty-kate)

- Do not allow user actions to capture dune's stdin (ocaml/dune#3677, fixes ocaml/dune#3672,
  @rgrinberg)

- `(subdir ...)` stanzas can now appear in dune files used via `(include ...)`.
  (ocaml/dune#3676, @nojb)
rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Aug 14, 2020
…lugin, dune-private-libs and dune-glob (2.7.0)

CHANGES:

- Write intermediate files in a `.mdx` folder for each `mdx` stanza
  to prevent the corresponding actions to be executed as part of the `@all`
  alias (ocaml/dune#3659, @NathanReb)

- Read Coq flags from `env` (ocaml/dune#3547 , fixes ocaml/dune#3486, @gares)

- Add instrumentation framework to toggle instrumentation by `bisect_ppx`,
  `landmarks`, etc, via dune-workspace and/or the command-line. (ocaml/dune#3404, ocaml/dune#3526
  @stephanieyou, @nojb)

- Formatting of dune files is now done in the executing dune process instead of
  in a separate process. (ocaml/dune#3536, @nojb)

- Add a `--debug-artifact-substution` flag to help debug problem with
  version not being captured by `dune-build-info` (ocaml/dune#3589,
  @jeremiedimino)

- Allow the use of the `context_name` variable in the `enabled_if` fields of
  executable(s) and install stanzas. (ocaml/dune#3568, fixes ocaml/dune#3566, @voodoos)

- Fix compatibility with OCaml 4.12.0 when compiling empty archives; no .a file
  is generated. (ocaml/dune#3576, @dra27)

- `$ dune utop` no longer tries to load optional libraries that are unavailable
  (ocaml/dune#3612, fixes ocaml/dune#3188, @anuragsoni)

- Fix dune-build-info on 4.10.0+flambda (ocaml/dune#3599, @emillon, @jeremiedimino).

- Allow multiple libraries with `inline_tests` to be defined in the same
  directory (ocaml/dune#3621, @rgrinberg)

- Run exit hooks in jsoo separate compilation mode (ocaml/dune#3626, fixes ocaml/dune#3622,
  @rgrinberg)

- Add (alias ...), (mode ...) fields to (copy_fields ...) stanza (ocaml/dune#3631, @nojb)

- (copy_files ...) now supports copying files from outside the workspace using
  absolute file names (ocaml/dune#3639, @nojb)

- Dune does not use `ocamlc` as an intermediary to call C compiler anymore.
  Configuration flags `ocamlc_cflags` and `ocamlc_cppflags` are always prepended
  to the compiler arguments. (ocaml/dune#3565, fixes ocaml/dune#3346, @voodoos)

- Revert the build optimization in ocaml/dune#2268. This optimization slows down building
  individual executables when they're part of an `executables` stanza group
  (ocaml/dune#3644, @rgrinberg)

- Use `{dev}` rather than `{pinned}` in the generated `.opam` file. (ocaml/dune#3647,
  @kit-ty-kate)

- Insert correct extension name when editing `dune-project` files. Previously,
  dune would just insert the stanza name. (ocaml/dune#3649, fixes ocaml/dune#3624, @rgrinberg)

- Fix crash when evaluating an `mdx` stanza that depends on unavailable
  packages. (ocaml/dune#3650, @craigfe)

- Fix typo in `cache-check-probablity` field in dune config files. This field
  now requires 2.7 as it wasn't usable before this version. (ocaml/dune#3652, @edwintorok)

- Add `"odoc" {with-doc}` to the dependencies in the generated `.opam` files.
  (ocaml/dune#3667, @kit-ty-kate)

- Do not allow user actions to capture dune's stdin (ocaml/dune#3677, fixes ocaml/dune#3672,
  @rgrinberg)

- `(subdir ...)` stanzas can now appear in dune files used via `(include ...)`.
  (ocaml/dune#3676, @nojb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants