dune icon indicating copy to clipboard operation
dune copied to clipboard

Special variables: add %{file-available:<file>} syntax

Open maroneze opened this issue 3 years ago • 0 comments

Desired Behavior

In some situations, especially when mixing dune and non-dune subprojects, we would like to be able to conditionally depend on the existence of a certain file, that is, write:

(enabled_if %{file-available:<file>})

Which would return true if <file> exists, or false otherwise.

I could not find a way to emulate this behavior with the current boolean functions in Dune, at least not in a simple way (at the end I mention a possible workaround, which seems full of complications).

In my particular use case, this would decide whether a given test (which is built using a dune rule) should be run. This test depends on the existence of a node_modules directory, that is, whether the user ran npm install before running the test. The npm install part is completely optional: users may not want to run it (too costly); or they may be unable to do so (lack of internet connectivity); or it may be an optional component only available in certain configurations.

In any case, there is currently no library or executable associated with the subproject; so I cannot readily use lib-available or bin-available.

I also tried using read:, since the documentation says read:<path> expands to the contents of the given file, in case a file containing the string true might be interpreted as the true value. This did not work, however.

Using the existence of a file to conditionally enable some feature seems like it could be useful in several scenarios. For instance, the stamp idiom is based on creating files to indicate whether certain stages were reached. It could be abused, though.

To check the feasibility of the required feature, I quickly hacked the dune source code to test, and it seems to work. But seeing the memoization that takes place inside Dune made me realize that there is an issue if the file in question could be created or erased during the build. The user should be duly notified that the file should not be modified by the build, otherwise all bets are off. Despite that restriction, the code to support it seems simple (except for relative path issues, which require a bit more care).

Overall, this works like an extension of bin-available.

Workaround in the absence of this feature

This request does smell a bit of feature creep. It is probably always possible to replace the existence check of a file with a library, especially if the directory containing it is writable; for instance, after running npm install in my example, which would create a node_modules directory, I might as well run:

echo "(library (name node_modules))" > dune

To create an empty library and then use %{lib-available:node_modules} to check its existence. But if the directory already has a dune file, it might require creating a subdirectory; otherwise, if the directory is not handled by dune (e.g. not present in a dirs stanza), that might also be a problem. Overall, for each file to check, I might have to create a new library. So, it is possible to sidestep the need for file-available, but it is very inconvenient to do so. Unless there are already some better techniques to emulate this behavior.

Example

(enabled_if %{file-available:node_modules})

The above rule should run only if the node_modules file/directory exists.

maroneze avatar Jul 27 '22 07:07 maroneze